forked from facebook/hermes
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Record inline caching misses during execution
Summary: This diff adds the implementation of data structure that keeps track of inline caching misses during the execution. Whenever an inline caching miss is detected. The inline caching profiler adds a record in the data structure, which is a two-layer hash map. The first layer is indexed by source location (i.e., code block pointer and instruction offset), the second layer is indexed by the tuple of <property id, object hidden class, cached hidden class>. Reviewed By: dulinriley Differential Revision: D17165022 fbshipit-source-id: 23880f597ff5a2f46618292e5d1c0f6a56eefade
- Loading branch information
1 parent
1d4413a
commit 8504f1f
Showing
7 changed files
with
229 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the LICENSE | ||
* file in the root directory of this source tree. | ||
*/ | ||
#ifndef INLINECACHE_PROFILER_H | ||
#define INLINECACHE_PROFILER_H | ||
|
||
#include "hermes/VM/SymbolID.h" | ||
#include "llvm/ADT/DenseMap.h" | ||
|
||
namespace hermes { | ||
namespace vm { | ||
|
||
class CodeBlock; | ||
class HiddenClass; | ||
class JSArray; | ||
|
||
class InlineCacheProfiler { | ||
public: | ||
using ClassId = uint64_t; | ||
using PropertyId = uint32_t; | ||
using ICSrcKey = std::pair<uint32_t, CodeBlock *>; | ||
using HiddenClassPair = std::pair<ClassId, ClassId>; | ||
using ICMissKey = std::pair<PropertyId, HiddenClassPair>; | ||
|
||
/// Stores all inline caching misses at one specific source location, which | ||
/// is uniquely identified by code block and instruction offset. | ||
struct ICMiss { | ||
/// Increment the inline caching miss count for a pair of hidden classes. | ||
void insertMiss(ICMissKey icRecord) { | ||
auto ret = | ||
hiddenClasses.insert(std::pair<ICMissKey, uint32_t>(icRecord, 1)); | ||
if (!ret.second) { | ||
++(ret.first->second); | ||
} | ||
++missCount; | ||
} | ||
|
||
/// Total number of inline caching misses at the source location. | ||
uint32_t missCount{0}; | ||
|
||
/// Internal map that keeps track of the mapping between | ||
/// <property, object hidden class, cached hidden class> and its frequency. | ||
llvm::DenseMap<ICMissKey, uint32_t> hiddenClasses; | ||
}; | ||
|
||
/// Add an inline caching miss record. | ||
bool insertICMiss( | ||
CodeBlock *codeblock, | ||
uint32_t instOffset, | ||
SymbolID &propertyID, | ||
ClassId objectHiddenClassId, | ||
ClassId cachedHiddenClassId); | ||
|
||
/// Get the total number of inline caching misses. | ||
uint32_t getTotalMisses() { | ||
return totalMisses_; | ||
} | ||
|
||
/// Get a JS array containing all hidden classes that shouldn't be | ||
/// garbage collected. | ||
JSArray *getHiddenClassArray(); | ||
|
||
/// Set a JS array containing all hidden classes that shouldn't be | ||
/// garbage collected. | ||
void setHiddenClassArray(JSArray *hiddenClassArray); | ||
|
||
/// Get the current index of element in the hidden class array | ||
/// used by the inline caching profiler. | ||
uint32_t &getHiddenClassArrayIndex(); | ||
|
||
/// Get a map from object Id to array index in the array | ||
/// referenced by cachedHiddenClassesRawPtr_. | ||
llvm::DenseMap<InlineCacheProfiler::ClassId, int32_t> &getClassIdtoIndexMap(); | ||
|
||
private: | ||
/// Keep track of the current index of the hidden class array | ||
/// used by the inline caching profiler. | ||
uint32_t hcIdx_{0}; | ||
|
||
/// Store an array of hidden classes that will be used | ||
/// by inline caching profiler. | ||
JSArray *cachedHiddenClassesRawPtr_; | ||
|
||
/// Store a map from object Id to array index in the array | ||
/// referenced by cachedHiddenClassesRawPtr_. | ||
llvm::DenseMap<InlineCacheProfiler::ClassId, int32_t> classIdToIdx_; | ||
|
||
/// Total number of inline caching misses during the program execution. | ||
uint32_t totalMisses_{0}; | ||
|
||
/// Store the data structure of all inline caching misses information. | ||
/// The map is keyed by pairs <instruction offset, CodeBlock> and maps | ||
/// to ICMiss objects, which keeps track of hidden classes and frequency. | ||
llvm::DenseMap<ICSrcKey, ICMiss> cacheMisses_; | ||
}; | ||
|
||
} // namespace vm | ||
} // namespace hermes | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the LICENSE | ||
* file in the root directory of this source tree. | ||
*/ | ||
#ifdef HERMESVM_PROFILER_BB | ||
#ifndef INLINECACHE_PROFILER_H | ||
#include "hermes/VM/Profiler/InlineCacheProfiler.h" | ||
#include "hermes/VM/CodeBlock.h" | ||
#include "hermes/VM/Handle.h" | ||
#include "hermes/VM/HiddenClass.h" | ||
#include "hermes/VM/JSArray.h" | ||
#include "hermes/VM/Runtime.h" | ||
#include "hermes/VM/StringView.h" | ||
#include "hermes/VM/SymbolID.h" | ||
|
||
#include <vector> | ||
|
||
namespace hermes { | ||
namespace vm { | ||
|
||
bool InlineCacheProfiler::insertICMiss( | ||
CodeBlock *codeblock, | ||
uint32_t instOffset, | ||
SymbolID &propertyID, | ||
ClassId objectHiddenClassId, | ||
ClassId cachedHiddenClassId) { | ||
// if not exist, create inline caching entry for the source location | ||
ICSrcKey icKey(instOffset, codeblock); | ||
auto it = cacheMisses_.find(icKey); | ||
if (it == cacheMisses_.end()) { | ||
ICMiss icMiss; | ||
auto p = cacheMisses_.try_emplace(icKey, icMiss); | ||
assert(p.second && "Guaranteed to insert"); | ||
it = p.first; | ||
} | ||
// record the hidden class pair for the source location | ||
auto hcPair = | ||
std::pair<ClassId, ClassId>(objectHiddenClassId, cachedHiddenClassId); | ||
auto icRecord = | ||
std::pair<PropertyId, HiddenClassPair>(propertyID.unsafeGetRaw(), hcPair); | ||
it->second.insertMiss(icRecord); | ||
|
||
++totalMisses_; | ||
return true; | ||
} | ||
|
||
JSArray *InlineCacheProfiler::getHiddenClassArray() { | ||
return cachedHiddenClassesRawPtr_; | ||
} | ||
|
||
void InlineCacheProfiler::setHiddenClassArray(JSArray *hiddenClassArray) { | ||
cachedHiddenClassesRawPtr_ = hiddenClassArray; | ||
} | ||
|
||
uint32_t &InlineCacheProfiler::getHiddenClassArrayIndex() { | ||
return hcIdx_; | ||
} | ||
|
||
llvm::DenseMap<InlineCacheProfiler::ClassId, int32_t> | ||
&InlineCacheProfiler::getClassIdtoIndexMap() { | ||
return classIdToIdx_; | ||
} | ||
} // namespace vm | ||
} // namespace hermes | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters