[lite] Allocate feedback vectors lazily
Allocate feedback vectors lazily when the function's interrupt budget has reached a specified threshold. This cl introduces a new field in the ClosureFeedbackCellArray to track the interrupt budget for allocating feedback vectors. Using the interrupt budget on the bytecode array could cause problems when there are closures across native contexts and we may delay allocating feedback vectors in one of them causing unexpected performance cliffs. In the long term we may want to remove interrupt budget from bytecode array and use context specific budget for tiering up decisions as well. Bug: v8:8394 Change-Id: Ia8fbb71f5e8543a92f14c44aa762973da82d445c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1520719 Commit-Queue: Mythri Alle <mythria@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#60450}
This commit is contained in:
parent
26ffe82e70
commit
7629afdb9d
@ -1086,10 +1086,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
FrameScope frame_scope(masm, StackFrame::MANUAL);
|
||||
__ PushStandardFrame(closure);
|
||||
|
||||
// Reset code age.
|
||||
__ mov(r9, Operand(BytecodeArray::kNoAgeBytecodeAge));
|
||||
__ strb(r9, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kBytecodeAgeOffset));
|
||||
// Reset code age and the OSR arming. The OSR field and BytecodeAgeOffset are
|
||||
// 8-bit fields next to each other, so we could just optimize by writing a
|
||||
// 16-bit. These static asserts guard our assumption is valid.
|
||||
STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset ==
|
||||
BytecodeArray::kOSRNestingLevelOffset + kCharSize);
|
||||
STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0);
|
||||
__ mov(r9, Operand(0));
|
||||
__ strh(r9, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kOSRNestingLevelOffset));
|
||||
|
||||
// Load the initial bytecode offset.
|
||||
__ mov(kInterpreterBytecodeOffsetRegister,
|
||||
|
@ -1215,9 +1215,14 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ Add(fp, sp, StandardFrameConstants::kFixedFrameSizeFromFp);
|
||||
|
||||
// Reset code age.
|
||||
__ Mov(x10, Operand(BytecodeArray::kNoAgeBytecodeAge));
|
||||
__ Strb(x10, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kBytecodeAgeOffset));
|
||||
// Reset code age and the OSR arming. The OSR field and BytecodeAgeOffset are
|
||||
// 8-bit fields next to each other, so we could just optimize by writing a
|
||||
// 16-bit. These static asserts guard our assumption is valid.
|
||||
STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset ==
|
||||
BytecodeArray::kOSRNestingLevelOffset + kCharSize);
|
||||
STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0);
|
||||
__ Strh(wzr, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kOSRNestingLevelOffset));
|
||||
|
||||
// Load the initial bytecode offset.
|
||||
__ Mov(kInterpreterBytecodeOffsetRegister,
|
||||
|
@ -134,7 +134,8 @@ void LazyBuiltinsAssembler::CompileLazy(TNode<JSFunction> function) {
|
||||
|
||||
Label use_sfi_code(this);
|
||||
// If there is no feedback, don't check for optimized code.
|
||||
GotoIf(IsFixedArray(feedback_cell_value), &use_sfi_code);
|
||||
GotoIf(HasInstanceType(feedback_cell_value, CLOSURE_FEEDBACK_CELL_ARRAY_TYPE),
|
||||
&use_sfi_code);
|
||||
|
||||
// If it isn't undefined or fixed array it must be a feedback vector.
|
||||
CSA_ASSERT(this, IsFeedbackVector(feedback_cell_value));
|
||||
|
@ -1014,10 +1014,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
|
||||
}
|
||||
|
||||
// Reset code age.
|
||||
__ mov_b(FieldOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kBytecodeAgeOffset),
|
||||
Immediate(BytecodeArray::kNoAgeBytecodeAge));
|
||||
// Reset code age and the OSR arming. The OSR field and BytecodeAgeOffset are
|
||||
// 8-bit fields next to each other, so we could just optimize by writing a
|
||||
// 16-bit. These static asserts guard our assumption is valid.
|
||||
STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset ==
|
||||
BytecodeArray::kOSRNestingLevelOffset + kCharSize);
|
||||
STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0);
|
||||
__ mov_w(FieldOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kOSRNestingLevelOffset),
|
||||
Immediate(0));
|
||||
|
||||
// Push bytecode array.
|
||||
__ push(kInterpreterBytecodeArrayRegister);
|
||||
|
@ -1101,10 +1101,15 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ Push(rsi); // Callee's context.
|
||||
__ Push(rdi); // Callee's JS function.
|
||||
|
||||
// Reset code age.
|
||||
__ movb(FieldOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kBytecodeAgeOffset),
|
||||
Immediate(BytecodeArray::kNoAgeBytecodeAge));
|
||||
// Reset code age and the OSR arming. The OSR field and BytecodeAgeOffset are
|
||||
// 8-bit fields next to each other, so we could just optimize by writing a
|
||||
// 16-bit. These static asserts guard our assumption is valid.
|
||||
STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset ==
|
||||
BytecodeArray::kOSRNestingLevelOffset + kCharSize);
|
||||
STATIC_ASSERT(BytecodeArray::kNoAgeBytecodeAge == 0);
|
||||
__ movw(FieldOperand(kInterpreterBytecodeArrayRegister,
|
||||
BytecodeArray::kOSRNestingLevelOffset),
|
||||
Immediate(0));
|
||||
|
||||
// Load initial bytecode offset.
|
||||
__ movq(kInterpreterBytecodeOffsetRegister,
|
||||
|
@ -10045,14 +10045,16 @@ TNode<HeapObject> CodeStubAssembler::LoadFeedbackVector(
|
||||
return maybe_vector.value();
|
||||
}
|
||||
|
||||
TNode<FixedArray> CodeStubAssembler::LoadClosureFeedbackArray(
|
||||
TNode<ClosureFeedbackCellArray> CodeStubAssembler::LoadClosureFeedbackArray(
|
||||
SloppyTNode<JSFunction> closure) {
|
||||
TVARIABLE(HeapObject, feedback_cell_array, LoadFeedbackCellValue(closure));
|
||||
Label end(this);
|
||||
|
||||
// When feedback vectors are not yet allocated feedback cell contains a
|
||||
// an array of feedback cells used by create closures.
|
||||
GotoIf(IsFixedArray(feedback_cell_array.value()), &end);
|
||||
GotoIf(HasInstanceType(feedback_cell_array.value(),
|
||||
CLOSURE_FEEDBACK_CELL_ARRAY_TYPE),
|
||||
&end);
|
||||
|
||||
// Load FeedbackCellArray from feedback vector.
|
||||
TNode<FeedbackVector> vector = CAST(feedback_cell_array.value());
|
||||
|
@ -2872,7 +2872,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// used when creating closures from this function. This array could be
|
||||
// directly hanging off the FeedbackCell when there is no feedback vector
|
||||
// or available from the feedback vector's header.
|
||||
TNode<FixedArray> LoadClosureFeedbackArray(SloppyTNode<JSFunction> closure);
|
||||
TNode<ClosureFeedbackCellArray> LoadClosureFeedbackArray(
|
||||
SloppyTNode<JSFunction> closure);
|
||||
|
||||
// Update the type feedback vector.
|
||||
void UpdateFeedback(Node* feedback, Node* feedback_vector, Node* slot_id);
|
||||
|
@ -297,6 +297,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
|
||||
case DESCRIPTOR_ARRAY_TYPE:
|
||||
case TRANSITION_ARRAY_TYPE:
|
||||
case FEEDBACK_CELL_TYPE:
|
||||
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
|
||||
case FEEDBACK_VECTOR_TYPE:
|
||||
case PROPERTY_ARRAY_TYPE:
|
||||
case FOREIGN_TYPE:
|
||||
|
@ -23,11 +23,14 @@ namespace internal {
|
||||
|
||||
OBJECT_CONSTRUCTORS_IMPL(FeedbackVector, HeapObject)
|
||||
OBJECT_CONSTRUCTORS_IMPL(FeedbackMetadata, HeapObject)
|
||||
OBJECT_CONSTRUCTORS_IMPL(ClosureFeedbackCellArray, FixedArray)
|
||||
|
||||
NEVER_READ_ONLY_SPACE_IMPL(FeedbackVector)
|
||||
NEVER_READ_ONLY_SPACE_IMPL(ClosureFeedbackCellArray)
|
||||
|
||||
CAST_ACCESSOR(FeedbackVector)
|
||||
CAST_ACCESSOR(FeedbackMetadata)
|
||||
CAST_ACCESSOR(ClosureFeedbackCellArray)
|
||||
|
||||
INT32_ACCESSORS(FeedbackMetadata, slot_count, kSlotCountOffset)
|
||||
|
||||
@ -93,10 +96,17 @@ int FeedbackMetadata::GetSlotSize(FeedbackSlotKind kind) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
SMI_ACCESSORS(ClosureFeedbackCellArray, interrupt_budget,
|
||||
FixedArray::OffsetOfElementAt(kInterruptBudgetIndex))
|
||||
Handle<FeedbackCell> ClosureFeedbackCellArray::GetFeedbackCell(int index) {
|
||||
return handle(FeedbackCell::cast(get(index + kFeedbackCellStartIndex)),
|
||||
GetIsolate());
|
||||
}
|
||||
|
||||
ACCESSORS(FeedbackVector, shared_function_info, SharedFunctionInfo,
|
||||
kSharedFunctionInfoOffset)
|
||||
WEAK_ACCESSORS(FeedbackVector, optimized_code_weak_or_smi, kOptimizedCodeOffset)
|
||||
ACCESSORS(FeedbackVector, closure_feedback_cell_array, FixedArray,
|
||||
ACCESSORS(FeedbackVector, closure_feedback_cell_array, ClosureFeedbackCellArray,
|
||||
kClosureFeedbackCellArrayOffset)
|
||||
INT32_ACCESSORS(FeedbackVector, length, kLengthOffset)
|
||||
INT32_ACCESSORS(FeedbackVector, invocation_count, kInvocationCountOffset)
|
||||
@ -161,8 +171,9 @@ MaybeObject FeedbackVector::get(int index) const {
|
||||
|
||||
Handle<FeedbackCell> FeedbackVector::GetClosureFeedbackCell(int index) const {
|
||||
DCHECK_GE(index, 0);
|
||||
FixedArray cell_array = closure_feedback_cell_array();
|
||||
return handle(FeedbackCell::cast(cell_array.get(index)), GetIsolate());
|
||||
ClosureFeedbackCellArray cell_array =
|
||||
ClosureFeedbackCellArray::cast(closure_feedback_cell_array());
|
||||
return cell_array->GetFeedbackCell(index);
|
||||
}
|
||||
|
||||
void FeedbackVector::Set(FeedbackSlot slot, MaybeObject value,
|
||||
|
@ -206,16 +206,35 @@ FeedbackSlot FeedbackVector::GetTypeProfileSlot() const {
|
||||
return slot;
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<ClosureFeedbackCellArray> ClosureFeedbackCellArray::New(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared) {
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
int num_feedback_cells =
|
||||
shared->feedback_metadata()->closure_feedback_cell_count();
|
||||
|
||||
Handle<ClosureFeedbackCellArray> feedback_cell_array =
|
||||
factory->NewClosureFeedbackCellArray(num_feedback_cells);
|
||||
|
||||
for (int i = 0; i < num_feedback_cells; i++) {
|
||||
Handle<FeedbackCell> cell =
|
||||
factory->NewNoClosuresCell(factory->undefined_value());
|
||||
feedback_cell_array->set(i + kFeedbackCellStartIndex, *cell);
|
||||
}
|
||||
return feedback_cell_array;
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<FeedbackVector> FeedbackVector::New(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared,
|
||||
Handle<FixedArray> closure_feedback_cell_array) {
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array) {
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
const int slot_count = shared->feedback_metadata()->slot_count();
|
||||
|
||||
Handle<FeedbackVector> vector =
|
||||
factory->NewFeedbackVector(shared, AllocationType::kOld);
|
||||
Handle<FeedbackVector> vector = factory->NewFeedbackVector(
|
||||
shared, closure_feedback_cell_array, AllocationType::kOld);
|
||||
|
||||
DCHECK_EQ(vector->length(), slot_count);
|
||||
|
||||
@ -229,8 +248,6 @@ Handle<FeedbackVector> FeedbackVector::New(
|
||||
DCHECK_EQ(vector->profiler_ticks(), 0);
|
||||
DCHECK_EQ(vector->deopt_count(), 0);
|
||||
|
||||
vector->set_closure_feedback_cell_array(*closure_feedback_cell_array);
|
||||
|
||||
// Ensure we can skip the write barrier
|
||||
Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
|
||||
DCHECK_EQ(ReadOnlyRoots(isolate).uninitialized_symbol(),
|
||||
@ -297,27 +314,6 @@ Handle<FeedbackVector> FeedbackVector::New(
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<FixedArray> FeedbackVector::NewClosureFeedbackCellArray(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared) {
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
int num_feedback_cells =
|
||||
shared->feedback_metadata()->closure_feedback_cell_count();
|
||||
if (num_feedback_cells == 0) {
|
||||
return factory->empty_fixed_array();
|
||||
}
|
||||
|
||||
Handle<FixedArray> feedback_cell_array =
|
||||
factory->NewFixedArray(num_feedback_cells, AllocationType::kOld);
|
||||
for (int i = 0; i < num_feedback_cells; i++) {
|
||||
Handle<FeedbackCell> cell =
|
||||
factory->NewNoClosuresCell(factory->undefined_value());
|
||||
feedback_cell_array->set(i, *cell);
|
||||
}
|
||||
return feedback_cell_array;
|
||||
}
|
||||
|
||||
// static
|
||||
void FeedbackVector::AddToVectorsForProfilingTools(
|
||||
Isolate* isolate, Handle<FeedbackVector> vector) {
|
||||
|
@ -144,6 +144,33 @@ typedef std::vector<MaybeObjectHandle> MaybeObjectHandles;
|
||||
|
||||
class FeedbackMetadata;
|
||||
|
||||
// ClosureFeedbackCellArray is a FixedArray that contains feedback cells used
|
||||
// when creating closures from a function. Along with the feedback
|
||||
// cells, the first slot (slot 0) is used to hold a budget to measure the
|
||||
// hotness of the function. This is created once the function is compiled and is
|
||||
// either held by the feedback vector (if allocated) or by the FeedbackCell of
|
||||
// the closure.
|
||||
class ClosureFeedbackCellArray : public FixedArray {
|
||||
public:
|
||||
NEVER_READ_ONLY_SPACE
|
||||
|
||||
DECL_CAST(ClosureFeedbackCellArray)
|
||||
|
||||
V8_EXPORT_PRIVATE static Handle<ClosureFeedbackCellArray> New(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared);
|
||||
inline Handle<FeedbackCell> GetFeedbackCell(int index);
|
||||
|
||||
DECL_INT_ACCESSORS(interrupt_budget)
|
||||
|
||||
DECL_VERIFIER(ClosureFeedbackCellArray)
|
||||
DECL_PRINTER(ClosureFeedbackCellArray)
|
||||
|
||||
enum { kInterruptBudgetIndex, kFeedbackCellStartIndex };
|
||||
|
||||
private:
|
||||
OBJECT_CONSTRUCTORS(ClosureFeedbackCellArray, FixedArray);
|
||||
};
|
||||
|
||||
// A FeedbackVector has a fixed header with:
|
||||
// - shared function info (which includes feedback metadata)
|
||||
// - invocation count
|
||||
@ -171,7 +198,7 @@ class FeedbackVector : public HeapObject {
|
||||
|
||||
// [feedback_cell_array]: The FixedArray to hold the feedback cells for any
|
||||
// closures created by this function.
|
||||
DECL_ACCESSORS(closure_feedback_cell_array, FixedArray)
|
||||
DECL_ACCESSORS(closure_feedback_cell_array, ClosureFeedbackCellArray)
|
||||
|
||||
// [length]: The length of the feedback vector (not including the header, i.e.
|
||||
// the number of feedback slots).
|
||||
@ -234,10 +261,7 @@ class FeedbackVector : public HeapObject {
|
||||
|
||||
V8_EXPORT_PRIVATE static Handle<FeedbackVector> New(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared,
|
||||
Handle<FixedArray> closure_feedback_cell_array);
|
||||
|
||||
V8_EXPORT_PRIVATE static Handle<FixedArray> NewClosureFeedbackCellArray(
|
||||
Isolate* isolate, Handle<SharedFunctionInfo> shared);
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array);
|
||||
|
||||
#define DEFINE_SLOT_KIND_PREDICATE(Name) \
|
||||
bool Name(FeedbackSlot slot) const { return Name##Kind(GetKind(slot)); }
|
||||
|
@ -370,6 +370,11 @@ DEFINE_INT(interrupt_budget, 144 * KB,
|
||||
#undef FLAG
|
||||
#define FLAG FLAG_FULL
|
||||
|
||||
DEFINE_INT(budget_for_feedback_vector_allocation, 2 * KB,
|
||||
"The budget in amount of bytecode executed by a function before we "
|
||||
"decide to allocate feedback vectors")
|
||||
DEFINE_BOOL(lazy_feedback_allocation, false, "Allocate feedback vectors lazily")
|
||||
|
||||
// Flags for Ignition.
|
||||
DEFINE_BOOL(ignition_elide_noneffectful_bytecodes, true,
|
||||
"elide bytecodes which won't have any external effect")
|
||||
@ -1230,7 +1235,7 @@ DEFINE_NEG_IMPLICATION(jitless, wasm_lazy_compilation)
|
||||
DEFINE_BOOL(opt, !V8_LITE_BOOL, "use adaptive optimizations")
|
||||
|
||||
// Enable use of inline caches to optimize object access operations.
|
||||
DEFINE_BOOL(use_ic, !V8_LITE_BOOL, "use inline caching")
|
||||
DEFINE_BOOL(use_ic, true, "use inline caching")
|
||||
|
||||
// Favor memory over execution speed.
|
||||
DEFINE_BOOL(optimize_for_size, V8_LITE_BOOL,
|
||||
@ -1543,6 +1548,7 @@ DEFINE_BOOL(raw_heap_snapshots, V8_ENABLE_RAW_HEAP_SNAPSHOTS_BOOL,
|
||||
DEFINE_BOOL(lite_mode, V8_LITE_BOOL,
|
||||
"enables trade-off of performance for memory savings "
|
||||
"(Lite mode only)")
|
||||
DEFINE_IMPLICATION(lite_mode, lazy_feedback_allocation)
|
||||
|
||||
// Cleanup...
|
||||
#undef FLAG_FULL
|
||||
|
@ -418,8 +418,25 @@ Handle<FixedArray> Factory::NewUninitializedFixedArray(
|
||||
*undefined_value(), allocation);
|
||||
}
|
||||
|
||||
Handle<ClosureFeedbackCellArray> Factory::NewClosureFeedbackCellArray(
|
||||
int num_slots, AllocationType allocation) {
|
||||
int length = ClosureFeedbackCellArray::kFeedbackCellStartIndex + num_slots;
|
||||
Handle<ClosureFeedbackCellArray> feedback_cell_array =
|
||||
NewFixedArrayWithMap<ClosureFeedbackCellArray>(
|
||||
RootIndex::kClosureFeedbackCellArrayMap, length, allocation);
|
||||
|
||||
// Initialize header fields
|
||||
feedback_cell_array->set_interrupt_budget(
|
||||
FLAG_budget_for_feedback_vector_allocation);
|
||||
DCHECK_EQ(ClosureFeedbackCellArray::kFeedbackCellStartIndex, 1);
|
||||
|
||||
return feedback_cell_array;
|
||||
}
|
||||
|
||||
Handle<FeedbackVector> Factory::NewFeedbackVector(
|
||||
Handle<SharedFunctionInfo> shared, AllocationType allocation) {
|
||||
Handle<SharedFunctionInfo> shared,
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array,
|
||||
AllocationType allocation) {
|
||||
int length = shared->feedback_metadata()->slot_count();
|
||||
DCHECK_LE(0, length);
|
||||
int size = FeedbackVector::SizeFor(length);
|
||||
@ -435,7 +452,7 @@ Handle<FeedbackVector> Factory::NewFeedbackVector(
|
||||
vector->set_invocation_count(0);
|
||||
vector->set_profiler_ticks(0);
|
||||
vector->set_deopt_count(0);
|
||||
vector->set_closure_feedback_cell_array(*empty_fixed_array());
|
||||
vector->set_closure_feedback_cell_array(*closure_feedback_cell_array);
|
||||
|
||||
// TODO(leszeks): Initialize based on the feedback metadata.
|
||||
MemsetTagged(ObjectSlot(vector->slots_start()), *undefined_value(), length);
|
||||
|
@ -156,10 +156,16 @@ class V8_EXPORT_PRIVATE Factory {
|
||||
Handle<FixedArray> NewUninitializedFixedArray(
|
||||
int length, AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
// Allocates a closure feedback cell array whose feedback cells are
|
||||
// initialized with undefined values.
|
||||
Handle<ClosureFeedbackCellArray> NewClosureFeedbackCellArray(
|
||||
int num_slots, AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
// Allocates a feedback vector whose slots are initialized with undefined
|
||||
// values.
|
||||
Handle<FeedbackVector> NewFeedbackVector(
|
||||
Handle<SharedFunctionInfo> shared,
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array,
|
||||
AllocationType allocation = AllocationType::kYoung);
|
||||
|
||||
// Allocates a clean embedder data array with given capacity.
|
||||
|
@ -616,13 +616,6 @@ void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
|
||||
|
||||
size_t calculated_size = 0;
|
||||
|
||||
// Log the feedback_cell array used for create closures.
|
||||
RecordVirtualObjectStats(
|
||||
vector, vector->closure_feedback_cell_array(),
|
||||
ObjectStats::FEEDBACK_VECTOR_CREATE_CLOSURE_ARRAY_TYPE,
|
||||
vector->closure_feedback_cell_array()->Size(),
|
||||
ObjectStats::kNoOverAllocation);
|
||||
|
||||
// Log the feedback vector's header (fixed fields).
|
||||
size_t header_size = vector->slots_start().address() - vector->address();
|
||||
stats_->RecordVirtualObjectStats(ObjectStats::FEEDBACK_VECTOR_HEADER_TYPE,
|
||||
|
@ -31,7 +31,6 @@
|
||||
V(ENUM_INDICES_CACHE_TYPE) \
|
||||
V(FEEDBACK_VECTOR_ENTRY_TYPE) \
|
||||
V(FEEDBACK_VECTOR_HEADER_TYPE) \
|
||||
V(FEEDBACK_VECTOR_CREATE_CLOSURE_ARRAY_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_CALL_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE) \
|
||||
V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE) \
|
||||
|
@ -369,6 +369,8 @@ bool Heap::CreateInitialMaps() {
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(SCOPE_INFO_TYPE, scope_info)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
|
||||
ALLOCATE_VARSIZE_MAP(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE,
|
||||
closure_feedback_cell_array)
|
||||
ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector)
|
||||
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
|
||||
Context::NUMBER_FUNCTION_INDEX)
|
||||
|
@ -1253,48 +1253,73 @@ Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
|
||||
void InterpreterAssembler::UpdateInterruptBudget(Node* weight, bool backward) {
|
||||
Comment("[ UpdateInterruptBudget");
|
||||
|
||||
Node* budget_offset =
|
||||
IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag);
|
||||
|
||||
// Assert that the weight is positive (negative weights should be implemented
|
||||
// as backward updates).
|
||||
CSA_ASSERT(this, Int32GreaterThanOrEqual(weight, Int32Constant(0)));
|
||||
|
||||
// Update budget by |weight| and check if it reaches zero.
|
||||
Variable new_budget(this, MachineRepresentation::kWord32);
|
||||
Node* old_budget =
|
||||
Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset);
|
||||
Label load_budget_from_bytecode(this), load_budget_done(this);
|
||||
TNode<JSFunction> function = CAST(LoadRegister(Register::function_closure()));
|
||||
TNode<HeapObject> feedback_cell_value = LoadFeedbackCellValue(function);
|
||||
Node* budget_offset =
|
||||
IntPtrConstant(BytecodeArray::kInterruptBudgetOffset - kHeapObjectTag);
|
||||
TVARIABLE(Int32T, old_budget);
|
||||
// TODO(mythria): We should use the interrupt budget on the feedback vector
|
||||
// for updating runtime profiler ticks as well. That would avoid having two
|
||||
// different places where we track interrupt budget.
|
||||
GotoIf(IsFeedbackVector(feedback_cell_value), &load_budget_from_bytecode);
|
||||
TNode<FixedArray> closure_feedback_cell_array = CAST(feedback_cell_value);
|
||||
TNode<Smi> old_budget_smi = CAST(
|
||||
LoadFixedArrayElement(closure_feedback_cell_array,
|
||||
ClosureFeedbackCellArray::kInterruptBudgetIndex));
|
||||
old_budget = SmiToInt32(old_budget_smi);
|
||||
Goto(&load_budget_done);
|
||||
|
||||
BIND(&load_budget_from_bytecode);
|
||||
old_budget = UncheckedCast<Int32T>(
|
||||
Load(MachineType::Int32(), BytecodeArrayTaggedPointer(), budget_offset));
|
||||
Goto(&load_budget_done);
|
||||
|
||||
BIND(&load_budget_done);
|
||||
// Make sure we include the current bytecode in the budget calculation.
|
||||
Node* budget_after_bytecode =
|
||||
Int32Sub(old_budget, Int32Constant(CurrentBytecodeSize()));
|
||||
TNode<Int32T> budget_after_bytecode = Signed(
|
||||
Int32Sub(old_budget.value(), Int32Constant(CurrentBytecodeSize())));
|
||||
|
||||
TVARIABLE(Int32T, new_budget);
|
||||
if (backward) {
|
||||
new_budget.Bind(Int32Sub(budget_after_bytecode, weight));
|
||||
|
||||
// Update budget by |weight| and check if it reaches zero.
|
||||
new_budget = Signed(Int32Sub(budget_after_bytecode, weight));
|
||||
Node* condition =
|
||||
Int32GreaterThanOrEqual(new_budget.value(), Int32Constant(0));
|
||||
Label ok(this), interrupt_check(this, Label::kDeferred);
|
||||
Label ok(this), interrupt_check(this);
|
||||
Branch(condition, &ok, &interrupt_check);
|
||||
|
||||
// Perform interrupt and reset budget.
|
||||
BIND(&interrupt_check);
|
||||
{
|
||||
CallRuntime(Runtime::kInterrupt, GetContext());
|
||||
new_budget.Bind(Int32Constant(Interpreter::InterruptBudget()));
|
||||
Goto(&ok);
|
||||
}
|
||||
CallRuntime(Runtime::kBytecodeBudgetInterrupt, GetContext(), function);
|
||||
new_budget = Int32Constant(Interpreter::InterruptBudget());
|
||||
Goto(&ok);
|
||||
|
||||
BIND(&ok);
|
||||
} else {
|
||||
// For a forward jump, we know we only increase the interrupt budget, so
|
||||
// no need to check if it's below zero.
|
||||
new_budget.Bind(Int32Add(budget_after_bytecode, weight));
|
||||
new_budget = Signed(Int32Add(budget_after_bytecode, weight));
|
||||
}
|
||||
|
||||
// Update budget.
|
||||
Label update_budget_in_bytecode(this), end(this);
|
||||
GotoIf(IsFeedbackVector(feedback_cell_value), &update_budget_in_bytecode);
|
||||
StoreFixedArrayElement(closure_feedback_cell_array,
|
||||
ClosureFeedbackCellArray::kInterruptBudgetIndex,
|
||||
SmiFromInt32(new_budget.value()), SKIP_WRITE_BARRIER);
|
||||
Goto(&end);
|
||||
|
||||
BIND(&update_budget_in_bytecode);
|
||||
StoreNoWriteBarrier(MachineRepresentation::kWord32,
|
||||
BytecodeArrayTaggedPointer(), budget_offset,
|
||||
new_budget.value());
|
||||
Goto(&end);
|
||||
|
||||
BIND(&end);
|
||||
Comment("] UpdateInterruptBudget");
|
||||
}
|
||||
|
||||
|
@ -2634,8 +2634,9 @@ IGNITION_HANDLER(CreateClosure, InterpreterAssembler) {
|
||||
Label if_undefined(this);
|
||||
TNode<FixedArray> feedback_cell_array =
|
||||
LoadClosureFeedbackArray(LoadRegister(Register::function_closure()));
|
||||
TNode<FeedbackCell> feedback_cell =
|
||||
CAST(LoadFixedArrayElement(feedback_cell_array, slot));
|
||||
TNode<FeedbackCell> feedback_cell = CAST(LoadFixedArrayElement(
|
||||
feedback_cell_array, slot,
|
||||
ClosureFeedbackCellArray::kFeedbackCellStartIndex * kTaggedSize));
|
||||
|
||||
Label if_fast(this), if_slow(this, Label::kDeferred);
|
||||
Branch(IsSetWord32<CreateClosureFlags::FastNewClosureBit>(flags), &if_fast,
|
||||
|
@ -832,6 +832,7 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
|
||||
p4);
|
||||
case FIXED_ARRAY_TYPE:
|
||||
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
|
||||
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
|
||||
case HASH_TABLE_TYPE:
|
||||
case ORDERED_HASH_MAP_TYPE:
|
||||
case ORDERED_HASH_SET_TYPE:
|
||||
|
@ -168,6 +168,7 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
|
||||
EmbedderDataArray::cast(*this)->EmbedderDataArrayVerify(isolate);
|
||||
break;
|
||||
// FixedArray types
|
||||
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
|
||||
case HASH_TABLE_TYPE:
|
||||
case ORDERED_HASH_MAP_TYPE:
|
||||
case ORDERED_HASH_SET_TYPE:
|
||||
|
@ -129,6 +129,7 @@ namespace internal {
|
||||
\
|
||||
V(FIXED_ARRAY_TYPE) \
|
||||
V(OBJECT_BOILERPLATE_DESCRIPTION_TYPE) \
|
||||
V(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE) \
|
||||
V(HASH_TABLE_TYPE) \
|
||||
V(ORDERED_HASH_MAP_TYPE) \
|
||||
V(ORDERED_HASH_SET_TYPE) \
|
||||
|
@ -197,6 +197,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
|
||||
case FEEDBACK_CELL_TYPE:
|
||||
FeedbackCell::cast(*this)->FeedbackCellPrint(os);
|
||||
break;
|
||||
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
|
||||
ClosureFeedbackCellArray::cast(*this)->ClosureFeedbackCellArrayPrint(os);
|
||||
break;
|
||||
case FEEDBACK_VECTOR_TYPE:
|
||||
FeedbackVector::cast(*this)->FeedbackVectorPrint(os);
|
||||
break;
|
||||
@ -1086,6 +1089,10 @@ void FeedbackMetadata::FeedbackMetadataPrint(std::ostream& os) {
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void ClosureFeedbackCellArray::ClosureFeedbackCellArrayPrint(std::ostream& os) {
|
||||
PrintFixedArrayWithHeader(os, *this, "ClosureFeedbackCellArray");
|
||||
}
|
||||
|
||||
void FeedbackVector::FeedbackVectorPrint(std::ostream& os) { // NOLINT
|
||||
PrintHeader(os, "FeedbackVector");
|
||||
os << "\n - length: " << length();
|
||||
|
@ -1988,6 +1988,10 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
|
||||
os << "<ClosureFeedbackCellArray["
|
||||
<< ClosureFeedbackCellArray::cast(*this)->length() << "]>";
|
||||
break;
|
||||
case FEEDBACK_VECTOR_TYPE:
|
||||
os << "<FeedbackVector[" << FeedbackVector::cast(*this)->length() << "]>";
|
||||
break;
|
||||
|
@ -99,6 +99,7 @@
|
||||
// - ScopeInfo
|
||||
// - ModuleInfo
|
||||
// - ScriptContextTable
|
||||
// - ClosureFeedbackCellArray
|
||||
// - FixedDoubleArray
|
||||
// - Name
|
||||
// - String
|
||||
@ -256,6 +257,7 @@ class AllocationSite;
|
||||
class ByteArray;
|
||||
class CachedTemplateObject;
|
||||
class Cell;
|
||||
class ClosureFeedbackCellArray;
|
||||
class ConsString;
|
||||
class DependentCode;
|
||||
class ElementsAccessor;
|
||||
@ -345,6 +347,7 @@ class ZoneForwardList;
|
||||
V(Constructor) \
|
||||
V(Context) \
|
||||
V(CoverageInfo) \
|
||||
V(ClosureFeedbackCellArray) \
|
||||
V(DataHandler) \
|
||||
V(DeoptimizationData) \
|
||||
V(DependentCode) \
|
||||
|
@ -830,6 +830,11 @@ class BytecodeArray : public FixedArrayBase {
|
||||
BYTECODE_ARRAY_FIELDS)
|
||||
#undef BYTECODE_ARRAY_FIELDS
|
||||
|
||||
// InterpreterEntryTrampoline expects these fields to be next to each other
|
||||
// and writes a 16-bit value to reset them.
|
||||
STATIC_ASSERT(BytecodeArray::kBytecodeAgeOffset ==
|
||||
kOSRNestingLevelOffset + kCharSize);
|
||||
|
||||
// Maximal memory consumption for a single BytecodeArray.
|
||||
static const int kMaxSize = 512 * MB;
|
||||
// Maximal length of a single BytecodeArray.
|
||||
|
@ -195,6 +195,7 @@ enum InstanceType : uint16_t {
|
||||
// FixedArrays.
|
||||
FIXED_ARRAY_TYPE, // FIRST_FIXED_ARRAY_TYPE
|
||||
OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
|
||||
CLOSURE_FEEDBACK_CELL_ARRAY_TYPE,
|
||||
HASH_TABLE_TYPE, // FIRST_HASH_TABLE_TYPE
|
||||
ORDERED_HASH_MAP_TYPE, // FIRST_DICTIONARY_TYPE
|
||||
ORDERED_HASH_SET_TYPE,
|
||||
@ -408,6 +409,7 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
|
||||
V(CachedTemplateObject, TUPLE3_TYPE) \
|
||||
V(CodeDataContainer, CODE_DATA_CONTAINER_TYPE) \
|
||||
V(CoverageInfo, FIXED_ARRAY_TYPE) \
|
||||
V(ClosureFeedbackCellArray, CLOSURE_FEEDBACK_CELL_ARRAY_TYPE) \
|
||||
V(DescriptorArray, DESCRIPTOR_ARRAY_TYPE) \
|
||||
V(EmbedderDataArray, EMBEDDER_DATA_ARRAY_TYPE) \
|
||||
V(EphemeronHashTable, EPHEMERON_HASH_TABLE_TYPE) \
|
||||
|
@ -467,9 +467,9 @@ FeedbackVector JSFunction::feedback_vector() const {
|
||||
return FeedbackVector::cast(raw_feedback_cell()->value());
|
||||
}
|
||||
|
||||
FixedArray JSFunction::closure_feedback_cell_array() const {
|
||||
ClosureFeedbackCellArray JSFunction::closure_feedback_cell_array() const {
|
||||
DCHECK(has_closure_feedback_cell_array());
|
||||
return FixedArray::cast(raw_feedback_cell()->value());
|
||||
return ClosureFeedbackCellArray::cast(raw_feedback_cell()->value());
|
||||
}
|
||||
|
||||
// Code objects that are marked for deoptimization are not considered to be
|
||||
@ -589,14 +589,12 @@ void JSFunction::SetOptimizationMarker(OptimizationMarker marker) {
|
||||
|
||||
bool JSFunction::has_feedback_vector() const {
|
||||
return shared()->is_compiled() &&
|
||||
!raw_feedback_cell()->value()->IsUndefined() &&
|
||||
raw_feedback_cell()->value()->IsFeedbackVector();
|
||||
}
|
||||
|
||||
bool JSFunction::has_closure_feedback_cell_array() const {
|
||||
return shared()->is_compiled() &&
|
||||
!raw_feedback_cell()->value()->IsUndefined() &&
|
||||
raw_feedback_cell()->value()->IsFixedArray();
|
||||
raw_feedback_cell()->value()->IsClosureFeedbackCellArray();
|
||||
}
|
||||
|
||||
Context JSFunction::context() {
|
||||
|
@ -4938,7 +4938,7 @@ void JSFunction::EnsureClosureFeedbackCellArray(Handle<JSFunction> function) {
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate);
|
||||
DCHECK(function->shared()->HasBytecodeArray());
|
||||
Handle<HeapObject> feedback_cell_array =
|
||||
FeedbackVector::NewClosureFeedbackCellArray(isolate, shared);
|
||||
ClosureFeedbackCellArray::New(isolate, shared);
|
||||
// Many closure cell is used as a way to specify that there is no
|
||||
// feedback cell for this function and a new feedback cell has to be
|
||||
// allocated for this funciton. For ex: for eval functions, we have to create
|
||||
@ -4966,7 +4966,7 @@ void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
|
||||
DCHECK(function->shared()->HasBytecodeArray());
|
||||
|
||||
EnsureClosureFeedbackCellArray(function);
|
||||
Handle<FixedArray> closure_feedback_cell_array =
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
|
||||
handle(function->closure_feedback_cell_array(), isolate);
|
||||
Handle<HeapObject> feedback_vector =
|
||||
FeedbackVector::New(isolate, shared, closure_feedback_cell_array);
|
||||
@ -4980,7 +4980,7 @@ void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
|
||||
|
||||
// static
|
||||
void JSFunction::InitializeFeedbackCell(Handle<JSFunction> function) {
|
||||
if (FLAG_lite_mode) {
|
||||
if (FLAG_lazy_feedback_allocation) {
|
||||
EnsureClosureFeedbackCellArray(function);
|
||||
} else {
|
||||
EnsureFeedbackVector(function);
|
||||
|
@ -1036,7 +1036,7 @@ class JSFunction : public JSObject {
|
||||
// cell arrays after compile, when we want to allocate feedback vectors
|
||||
// lazily.
|
||||
inline bool has_closure_feedback_cell_array() const;
|
||||
inline FixedArray closure_feedback_cell_array() const;
|
||||
inline ClosureFeedbackCellArray closure_feedback_cell_array() const;
|
||||
static void EnsureClosureFeedbackCellArray(Handle<JSFunction> function);
|
||||
|
||||
// Initializes the feedback cell of |function|. In lite mode, this would be
|
||||
|
@ -133,6 +133,7 @@ VisitorId Map::GetVisitorId(Map map) {
|
||||
|
||||
case FIXED_ARRAY_TYPE:
|
||||
case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
|
||||
case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
|
||||
case HASH_TABLE_TYPE:
|
||||
case ORDERED_HASH_MAP_TYPE:
|
||||
case ORDERED_HASH_SET_TYPE:
|
||||
|
@ -60,6 +60,8 @@ class RootVisitor;
|
||||
V(Map, foreign_map, ForeignMap) \
|
||||
V(Map, heap_number_map, HeapNumberMap) \
|
||||
V(Map, transition_array_map, TransitionArrayMap) \
|
||||
/* TODO(mythria): Once lazy feedback lands, check if feedback vector map */ \
|
||||
/* is still a popular map */ \
|
||||
V(Map, feedback_vector_map, FeedbackVectorMap) \
|
||||
V(ScopeInfo, empty_scope_info, EmptyScopeInfo) \
|
||||
V(FixedArray, empty_fixed_array, EmptyFixedArray) \
|
||||
@ -83,6 +85,7 @@ class RootVisitor;
|
||||
V(Map, debug_evaluate_context_map, DebugEvaluateContextMap) \
|
||||
V(Map, script_context_table_map, ScriptContextTableMap) \
|
||||
/* Maps */ \
|
||||
V(Map, closure_feedback_cell_array_map, ClosureFeedbackCellArrayMap) \
|
||||
V(Map, feedback_metadata_map, FeedbackMetadataArrayMap) \
|
||||
V(Map, array_list_map, ArrayListMap) \
|
||||
V(Map, bigint_map, BigIntMap) \
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "src/conversions.h"
|
||||
#include "src/counters.h"
|
||||
#include "src/debug/debug.h"
|
||||
#include "src/feedback-vector-inl.h"
|
||||
#include "src/frames-inl.h"
|
||||
#include "src/isolate-inl.h"
|
||||
#include "src/message-template.h"
|
||||
@ -271,6 +272,25 @@ RUNTIME_FUNCTION(Runtime_StackGuard) {
|
||||
return isolate->stack_guard()->HandleInterrupts();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterrupt) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
||||
if (!function->has_feedback_vector()) {
|
||||
JSFunction::EnsureFeedbackVector(function);
|
||||
// Also initialize the invocation count here. This is only really needed for
|
||||
// OSR. When we OSR functions with lazy feedback allocation we want to have
|
||||
// a non zero invocation count so we can inline functions.
|
||||
function->feedback_vector()->set_invocation_count(1);
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
// Handle interrupts.
|
||||
{
|
||||
SealHandleScope shs(isolate);
|
||||
return isolate->stack_guard()->HandleInterrupts();
|
||||
}
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_Interrupt) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(0, args.length());
|
||||
|
@ -140,15 +140,16 @@ Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
|
||||
Handle<Context> context(isolate->context(), isolate);
|
||||
|
||||
Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>::null();
|
||||
Handle<FixedArray> closure_feedback_cell_array = Handle<FixedArray>::null();
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
|
||||
Handle<ClosureFeedbackCellArray>::null();
|
||||
if (closure->has_feedback_vector()) {
|
||||
feedback_vector =
|
||||
Handle<FeedbackVector>(closure->feedback_vector(), isolate);
|
||||
closure_feedback_cell_array = Handle<FixedArray>(
|
||||
closure_feedback_cell_array = Handle<ClosureFeedbackCellArray>(
|
||||
feedback_vector->closure_feedback_cell_array(), isolate);
|
||||
} else {
|
||||
closure_feedback_cell_array =
|
||||
Handle<FixedArray>(closure->closure_feedback_cell_array(), isolate);
|
||||
closure_feedback_cell_array = Handle<ClosureFeedbackCellArray>(
|
||||
closure->closure_feedback_cell_array(), isolate);
|
||||
}
|
||||
|
||||
// Traverse the name/value pairs and set the properties.
|
||||
@ -167,10 +168,9 @@ Object DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations,
|
||||
Handle<Object> value;
|
||||
if (is_function) {
|
||||
DCHECK(possibly_feedback_cell_slot->IsSmi());
|
||||
Handle<FeedbackCell> feedback_cell = Handle<FeedbackCell>(
|
||||
FeedbackCell::cast(closure_feedback_cell_array->get(
|
||||
Smi::ToInt(*possibly_feedback_cell_slot))),
|
||||
isolate);
|
||||
Handle<FeedbackCell> feedback_cell =
|
||||
closure_feedback_cell_array->GetFeedbackCell(
|
||||
Smi::ToInt(*possibly_feedback_cell_slot));
|
||||
// Copy the function and update its context. Use it as value.
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
Handle<SharedFunctionInfo>::cast(initial_value);
|
||||
|
@ -299,6 +299,39 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool EnsureFeedbackVector(Handle<JSFunction> function) {
|
||||
// Check function allows lazy compilation.
|
||||
if (!function->shared()->allows_lazy_compilation()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If function isn't compiled, compile it now.
|
||||
IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
|
||||
if (!is_compiled_scope.is_compiled() &&
|
||||
!Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
|
||||
&is_compiled_scope)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure function has a feedback vector to hold type feedback for
|
||||
// optimization.
|
||||
JSFunction::EnsureFeedbackVector(function);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_EnsureFeedbackVectorForFunction) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
||||
|
||||
EnsureFeedbackVector(function);
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
@ -307,23 +340,10 @@ RUNTIME_FUNCTION(Runtime_PrepareFunctionForOptimization) {
|
||||
// Only one function should be prepared for optimization at a time
|
||||
CHECK(isolate->heap()->pending_optimize_for_test_bytecode()->IsUndefined());
|
||||
|
||||
// Check function allows lazy compilation.
|
||||
if (!function->shared()->allows_lazy_compilation()) {
|
||||
if (!EnsureFeedbackVector(function)) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
// If function isn't compiled, compile it now.
|
||||
IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
|
||||
if (!is_compiled_scope.is_compiled() &&
|
||||
!Compiler::Compile(function, Compiler::CLEAR_EXCEPTION,
|
||||
&is_compiled_scope)) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
// Ensure function has a feedback vector to hold type feedback for
|
||||
// optimization.
|
||||
JSFunction::EnsureFeedbackVector(function);
|
||||
|
||||
// If optimization is disabled for the function, return without making it
|
||||
// pending optimize for test.
|
||||
if (function->shared()->optimization_disabled() &&
|
||||
|
@ -219,6 +219,7 @@ namespace internal {
|
||||
F(GetTemplateObject, 3, 1) \
|
||||
F(IncrementUseCounter, 1, 1) \
|
||||
F(Interrupt, 0, 1) \
|
||||
F(BytecodeBudgetInterrupt, 1, 1) \
|
||||
F(NewReferenceError, 2, 1) \
|
||||
F(NewSyntaxError, 2, 1) \
|
||||
F(NewTypeError, 2, 1) \
|
||||
@ -494,6 +495,7 @@ namespace internal {
|
||||
F(NotifyContextDisposed, 0, 1) \
|
||||
F(OptimizeFunctionOnNextCall, -1, 1) \
|
||||
F(OptimizeOsr, -1, 1) \
|
||||
F(EnsureFeedbackVectorForFunction, 1, 1) \
|
||||
F(PrepareFunctionForOptimization, 1, 1) \
|
||||
F(PrintWithNameForAssert, 2, 1) \
|
||||
F(RedirectToWasmInterpreter, 2, 1) \
|
||||
|
@ -555,6 +555,12 @@
|
||||
'test-cpu-profiler/TickLinesBaseline': [SKIP],
|
||||
'test-cpu-profiler/TickLinesOptimized': [SKIP],
|
||||
'test-cpu-profiler/Inlining2': [SKIP],
|
||||
|
||||
# TODO(mythria): Code logging tests that currently fail with lazy feedback
|
||||
# allocation. Fix logging to work without feedback vectors and enable these
|
||||
# tests in lite_mode.
|
||||
'test-log/ExternalCodeEventListenerWithInterpretedFramesNativeStack': [SKIP],
|
||||
'test-log/LogInterpretedFramesNativeStack': [SKIP]
|
||||
}], # lite_mode
|
||||
|
||||
##############################################################################
|
||||
|
@ -3224,6 +3224,7 @@ TEST(IncrementalMarkingPreservesMonomorphicCallIC) {
|
||||
if (!FLAG_use_ic) return;
|
||||
if (!FLAG_incremental_marking) return;
|
||||
if (FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Value> fun1, fun2;
|
||||
@ -3241,7 +3242,9 @@ TEST(IncrementalMarkingPreservesMonomorphicCallIC) {
|
||||
// Prepare function f that contains type feedback for the two closures.
|
||||
CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust());
|
||||
CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust());
|
||||
CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);");
|
||||
CompileRun(
|
||||
"function f(a, b) { a(); b(); } %EnsureFeedbackVectorForFunction(f); "
|
||||
"f(fun1, fun2);");
|
||||
|
||||
Handle<JSFunction> f = Handle<JSFunction>::cast(
|
||||
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
|
||||
@ -3276,9 +3279,9 @@ static void CheckVectorIC(Handle<JSFunction> f, int slot_index,
|
||||
}
|
||||
|
||||
TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
|
||||
if (FLAG_lite_mode) return;
|
||||
if (!FLAG_incremental_marking) return;
|
||||
if (FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
|
||||
@ -3286,7 +3289,9 @@ TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
|
||||
// originating from the same native context.
|
||||
CompileRun(
|
||||
"function fun() { this.x = 1; };"
|
||||
"function f(o) { return new o(); } f(fun); f(fun);");
|
||||
"function f(o) { return new o(); }"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"f(fun); f(fun);");
|
||||
Handle<JSFunction> f = Handle<JSFunction>::cast(
|
||||
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
|
||||
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
|
||||
@ -3304,13 +3309,16 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
|
||||
if (!FLAG_use_ic) return;
|
||||
if (!FLAG_incremental_marking) return;
|
||||
if (FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
|
||||
// Prepare function f that contains a monomorphic IC for object
|
||||
// originating from the same native context.
|
||||
CompileRun("function fun() { this.x = 1; }; var obj = new fun();"
|
||||
"function f(o) { return o.x; } f(obj); f(obj);");
|
||||
CompileRun(
|
||||
"function fun() { this.x = 1; }; var obj = new fun();"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(o) { return o.x; } f(obj); f(obj);");
|
||||
Handle<JSFunction> f = Handle<JSFunction>::cast(
|
||||
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
|
||||
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
|
||||
@ -3327,6 +3335,7 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
|
||||
if (!FLAG_use_ic) return;
|
||||
if (!FLAG_incremental_marking) return;
|
||||
if (FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Value> obj1, obj2;
|
||||
@ -3348,7 +3357,10 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
|
||||
// originating from two different native contexts.
|
||||
CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust());
|
||||
CHECK(CcTest::global()->Set(ctx, v8_str("obj2"), obj2).FromJust());
|
||||
CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);");
|
||||
CompileRun(
|
||||
"function f(o) { return o.x; }; "
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"f(obj1); f(obj1); f(obj2);");
|
||||
Handle<JSFunction> f = Handle<JSFunction>::cast(
|
||||
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
|
||||
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
|
||||
@ -3366,6 +3378,7 @@ TEST(ContextDisposeDoesntClearPolymorphicIC) {
|
||||
if (!FLAG_use_ic) return;
|
||||
if (!FLAG_incremental_marking) return;
|
||||
if (FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Value> obj1, obj2;
|
||||
@ -3387,7 +3400,10 @@ TEST(ContextDisposeDoesntClearPolymorphicIC) {
|
||||
// originating from two different native contexts.
|
||||
CHECK(CcTest::global()->Set(ctx, v8_str("obj1"), obj1).FromJust());
|
||||
CHECK(CcTest::global()->Set(ctx, v8_str("obj2"), obj2).FromJust());
|
||||
CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);");
|
||||
CompileRun(
|
||||
"function f(o) { return o.x; }; "
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"f(obj1); f(obj1); f(obj2);");
|
||||
Handle<JSFunction> f = Handle<JSFunction>::cast(
|
||||
v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
|
||||
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
|
||||
@ -4481,6 +4497,7 @@ TEST(WeakFunctionInConstructor) {
|
||||
void CheckWeakness(const char* source) {
|
||||
FLAG_stress_compaction = false;
|
||||
FLAG_stress_incremental_marking = false;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CcTest::InitializeVM();
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
LocalContext env;
|
||||
@ -4503,17 +4520,19 @@ void CheckWeakness(const char* source) {
|
||||
// Each of the following "weak IC" tests creates an IC that embeds a map with
|
||||
// the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
|
||||
TEST(WeakMapInMonomorphicLoadIC) {
|
||||
CheckWeakness("function loadIC(obj) {"
|
||||
" return obj.name;"
|
||||
"}"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" loadIC(obj);"
|
||||
" loadIC(obj);"
|
||||
" loadIC(obj);"
|
||||
" return proto;"
|
||||
" })();");
|
||||
CheckWeakness(
|
||||
"function loadIC(obj) {"
|
||||
" return obj.name;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(loadIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" loadIC(obj);"
|
||||
" loadIC(obj);"
|
||||
" loadIC(obj);"
|
||||
" return proto;"
|
||||
" })();");
|
||||
}
|
||||
|
||||
|
||||
@ -4522,6 +4541,7 @@ TEST(WeakMapInPolymorphicLoadIC) {
|
||||
"function loadIC(obj) {"
|
||||
" return obj.name;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(loadIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
@ -4537,17 +4557,19 @@ TEST(WeakMapInPolymorphicLoadIC) {
|
||||
|
||||
|
||||
TEST(WeakMapInMonomorphicKeyedLoadIC) {
|
||||
CheckWeakness("function keyedLoadIC(obj, field) {"
|
||||
" return obj[field];"
|
||||
"}"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" keyedLoadIC(obj, 'name');"
|
||||
" keyedLoadIC(obj, 'name');"
|
||||
" keyedLoadIC(obj, 'name');"
|
||||
" return proto;"
|
||||
" })();");
|
||||
CheckWeakness(
|
||||
"function keyedLoadIC(obj, field) {"
|
||||
" return obj[field];"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(keyedLoadIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" keyedLoadIC(obj, 'name');"
|
||||
" keyedLoadIC(obj, 'name');"
|
||||
" keyedLoadIC(obj, 'name');"
|
||||
" return proto;"
|
||||
" })();");
|
||||
}
|
||||
|
||||
|
||||
@ -4556,6 +4578,7 @@ TEST(WeakMapInPolymorphicKeyedLoadIC) {
|
||||
"function keyedLoadIC(obj, field) {"
|
||||
" return obj[field];"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(keyedLoadIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
@ -4571,17 +4594,19 @@ TEST(WeakMapInPolymorphicKeyedLoadIC) {
|
||||
|
||||
|
||||
TEST(WeakMapInMonomorphicStoreIC) {
|
||||
CheckWeakness("function storeIC(obj, value) {"
|
||||
" obj.name = value;"
|
||||
"}"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" storeIC(obj, 'x');"
|
||||
" storeIC(obj, 'x');"
|
||||
" storeIC(obj, 'x');"
|
||||
" return proto;"
|
||||
" })();");
|
||||
CheckWeakness(
|
||||
"function storeIC(obj, value) {"
|
||||
" obj.name = value;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(storeIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" storeIC(obj, 'x');"
|
||||
" storeIC(obj, 'x');"
|
||||
" storeIC(obj, 'x');"
|
||||
" return proto;"
|
||||
" })();");
|
||||
}
|
||||
|
||||
|
||||
@ -4590,6 +4615,7 @@ TEST(WeakMapInPolymorphicStoreIC) {
|
||||
"function storeIC(obj, value) {"
|
||||
" obj.name = value;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(storeIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
@ -4605,17 +4631,19 @@ TEST(WeakMapInPolymorphicStoreIC) {
|
||||
|
||||
|
||||
TEST(WeakMapInMonomorphicKeyedStoreIC) {
|
||||
CheckWeakness("function keyedStoreIC(obj, field, value) {"
|
||||
" obj[field] = value;"
|
||||
"}"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" keyedStoreIC(obj, 'x');"
|
||||
" keyedStoreIC(obj, 'x');"
|
||||
" keyedStoreIC(obj, 'x');"
|
||||
" return proto;"
|
||||
" })();");
|
||||
CheckWeakness(
|
||||
"function keyedStoreIC(obj, field, value) {"
|
||||
" obj[field] = value;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(keyedStoreIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" keyedStoreIC(obj, 'x');"
|
||||
" keyedStoreIC(obj, 'x');"
|
||||
" keyedStoreIC(obj, 'x');"
|
||||
" return proto;"
|
||||
" })();");
|
||||
}
|
||||
|
||||
|
||||
@ -4624,6 +4652,7 @@ TEST(WeakMapInPolymorphicKeyedStoreIC) {
|
||||
"function keyedStoreIC(obj, field, value) {"
|
||||
" obj[field] = value;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(keyedStoreIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
@ -4639,17 +4668,20 @@ TEST(WeakMapInPolymorphicKeyedStoreIC) {
|
||||
|
||||
|
||||
TEST(WeakMapInMonomorphicCompareNilIC) {
|
||||
CheckWeakness("function compareNilIC(obj) {"
|
||||
" return obj == null;"
|
||||
"}"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" compareNilIC(obj);"
|
||||
" compareNilIC(obj);"
|
||||
" compareNilIC(obj);"
|
||||
" return proto;"
|
||||
" })();");
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CheckWeakness(
|
||||
"function compareNilIC(obj) {"
|
||||
" return obj == null;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(compareNilIC);"
|
||||
" (function() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
" compareNilIC(obj);"
|
||||
" compareNilIC(obj);"
|
||||
" compareNilIC(obj);"
|
||||
" return proto;"
|
||||
" })();");
|
||||
}
|
||||
|
||||
|
||||
@ -4676,10 +4708,12 @@ TEST(MonomorphicStaysMonomorphicAfterGC) {
|
||||
CcTest::InitializeVM();
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CompileRun(
|
||||
"function loadIC(obj) {"
|
||||
" return obj.name;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(loadIC);"
|
||||
"function testIC() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
@ -4710,10 +4744,12 @@ TEST(PolymorphicStaysPolymorphicAfterGC) {
|
||||
CcTest::InitializeVM();
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
FLAG_allow_natives_syntax = true;
|
||||
CompileRun(
|
||||
"function loadIC(obj) {"
|
||||
" return obj.name;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(loadIC);"
|
||||
"function testIC() {"
|
||||
" var proto = {'name' : 'weak'};"
|
||||
" var obj = Object.create(proto);"
|
||||
|
@ -29,8 +29,10 @@ Handle<FeedbackVector> CreateFeedbackVectorForTest(
|
||||
Handle<Object> obj = v8::Utils::OpenHandle(*script);
|
||||
Handle<SharedFunctionInfo> shared_function =
|
||||
Handle<SharedFunctionInfo>(JSFunction::cast(*obj)->shared(), i_isolate);
|
||||
Handle<FeedbackVector> fv =
|
||||
factory->NewFeedbackVector(shared_function, allocation);
|
||||
Handle<ClosureFeedbackCellArray> closure_cell_array =
|
||||
ClosureFeedbackCellArray::New(i_isolate, shared_function);
|
||||
Handle<FeedbackVector> fv = factory->NewFeedbackVector(
|
||||
shared_function, closure_cell_array, allocation);
|
||||
return fv;
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,7 @@ TEST(VectorICMetadata) {
|
||||
TEST(VectorCallICStates) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -164,7 +165,8 @@ TEST(VectorCallICStates) {
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"function foo() { return 17; }"
|
||||
"function foo() { return 17; };"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { a(); } f(foo);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
// There should be one IC.
|
||||
@ -185,6 +187,7 @@ TEST(VectorCallICStates) {
|
||||
TEST(VectorCallFeedback) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -193,6 +196,7 @@ TEST(VectorCallFeedback) {
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"function foo() { return 17; }"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { a(); } f(foo);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
Handle<JSFunction> foo = GetFunction("foo");
|
||||
@ -215,13 +219,17 @@ TEST(VectorCallFeedback) {
|
||||
TEST(VectorCallFeedbackForArray) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
v8::HandleScope scope(context->GetIsolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun("function f(a) { a(); } f(Array);");
|
||||
CompileRun(
|
||||
"function f(a) { a(); };"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"f(Array);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
// There should be one IC.
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
@ -252,6 +260,8 @@ size_t GetFeedbackVectorLength(Isolate* isolate, const char* src,
|
||||
TEST(OneShotCallICSlotCount) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
if (i::FLAG_lazy_feedback_allocation) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -306,6 +316,7 @@ TEST(OneShotCallICSlotCount) {
|
||||
TEST(VectorCallCounts) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -315,6 +326,7 @@ TEST(VectorCallCounts) {
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"function foo() { return 17; }"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { a(); } f(foo);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
// There should be one IC.
|
||||
@ -337,6 +349,7 @@ TEST(VectorCallCounts) {
|
||||
TEST(VectorConstructCounts) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -346,6 +359,7 @@ TEST(VectorConstructCounts) {
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"function Foo() {}"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { new a(); } f(Foo);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
@ -370,6 +384,7 @@ TEST(VectorConstructCounts) {
|
||||
TEST(VectorSpeculationMode) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -379,6 +394,7 @@ TEST(VectorSpeculationMode) {
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"function Foo() {}"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { new a(); } f(Foo);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
@ -404,6 +420,7 @@ TEST(VectorSpeculationMode) {
|
||||
TEST(VectorLoadICStates) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -413,6 +430,7 @@ TEST(VectorLoadICStates) {
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"var o = { foo: 3 };"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { return a.foo; } f(o);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
// There should be one IC.
|
||||
@ -459,6 +477,7 @@ TEST(VectorLoadICStates) {
|
||||
TEST(VectorLoadGlobalICSlotSharing) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -474,6 +493,7 @@ TEST(VectorLoadGlobalICSlotSharing) {
|
||||
" var y = typeof o;"
|
||||
" return o , typeof o, x , y, o;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"f();");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
// There should be two IC slots for {o} references outside and inside
|
||||
@ -494,6 +514,7 @@ TEST(VectorLoadGlobalICSlotSharing) {
|
||||
TEST(VectorLoadICOnSmi) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -504,6 +525,7 @@ TEST(VectorLoadICOnSmi) {
|
||||
// Make sure function f has a call that uses a type feedback slot.
|
||||
CompileRun(
|
||||
"var o = { foo: 3 };"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"function f(a) { return a.foo; } f(o);");
|
||||
Handle<JSFunction> f = GetFunction("f");
|
||||
// There should be one IC.
|
||||
@ -554,6 +576,7 @@ TEST(VectorLoadICOnSmi) {
|
||||
TEST(ReferenceContextAllocatesNoSlots) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -567,6 +590,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
" y = a;"
|
||||
" return y;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(testvar);"
|
||||
"a = 3;"
|
||||
"testvar({});");
|
||||
|
||||
@ -588,6 +612,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
" 'use strict';"
|
||||
" x.blue = a;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(testprop);"
|
||||
"testprop({ blue: 3 });");
|
||||
|
||||
Handle<JSFunction> f = GetFunction("testprop");
|
||||
@ -606,6 +631,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
" x().blue = a;"
|
||||
" return x().blue;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(testpropfunc);"
|
||||
"function makeresult() { return { blue: 3 }; }"
|
||||
"testpropfunc(makeresult);");
|
||||
|
||||
@ -629,6 +655,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
" x[0] = a;"
|
||||
" return x[0];"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(testkeyedprop);"
|
||||
"testkeyedprop([0, 1, 2]);");
|
||||
|
||||
Handle<JSFunction> f = GetFunction("testkeyedprop");
|
||||
@ -650,6 +677,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
" x[0] = a;"
|
||||
" return x[0];"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(testkeyedprop);"
|
||||
"testkeyedprop([0, 1, 2]);");
|
||||
|
||||
Handle<JSFunction> f = GetFunction("testkeyedprop");
|
||||
@ -671,6 +699,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
" x.old = x.young = x.in_between = a;"
|
||||
" return x.old + x.young;"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(testcompound);"
|
||||
"testcompound({ old: 3, young: 3, in_between: 3 });");
|
||||
|
||||
Handle<JSFunction> f = GetFunction("testcompound");
|
||||
@ -694,6 +723,7 @@ TEST(ReferenceContextAllocatesNoSlots) {
|
||||
TEST(VectorStoreICBasic) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -702,7 +732,8 @@ TEST(VectorStoreICBasic) {
|
||||
CompileRun(
|
||||
"function f(a) {"
|
||||
" a.foo = 5;"
|
||||
"}"
|
||||
"};"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"var a = { foo: 3 };"
|
||||
"f(a);"
|
||||
"f(a);"
|
||||
@ -720,6 +751,7 @@ TEST(VectorStoreICBasic) {
|
||||
TEST(StoreOwnIC) {
|
||||
if (!i::FLAG_use_ic) return;
|
||||
if (i::FLAG_always_opt) return;
|
||||
FLAG_allow_natives_syntax = true;
|
||||
|
||||
CcTest::InitializeVM();
|
||||
LocalContext context;
|
||||
@ -729,6 +761,7 @@ TEST(StoreOwnIC) {
|
||||
"function f(v) {"
|
||||
" return {a: 0, b: v, c: 0};"
|
||||
"}"
|
||||
"%EnsureFeedbackVectorForFunction(f);"
|
||||
"f(1);"
|
||||
"f(2);"
|
||||
"f(3);");
|
||||
|
@ -49,8 +49,8 @@ Handle<FeedbackVector> NewFeedbackVector(Isolate* isolate, Spec* spec) {
|
||||
// Set the raw feedback metadata to circumvent checks that we are not
|
||||
// overwriting existing metadata.
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
|
||||
Handle<FixedArray> closure_feedback_cell_array =
|
||||
FeedbackVector::NewClosureFeedbackCellArray(isolate, shared);
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
|
||||
ClosureFeedbackCellArray::New(isolate, shared);
|
||||
return FeedbackVector::New(isolate, shared, closure_feedback_cell_array);
|
||||
}
|
||||
|
||||
|
@ -3908,7 +3908,10 @@ TEST(WeakReference) {
|
||||
i::Handle<i::SharedFunctionInfo> shared_function =
|
||||
i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared(),
|
||||
i_isolate);
|
||||
i::Handle<i::FeedbackVector> fv = factory->NewFeedbackVector(shared_function);
|
||||
i::Handle<i::ClosureFeedbackCellArray> feedback_cell_array =
|
||||
i::ClosureFeedbackCellArray::New(i_isolate, shared_function);
|
||||
i::Handle<i::FeedbackVector> fv =
|
||||
factory->NewFeedbackVector(shared_function, feedback_cell_array);
|
||||
|
||||
// Create a Code.
|
||||
i::Assembler assm(i::AssemblerOptions{});
|
||||
|
@ -174,20 +174,25 @@ function make_array() {
|
||||
return eval(make_array_string());
|
||||
}
|
||||
|
||||
%EnsureFeedbackVectorForFunction(construct_smis);
|
||||
function construct_smis() {
|
||||
var a = make_array();
|
||||
a[0] = 0; // Send the COW array map to the steak house.
|
||||
assertKind(elements_kind.fast_smi_only, a);
|
||||
return a;
|
||||
}
|
||||
|
||||
%NeverOptimizeFunction(construct_doubles);
|
||||
%EnsureFeedbackVectorForFunction(construct_doubles);
|
||||
function construct_doubles() {
|
||||
var a = construct_smis();
|
||||
a[0] = 1.5;
|
||||
assertKind(elements_kind.fast_double, a);
|
||||
return a;
|
||||
}
|
||||
|
||||
%NeverOptimizeFunction(construct_objects);
|
||||
%EnsureFeedbackVectorForFunction(construct_objects);
|
||||
function construct_objects() {
|
||||
var a = construct_smis();
|
||||
a[0] = "one";
|
||||
@ -196,6 +201,7 @@ function construct_objects() {
|
||||
}
|
||||
|
||||
// Test crankshafted transition SMI->DOUBLE.
|
||||
%EnsureFeedbackVectorForFunction(convert_to_double);
|
||||
%NeverOptimizeFunction(convert_to_double);
|
||||
function convert_to_double(array) {
|
||||
array[1] = 2.5;
|
||||
@ -208,6 +214,7 @@ for (var i = 0; i < 3; i++) convert_to_double(smis);
|
||||
smis = construct_smis();
|
||||
convert_to_double(smis);
|
||||
// Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
|
||||
%EnsureFeedbackVectorForFunction(convert_to_fast);
|
||||
%NeverOptimizeFunction(convert_to_fast);
|
||||
function convert_to_fast(array) {
|
||||
array[1] = "two";
|
||||
@ -225,7 +232,8 @@ convert_to_fast(smis);
|
||||
convert_to_fast(doubles);
|
||||
// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
|
||||
// transition to FAST directly).
|
||||
%NeverOptimizeFunction(convert_mixed);
|
||||
%EnsureFeedbackVectorForFunction(convert_mixed);
|
||||
%NeverOptimizeFunction(convert_mixed);
|
||||
function convert_mixed(array, value, kind) {
|
||||
array[1] = value;
|
||||
assertKind(kind, array);
|
||||
@ -267,6 +275,7 @@ function crankshaft_test() {
|
||||
var c = [get(1), get(2), get(3.5)];
|
||||
assertKind(elements_kind.fast_double, c);
|
||||
}
|
||||
%PrepareFunctionForOptimization(crankshaft_test);
|
||||
for (var i = 0; i < 3; i++) {
|
||||
crankshaft_test();
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ function make_array() {
|
||||
return eval(make_array_string());
|
||||
}
|
||||
|
||||
%EnsureFeedbackVectorForFunction(construct_smis);
|
||||
function construct_smis() {
|
||||
var a = make_array();
|
||||
a[0] = 0; // Send the COW array map to the steak house.
|
||||
@ -108,6 +109,7 @@ function construct_smis() {
|
||||
}
|
||||
|
||||
%NeverOptimizeFunction(construct_doubles);
|
||||
%EnsureFeedbackVectorForFunction(construct_doubles);
|
||||
function construct_doubles() {
|
||||
var a = construct_smis();
|
||||
a[0] = 1.5;
|
||||
@ -116,12 +118,14 @@ function construct_doubles() {
|
||||
}
|
||||
|
||||
%NeverOptimizeFunction(convert_mixed);
|
||||
%EnsureFeedbackVectorForFunction(convert_mixed);
|
||||
function convert_mixed(array, value, kind) {
|
||||
array[1] = value;
|
||||
assertKind(kind, array);
|
||||
assertEquals(value, array[1]);
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(test1);
|
||||
function test1() {
|
||||
// Test transition chain SMI->DOUBLE->FAST (crankshafted function will
|
||||
// transition to FAST directly).
|
||||
|
@ -87,59 +87,66 @@ function assertKind(expected, obj, name_opt) {
|
||||
assertEquals(expected, getKind(obj), name_opt);
|
||||
}
|
||||
|
||||
%NeverOptimizeFunction(construct_smis);
|
||||
%NeverOptimizeFunction(construct_doubles);
|
||||
%NeverOptimizeFunction(convert_mixed);
|
||||
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }
|
||||
%EnsureFeedbackVectorForFunction(test_osr_elements_kind);
|
||||
function test_osr_elements_kind() {
|
||||
%NeverOptimizeFunction(construct_smis);
|
||||
%NeverOptimizeFunction(construct_doubles);
|
||||
%NeverOptimizeFunction(convert_mixed);
|
||||
for (var i = 0; i < 10; i++) { if (i == 5) %OptimizeOsr(); }
|
||||
|
||||
// This code exists to eliminate the learning influence of AllocationSites
|
||||
// on the following tests.
|
||||
var __sequence = 0;
|
||||
function make_array_string() {
|
||||
this.__sequence = this.__sequence + 1;
|
||||
return "/* " + this.__sequence + " */ [0, 0, 0];"
|
||||
}
|
||||
function make_array() {
|
||||
return eval(make_array_string());
|
||||
}
|
||||
// This code exists to eliminate the learning influence of AllocationSites
|
||||
// on the following tests.
|
||||
var __sequence = 0;
|
||||
function make_array_string() {
|
||||
this.__sequence = this.__sequence + 1;
|
||||
return "/* " + this.__sequence + " */ [0, 0, 0];"
|
||||
}
|
||||
function make_array() {
|
||||
return eval(make_array_string());
|
||||
}
|
||||
|
||||
function construct_smis() {
|
||||
var a = make_array();
|
||||
a[0] = 0; // Send the COW array map to the steak house.
|
||||
assertKind(elements_kind.fast_smi_only, a);
|
||||
return a;
|
||||
}
|
||||
function construct_doubles() {
|
||||
var a = construct_smis();
|
||||
a[0] = 1.5;
|
||||
assertKind(elements_kind.fast_double, a);
|
||||
return a;
|
||||
}
|
||||
%EnsureFeedbackVectorForFunction(construct_smis);
|
||||
function construct_smis() {
|
||||
var a = make_array();
|
||||
a[0] = 0; // Send the COW array map to the steak house.
|
||||
assertKind(elements_kind.fast_smi_only, a);
|
||||
return a;
|
||||
}
|
||||
|
||||
// Test transition chain SMI->DOUBLE->FAST (optimized function will
|
||||
// transition to FAST directly).
|
||||
function convert_mixed(array, value, kind) {
|
||||
array[1] = value;
|
||||
assertKind(kind, array);
|
||||
assertEquals(value, array[1]);
|
||||
}
|
||||
smis = construct_smis();
|
||||
convert_mixed(smis, 1.5, elements_kind.fast_double);
|
||||
%EnsureFeedbackVectorForFunction(construct_doubles);
|
||||
function construct_doubles() {
|
||||
var a = construct_smis();
|
||||
a[0] = 1.5;
|
||||
assertKind(elements_kind.fast_double, a);
|
||||
return a;
|
||||
}
|
||||
|
||||
doubles = construct_doubles();
|
||||
convert_mixed(doubles, "three", elements_kind.fast);
|
||||
|
||||
convert_mixed(construct_smis(), "three", elements_kind.fast);
|
||||
convert_mixed(construct_doubles(), "three", elements_kind.fast);
|
||||
|
||||
if (%ICsAreEnabled()) {
|
||||
// Test that allocation sites allocate correct elements kind initially based
|
||||
// on previous transitions.
|
||||
// Test transition chain SMI->DOUBLE->FAST (optimized function will
|
||||
// transition to FAST directly).
|
||||
%EnsureFeedbackVectorForFunction(convert_mixed);
|
||||
function convert_mixed(array, value, kind) {
|
||||
array[1] = value;
|
||||
assertKind(kind, array);
|
||||
assertEquals(value, array[1]);
|
||||
}
|
||||
smis = construct_smis();
|
||||
convert_mixed(smis, 1.5, elements_kind.fast_double);
|
||||
|
||||
doubles = construct_doubles();
|
||||
convert_mixed(smis, 1, elements_kind.fast);
|
||||
convert_mixed(doubles, 1, elements_kind.fast);
|
||||
assertTrue(%HaveSameMap(smis, doubles));
|
||||
convert_mixed(doubles, "three", elements_kind.fast);
|
||||
|
||||
convert_mixed(construct_smis(), "three", elements_kind.fast);
|
||||
convert_mixed(construct_doubles(), "three", elements_kind.fast);
|
||||
|
||||
if (%ICsAreEnabled()) {
|
||||
// Test that allocation sites allocate correct elements kind initially based
|
||||
// on previous transitions.
|
||||
smis = construct_smis();
|
||||
doubles = construct_doubles();
|
||||
convert_mixed(smis, 1, elements_kind.fast);
|
||||
convert_mixed(doubles, 1, elements_kind.fast);
|
||||
assertTrue(%HaveSameMap(smis, doubles));
|
||||
}
|
||||
}
|
||||
|
||||
// Throw away type information in the ICs for next stress run.
|
||||
|
@ -108,8 +108,8 @@ class JSCallReducerTest : public TypedGraphTest {
|
||||
// Set the raw feedback metadata to circumvent checks that we are not
|
||||
// overwriting existing metadata.
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
|
||||
Handle<FixedArray> closure_feedback_cell_array =
|
||||
FeedbackVector::NewClosureFeedbackCellArray(isolate(), shared);
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
|
||||
ClosureFeedbackCellArray::New(isolate(), shared);
|
||||
Handle<FeedbackVector> vector =
|
||||
FeedbackVector::New(isolate(), shared, closure_feedback_cell_array);
|
||||
VectorSlotPair feedback(vector, FeedbackSlot(0), UNINITIALIZED);
|
||||
|
@ -35,8 +35,8 @@ class RedundancyEliminationTest : public GraphTest {
|
||||
isolate()->factory()->NewSharedFunctionInfoForBuiltin(
|
||||
isolate()->factory()->empty_string(), Builtins::kIllegal);
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(*metadata);
|
||||
Handle<FixedArray> closure_feedback_cell_array =
|
||||
FeedbackVector::NewClosureFeedbackCellArray(isolate(), shared);
|
||||
Handle<ClosureFeedbackCellArray> closure_feedback_cell_array =
|
||||
ClosureFeedbackCellArray::New(isolate(), shared);
|
||||
Handle<FeedbackVector> feedback_vector =
|
||||
FeedbackVector::New(isolate(), shared, closure_feedback_cell_array);
|
||||
vector_slot_pairs_.push_back(VectorSlotPair());
|
||||
|
@ -89,49 +89,50 @@ INSTANCE_TYPES = {
|
||||
188: "EMBEDDER_DATA_ARRAY_TYPE",
|
||||
189: "FIXED_ARRAY_TYPE",
|
||||
190: "OBJECT_BOILERPLATE_DESCRIPTION_TYPE",
|
||||
191: "HASH_TABLE_TYPE",
|
||||
192: "ORDERED_HASH_MAP_TYPE",
|
||||
193: "ORDERED_HASH_SET_TYPE",
|
||||
194: "ORDERED_NAME_DICTIONARY_TYPE",
|
||||
195: "NAME_DICTIONARY_TYPE",
|
||||
196: "GLOBAL_DICTIONARY_TYPE",
|
||||
197: "NUMBER_DICTIONARY_TYPE",
|
||||
198: "SIMPLE_NUMBER_DICTIONARY_TYPE",
|
||||
199: "STRING_TABLE_TYPE",
|
||||
200: "EPHEMERON_HASH_TABLE_TYPE",
|
||||
201: "SCOPE_INFO_TYPE",
|
||||
202: "SCRIPT_CONTEXT_TABLE_TYPE",
|
||||
203: "AWAIT_CONTEXT_TYPE",
|
||||
204: "BLOCK_CONTEXT_TYPE",
|
||||
205: "CATCH_CONTEXT_TYPE",
|
||||
206: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||
207: "EVAL_CONTEXT_TYPE",
|
||||
208: "FUNCTION_CONTEXT_TYPE",
|
||||
209: "MODULE_CONTEXT_TYPE",
|
||||
210: "NATIVE_CONTEXT_TYPE",
|
||||
211: "SCRIPT_CONTEXT_TYPE",
|
||||
212: "WITH_CONTEXT_TYPE",
|
||||
213: "WEAK_FIXED_ARRAY_TYPE",
|
||||
214: "TRANSITION_ARRAY_TYPE",
|
||||
215: "CALL_HANDLER_INFO_TYPE",
|
||||
216: "CELL_TYPE",
|
||||
217: "CODE_DATA_CONTAINER_TYPE",
|
||||
218: "DESCRIPTOR_ARRAY_TYPE",
|
||||
219: "FEEDBACK_CELL_TYPE",
|
||||
220: "FEEDBACK_VECTOR_TYPE",
|
||||
221: "LOAD_HANDLER_TYPE",
|
||||
222: "PREPARSE_DATA_TYPE",
|
||||
223: "PROPERTY_ARRAY_TYPE",
|
||||
224: "PROPERTY_CELL_TYPE",
|
||||
225: "SHARED_FUNCTION_INFO_TYPE",
|
||||
226: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
227: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
228: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||
229: "STORE_HANDLER_TYPE",
|
||||
230: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||
231: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||
232: "WEAK_ARRAY_LIST_TYPE",
|
||||
233: "WEAK_CELL_TYPE",
|
||||
191: "CLOSURE_FEEDBACK_CELL_ARRAY_TYPE",
|
||||
192: "HASH_TABLE_TYPE",
|
||||
193: "ORDERED_HASH_MAP_TYPE",
|
||||
194: "ORDERED_HASH_SET_TYPE",
|
||||
195: "ORDERED_NAME_DICTIONARY_TYPE",
|
||||
196: "NAME_DICTIONARY_TYPE",
|
||||
197: "GLOBAL_DICTIONARY_TYPE",
|
||||
198: "NUMBER_DICTIONARY_TYPE",
|
||||
199: "SIMPLE_NUMBER_DICTIONARY_TYPE",
|
||||
200: "STRING_TABLE_TYPE",
|
||||
201: "EPHEMERON_HASH_TABLE_TYPE",
|
||||
202: "SCOPE_INFO_TYPE",
|
||||
203: "SCRIPT_CONTEXT_TABLE_TYPE",
|
||||
204: "AWAIT_CONTEXT_TYPE",
|
||||
205: "BLOCK_CONTEXT_TYPE",
|
||||
206: "CATCH_CONTEXT_TYPE",
|
||||
207: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||
208: "EVAL_CONTEXT_TYPE",
|
||||
209: "FUNCTION_CONTEXT_TYPE",
|
||||
210: "MODULE_CONTEXT_TYPE",
|
||||
211: "NATIVE_CONTEXT_TYPE",
|
||||
212: "SCRIPT_CONTEXT_TYPE",
|
||||
213: "WITH_CONTEXT_TYPE",
|
||||
214: "WEAK_FIXED_ARRAY_TYPE",
|
||||
215: "TRANSITION_ARRAY_TYPE",
|
||||
216: "CALL_HANDLER_INFO_TYPE",
|
||||
217: "CELL_TYPE",
|
||||
218: "CODE_DATA_CONTAINER_TYPE",
|
||||
219: "DESCRIPTOR_ARRAY_TYPE",
|
||||
220: "FEEDBACK_CELL_TYPE",
|
||||
221: "FEEDBACK_VECTOR_TYPE",
|
||||
222: "LOAD_HANDLER_TYPE",
|
||||
223: "PREPARSE_DATA_TYPE",
|
||||
224: "PROPERTY_ARRAY_TYPE",
|
||||
225: "PROPERTY_CELL_TYPE",
|
||||
226: "SHARED_FUNCTION_INFO_TYPE",
|
||||
227: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
228: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
229: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||
230: "STORE_HANDLER_TYPE",
|
||||
231: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||
232: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||
233: "WEAK_ARRAY_LIST_TYPE",
|
||||
234: "WEAK_CELL_TYPE",
|
||||
1024: "JS_PROXY_TYPE",
|
||||
1025: "JS_GLOBAL_OBJECT_TYPE",
|
||||
1026: "JS_GLOBAL_PROXY_TYPE",
|
||||
@ -195,8 +196,8 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x00139): (138, "FreeSpaceMap"),
|
||||
("RO_SPACE", 0x00189): (132, "MetaMap"),
|
||||
("RO_SPACE", 0x00209): (131, "NullMap"),
|
||||
("RO_SPACE", 0x00271): (218, "DescriptorArrayMap"),
|
||||
("RO_SPACE", 0x002d1): (213, "WeakFixedArrayMap"),
|
||||
("RO_SPACE", 0x00271): (219, "DescriptorArrayMap"),
|
||||
("RO_SPACE", 0x002d1): (214, "WeakFixedArrayMap"),
|
||||
("RO_SPACE", 0x00321): (152, "OnePointerFillerMap"),
|
||||
("RO_SPACE", 0x00371): (152, "TwoPointerFillerMap"),
|
||||
("RO_SPACE", 0x003f1): (131, "UninitializedMap"),
|
||||
@ -209,140 +210,141 @@ KNOWN_MAPS = {
|
||||
("RO_SPACE", 0x007b1): (136, "ByteArrayMap"),
|
||||
("RO_SPACE", 0x00801): (189, "FixedArrayMap"),
|
||||
("RO_SPACE", 0x00851): (189, "FixedCOWArrayMap"),
|
||||
("RO_SPACE", 0x008a1): (191, "HashTableMap"),
|
||||
("RO_SPACE", 0x008a1): (192, "HashTableMap"),
|
||||
("RO_SPACE", 0x008f1): (128, "SymbolMap"),
|
||||
("RO_SPACE", 0x00941): (40, "OneByteStringMap"),
|
||||
("RO_SPACE", 0x00991): (201, "ScopeInfoMap"),
|
||||
("RO_SPACE", 0x009e1): (225, "SharedFunctionInfoMap"),
|
||||
("RO_SPACE", 0x00991): (202, "ScopeInfoMap"),
|
||||
("RO_SPACE", 0x009e1): (226, "SharedFunctionInfoMap"),
|
||||
("RO_SPACE", 0x00a31): (133, "CodeMap"),
|
||||
("RO_SPACE", 0x00a81): (208, "FunctionContextMap"),
|
||||
("RO_SPACE", 0x00ad1): (216, "CellMap"),
|
||||
("RO_SPACE", 0x00b21): (224, "GlobalPropertyCellMap"),
|
||||
("RO_SPACE", 0x00a81): (209, "FunctionContextMap"),
|
||||
("RO_SPACE", 0x00ad1): (217, "CellMap"),
|
||||
("RO_SPACE", 0x00b21): (225, "GlobalPropertyCellMap"),
|
||||
("RO_SPACE", 0x00b71): (135, "ForeignMap"),
|
||||
("RO_SPACE", 0x00bc1): (214, "TransitionArrayMap"),
|
||||
("RO_SPACE", 0x00c11): (220, "FeedbackVectorMap"),
|
||||
("RO_SPACE", 0x00bc1): (215, "TransitionArrayMap"),
|
||||
("RO_SPACE", 0x00c11): (221, "FeedbackVectorMap"),
|
||||
("RO_SPACE", 0x00cb1): (131, "ArgumentsMarkerMap"),
|
||||
("RO_SPACE", 0x00d51): (131, "ExceptionMap"),
|
||||
("RO_SPACE", 0x00df1): (131, "TerminationExceptionMap"),
|
||||
("RO_SPACE", 0x00e99): (131, "OptimizedOutMap"),
|
||||
("RO_SPACE", 0x00f39): (131, "StaleRegisterMap"),
|
||||
("RO_SPACE", 0x00fa9): (210, "NativeContextMap"),
|
||||
("RO_SPACE", 0x00ff9): (209, "ModuleContextMap"),
|
||||
("RO_SPACE", 0x01049): (207, "EvalContextMap"),
|
||||
("RO_SPACE", 0x01099): (211, "ScriptContextMap"),
|
||||
("RO_SPACE", 0x010e9): (203, "AwaitContextMap"),
|
||||
("RO_SPACE", 0x01139): (204, "BlockContextMap"),
|
||||
("RO_SPACE", 0x01189): (205, "CatchContextMap"),
|
||||
("RO_SPACE", 0x011d9): (212, "WithContextMap"),
|
||||
("RO_SPACE", 0x01229): (206, "DebugEvaluateContextMap"),
|
||||
("RO_SPACE", 0x01279): (202, "ScriptContextTableMap"),
|
||||
("RO_SPACE", 0x012c9): (151, "FeedbackMetadataArrayMap"),
|
||||
("RO_SPACE", 0x01319): (189, "ArrayListMap"),
|
||||
("RO_SPACE", 0x01369): (130, "BigIntMap"),
|
||||
("RO_SPACE", 0x013b9): (190, "ObjectBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x01409): (137, "BytecodeArrayMap"),
|
||||
("RO_SPACE", 0x01459): (217, "CodeDataContainerMap"),
|
||||
("RO_SPACE", 0x014a9): (150, "FixedDoubleArrayMap"),
|
||||
("RO_SPACE", 0x014f9): (196, "GlobalDictionaryMap"),
|
||||
("RO_SPACE", 0x01549): (219, "ManyClosuresCellMap"),
|
||||
("RO_SPACE", 0x01599): (189, "ModuleInfoMap"),
|
||||
("RO_SPACE", 0x015e9): (134, "MutableHeapNumberMap"),
|
||||
("RO_SPACE", 0x01639): (195, "NameDictionaryMap"),
|
||||
("RO_SPACE", 0x01689): (219, "NoClosuresCellMap"),
|
||||
("RO_SPACE", 0x016d9): (197, "NumberDictionaryMap"),
|
||||
("RO_SPACE", 0x01729): (219, "OneClosureCellMap"),
|
||||
("RO_SPACE", 0x01779): (192, "OrderedHashMapMap"),
|
||||
("RO_SPACE", 0x017c9): (193, "OrderedHashSetMap"),
|
||||
("RO_SPACE", 0x01819): (194, "OrderedNameDictionaryMap"),
|
||||
("RO_SPACE", 0x01869): (222, "PreparseDataMap"),
|
||||
("RO_SPACE", 0x018b9): (223, "PropertyArrayMap"),
|
||||
("RO_SPACE", 0x01909): (215, "SideEffectCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x01959): (215, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x019a9): (215, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x019f9): (198, "SimpleNumberDictionaryMap"),
|
||||
("RO_SPACE", 0x01a49): (189, "SloppyArgumentsElementsMap"),
|
||||
("RO_SPACE", 0x01a99): (226, "SmallOrderedHashMapMap"),
|
||||
("RO_SPACE", 0x01ae9): (227, "SmallOrderedHashSetMap"),
|
||||
("RO_SPACE", 0x01b39): (228, "SmallOrderedNameDictionaryMap"),
|
||||
("RO_SPACE", 0x01b89): (199, "StringTableMap"),
|
||||
("RO_SPACE", 0x01bd9): (230, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("RO_SPACE", 0x01c29): (231, "UncompiledDataWithPreparseDataMap"),
|
||||
("RO_SPACE", 0x01c79): (232, "WeakArrayListMap"),
|
||||
("RO_SPACE", 0x01cc9): (200, "EphemeronHashTableMap"),
|
||||
("RO_SPACE", 0x01d19): (188, "EmbedderDataArrayMap"),
|
||||
("RO_SPACE", 0x01d69): (233, "WeakCellMap"),
|
||||
("RO_SPACE", 0x01db9): (58, "NativeSourceStringMap"),
|
||||
("RO_SPACE", 0x01e09): (32, "StringMap"),
|
||||
("RO_SPACE", 0x01e59): (41, "ConsOneByteStringMap"),
|
||||
("RO_SPACE", 0x01ea9): (33, "ConsStringMap"),
|
||||
("RO_SPACE", 0x01ef9): (45, "ThinOneByteStringMap"),
|
||||
("RO_SPACE", 0x01f49): (37, "ThinStringMap"),
|
||||
("RO_SPACE", 0x01f99): (35, "SlicedStringMap"),
|
||||
("RO_SPACE", 0x01fe9): (43, "SlicedOneByteStringMap"),
|
||||
("RO_SPACE", 0x02039): (34, "ExternalStringMap"),
|
||||
("RO_SPACE", 0x02089): (42, "ExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x020d9): (50, "UncachedExternalStringMap"),
|
||||
("RO_SPACE", 0x02129): (0, "InternalizedStringMap"),
|
||||
("RO_SPACE", 0x02179): (2, "ExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x021c9): (10, "ExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x02219): (18, "UncachedExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x02269): (26, "UncachedExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x022b9): (58, "UncachedExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x02309): (140, "FixedUint8ArrayMap"),
|
||||
("RO_SPACE", 0x02359): (139, "FixedInt8ArrayMap"),
|
||||
("RO_SPACE", 0x023a9): (142, "FixedUint16ArrayMap"),
|
||||
("RO_SPACE", 0x023f9): (141, "FixedInt16ArrayMap"),
|
||||
("RO_SPACE", 0x02449): (144, "FixedUint32ArrayMap"),
|
||||
("RO_SPACE", 0x02499): (143, "FixedInt32ArrayMap"),
|
||||
("RO_SPACE", 0x024e9): (145, "FixedFloat32ArrayMap"),
|
||||
("RO_SPACE", 0x02539): (146, "FixedFloat64ArrayMap"),
|
||||
("RO_SPACE", 0x02589): (147, "FixedUint8ClampedArrayMap"),
|
||||
("RO_SPACE", 0x025d9): (149, "FixedBigUint64ArrayMap"),
|
||||
("RO_SPACE", 0x02629): (148, "FixedBigInt64ArrayMap"),
|
||||
("RO_SPACE", 0x02679): (131, "SelfReferenceMarkerMap"),
|
||||
("RO_SPACE", 0x026e1): (175, "Tuple2Map"),
|
||||
("RO_SPACE", 0x02781): (177, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x02ac1): (164, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x050a9): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x050f9): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x05149): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x05199): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x051e9): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x05239): (158, "AsmWasmDataMap"),
|
||||
("RO_SPACE", 0x05289): (159, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x052d9): (160, "ClassPositionsMap"),
|
||||
("RO_SPACE", 0x05329): (161, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x05379): (162, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x053c9): (163, "FunctionTemplateRareDataMap"),
|
||||
("RO_SPACE", 0x05419): (165, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x05469): (166, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x054b9): (167, "ModuleMap"),
|
||||
("RO_SPACE", 0x05509): (168, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x05559): (169, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x055a9): (170, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x055f9): (171, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x05649): (172, "ScriptMap"),
|
||||
("RO_SPACE", 0x05699): (173, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x056e9): (174, "StackTraceFrameMap"),
|
||||
("RO_SPACE", 0x05739): (176, "Tuple3Map"),
|
||||
("RO_SPACE", 0x05789): (178, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x057d9): (179, "WasmExceptionTagMap"),
|
||||
("RO_SPACE", 0x05829): (180, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x05879): (181, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x058c9): (182, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x05919): (183, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x05969): (184, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x059b9): (185, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x05a09): (186, "FinalizationGroupCleanupJobTaskMap"),
|
||||
("RO_SPACE", 0x05a59): (187, "AllocationSiteWithWeakNextMap"),
|
||||
("RO_SPACE", 0x05aa9): (187, "AllocationSiteWithoutWeakNextMap"),
|
||||
("RO_SPACE", 0x05af9): (221, "LoadHandler1Map"),
|
||||
("RO_SPACE", 0x05b49): (221, "LoadHandler2Map"),
|
||||
("RO_SPACE", 0x05b99): (221, "LoadHandler3Map"),
|
||||
("RO_SPACE", 0x05be9): (229, "StoreHandler0Map"),
|
||||
("RO_SPACE", 0x05c39): (229, "StoreHandler1Map"),
|
||||
("RO_SPACE", 0x05c89): (229, "StoreHandler2Map"),
|
||||
("RO_SPACE", 0x05cd9): (229, "StoreHandler3Map"),
|
||||
("RO_SPACE", 0x00fa9): (211, "NativeContextMap"),
|
||||
("RO_SPACE", 0x00ff9): (210, "ModuleContextMap"),
|
||||
("RO_SPACE", 0x01049): (208, "EvalContextMap"),
|
||||
("RO_SPACE", 0x01099): (212, "ScriptContextMap"),
|
||||
("RO_SPACE", 0x010e9): (204, "AwaitContextMap"),
|
||||
("RO_SPACE", 0x01139): (205, "BlockContextMap"),
|
||||
("RO_SPACE", 0x01189): (206, "CatchContextMap"),
|
||||
("RO_SPACE", 0x011d9): (213, "WithContextMap"),
|
||||
("RO_SPACE", 0x01229): (207, "DebugEvaluateContextMap"),
|
||||
("RO_SPACE", 0x01279): (203, "ScriptContextTableMap"),
|
||||
("RO_SPACE", 0x012c9): (191, "ClosureFeedbackCellArrayMap"),
|
||||
("RO_SPACE", 0x01319): (151, "FeedbackMetadataArrayMap"),
|
||||
("RO_SPACE", 0x01369): (189, "ArrayListMap"),
|
||||
("RO_SPACE", 0x013b9): (130, "BigIntMap"),
|
||||
("RO_SPACE", 0x01409): (190, "ObjectBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x01459): (137, "BytecodeArrayMap"),
|
||||
("RO_SPACE", 0x014a9): (218, "CodeDataContainerMap"),
|
||||
("RO_SPACE", 0x014f9): (150, "FixedDoubleArrayMap"),
|
||||
("RO_SPACE", 0x01549): (197, "GlobalDictionaryMap"),
|
||||
("RO_SPACE", 0x01599): (220, "ManyClosuresCellMap"),
|
||||
("RO_SPACE", 0x015e9): (189, "ModuleInfoMap"),
|
||||
("RO_SPACE", 0x01639): (134, "MutableHeapNumberMap"),
|
||||
("RO_SPACE", 0x01689): (196, "NameDictionaryMap"),
|
||||
("RO_SPACE", 0x016d9): (220, "NoClosuresCellMap"),
|
||||
("RO_SPACE", 0x01729): (198, "NumberDictionaryMap"),
|
||||
("RO_SPACE", 0x01779): (220, "OneClosureCellMap"),
|
||||
("RO_SPACE", 0x017c9): (193, "OrderedHashMapMap"),
|
||||
("RO_SPACE", 0x01819): (194, "OrderedHashSetMap"),
|
||||
("RO_SPACE", 0x01869): (195, "OrderedNameDictionaryMap"),
|
||||
("RO_SPACE", 0x018b9): (223, "PreparseDataMap"),
|
||||
("RO_SPACE", 0x01909): (224, "PropertyArrayMap"),
|
||||
("RO_SPACE", 0x01959): (216, "SideEffectCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x019a9): (216, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x019f9): (216, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("RO_SPACE", 0x01a49): (199, "SimpleNumberDictionaryMap"),
|
||||
("RO_SPACE", 0x01a99): (189, "SloppyArgumentsElementsMap"),
|
||||
("RO_SPACE", 0x01ae9): (227, "SmallOrderedHashMapMap"),
|
||||
("RO_SPACE", 0x01b39): (228, "SmallOrderedHashSetMap"),
|
||||
("RO_SPACE", 0x01b89): (229, "SmallOrderedNameDictionaryMap"),
|
||||
("RO_SPACE", 0x01bd9): (200, "StringTableMap"),
|
||||
("RO_SPACE", 0x01c29): (231, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("RO_SPACE", 0x01c79): (232, "UncompiledDataWithPreparseDataMap"),
|
||||
("RO_SPACE", 0x01cc9): (233, "WeakArrayListMap"),
|
||||
("RO_SPACE", 0x01d19): (201, "EphemeronHashTableMap"),
|
||||
("RO_SPACE", 0x01d69): (188, "EmbedderDataArrayMap"),
|
||||
("RO_SPACE", 0x01db9): (234, "WeakCellMap"),
|
||||
("RO_SPACE", 0x01e09): (58, "NativeSourceStringMap"),
|
||||
("RO_SPACE", 0x01e59): (32, "StringMap"),
|
||||
("RO_SPACE", 0x01ea9): (41, "ConsOneByteStringMap"),
|
||||
("RO_SPACE", 0x01ef9): (33, "ConsStringMap"),
|
||||
("RO_SPACE", 0x01f49): (45, "ThinOneByteStringMap"),
|
||||
("RO_SPACE", 0x01f99): (37, "ThinStringMap"),
|
||||
("RO_SPACE", 0x01fe9): (35, "SlicedStringMap"),
|
||||
("RO_SPACE", 0x02039): (43, "SlicedOneByteStringMap"),
|
||||
("RO_SPACE", 0x02089): (34, "ExternalStringMap"),
|
||||
("RO_SPACE", 0x020d9): (42, "ExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x02129): (50, "UncachedExternalStringMap"),
|
||||
("RO_SPACE", 0x02179): (0, "InternalizedStringMap"),
|
||||
("RO_SPACE", 0x021c9): (2, "ExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x02219): (10, "ExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x02269): (18, "UncachedExternalInternalizedStringMap"),
|
||||
("RO_SPACE", 0x022b9): (26, "UncachedExternalOneByteInternalizedStringMap"),
|
||||
("RO_SPACE", 0x02309): (58, "UncachedExternalOneByteStringMap"),
|
||||
("RO_SPACE", 0x02359): (140, "FixedUint8ArrayMap"),
|
||||
("RO_SPACE", 0x023a9): (139, "FixedInt8ArrayMap"),
|
||||
("RO_SPACE", 0x023f9): (142, "FixedUint16ArrayMap"),
|
||||
("RO_SPACE", 0x02449): (141, "FixedInt16ArrayMap"),
|
||||
("RO_SPACE", 0x02499): (144, "FixedUint32ArrayMap"),
|
||||
("RO_SPACE", 0x024e9): (143, "FixedInt32ArrayMap"),
|
||||
("RO_SPACE", 0x02539): (145, "FixedFloat32ArrayMap"),
|
||||
("RO_SPACE", 0x02589): (146, "FixedFloat64ArrayMap"),
|
||||
("RO_SPACE", 0x025d9): (147, "FixedUint8ClampedArrayMap"),
|
||||
("RO_SPACE", 0x02629): (149, "FixedBigUint64ArrayMap"),
|
||||
("RO_SPACE", 0x02679): (148, "FixedBigInt64ArrayMap"),
|
||||
("RO_SPACE", 0x026c9): (131, "SelfReferenceMarkerMap"),
|
||||
("RO_SPACE", 0x02731): (175, "Tuple2Map"),
|
||||
("RO_SPACE", 0x027d1): (177, "ArrayBoilerplateDescriptionMap"),
|
||||
("RO_SPACE", 0x02b11): (164, "InterceptorInfoMap"),
|
||||
("RO_SPACE", 0x050f9): (153, "AccessCheckInfoMap"),
|
||||
("RO_SPACE", 0x05149): (154, "AccessorInfoMap"),
|
||||
("RO_SPACE", 0x05199): (155, "AccessorPairMap"),
|
||||
("RO_SPACE", 0x051e9): (156, "AliasedArgumentsEntryMap"),
|
||||
("RO_SPACE", 0x05239): (157, "AllocationMementoMap"),
|
||||
("RO_SPACE", 0x05289): (158, "AsmWasmDataMap"),
|
||||
("RO_SPACE", 0x052d9): (159, "AsyncGeneratorRequestMap"),
|
||||
("RO_SPACE", 0x05329): (160, "ClassPositionsMap"),
|
||||
("RO_SPACE", 0x05379): (161, "DebugInfoMap"),
|
||||
("RO_SPACE", 0x053c9): (162, "FunctionTemplateInfoMap"),
|
||||
("RO_SPACE", 0x05419): (163, "FunctionTemplateRareDataMap"),
|
||||
("RO_SPACE", 0x05469): (165, "InterpreterDataMap"),
|
||||
("RO_SPACE", 0x054b9): (166, "ModuleInfoEntryMap"),
|
||||
("RO_SPACE", 0x05509): (167, "ModuleMap"),
|
||||
("RO_SPACE", 0x05559): (168, "ObjectTemplateInfoMap"),
|
||||
("RO_SPACE", 0x055a9): (169, "PromiseCapabilityMap"),
|
||||
("RO_SPACE", 0x055f9): (170, "PromiseReactionMap"),
|
||||
("RO_SPACE", 0x05649): (171, "PrototypeInfoMap"),
|
||||
("RO_SPACE", 0x05699): (172, "ScriptMap"),
|
||||
("RO_SPACE", 0x056e9): (173, "StackFrameInfoMap"),
|
||||
("RO_SPACE", 0x05739): (174, "StackTraceFrameMap"),
|
||||
("RO_SPACE", 0x05789): (176, "Tuple3Map"),
|
||||
("RO_SPACE", 0x057d9): (178, "WasmDebugInfoMap"),
|
||||
("RO_SPACE", 0x05829): (179, "WasmExceptionTagMap"),
|
||||
("RO_SPACE", 0x05879): (180, "WasmExportedFunctionDataMap"),
|
||||
("RO_SPACE", 0x058c9): (181, "CallableTaskMap"),
|
||||
("RO_SPACE", 0x05919): (182, "CallbackTaskMap"),
|
||||
("RO_SPACE", 0x05969): (183, "PromiseFulfillReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x059b9): (184, "PromiseRejectReactionJobTaskMap"),
|
||||
("RO_SPACE", 0x05a09): (185, "PromiseResolveThenableJobTaskMap"),
|
||||
("RO_SPACE", 0x05a59): (186, "FinalizationGroupCleanupJobTaskMap"),
|
||||
("RO_SPACE", 0x05aa9): (187, "AllocationSiteWithWeakNextMap"),
|
||||
("RO_SPACE", 0x05af9): (187, "AllocationSiteWithoutWeakNextMap"),
|
||||
("RO_SPACE", 0x05b49): (222, "LoadHandler1Map"),
|
||||
("RO_SPACE", 0x05b99): (222, "LoadHandler2Map"),
|
||||
("RO_SPACE", 0x05be9): (222, "LoadHandler3Map"),
|
||||
("RO_SPACE", 0x05c39): (230, "StoreHandler0Map"),
|
||||
("RO_SPACE", 0x05c89): (230, "StoreHandler1Map"),
|
||||
("RO_SPACE", 0x05cd9): (230, "StoreHandler2Map"),
|
||||
("RO_SPACE", 0x05d29): (230, "StoreHandler3Map"),
|
||||
("MAP_SPACE", 0x00139): (1057, "ExternalMap"),
|
||||
("MAP_SPACE", 0x00189): (1073, "JSMessageObjectMap"),
|
||||
}
|
||||
@ -367,37 +369,37 @@ KNOWN_OBJECTS = {
|
||||
("RO_SPACE", 0x00dc1): "TerminationException",
|
||||
("RO_SPACE", 0x00e69): "OptimizedOut",
|
||||
("RO_SPACE", 0x00f09): "StaleRegister",
|
||||
("RO_SPACE", 0x026c9): "EmptyEnumCache",
|
||||
("RO_SPACE", 0x02731): "EmptyPropertyArray",
|
||||
("RO_SPACE", 0x02741): "EmptyByteArray",
|
||||
("RO_SPACE", 0x02751): "EmptyObjectBoilerplateDescription",
|
||||
("RO_SPACE", 0x02769): "EmptyArrayBoilerplateDescription",
|
||||
("RO_SPACE", 0x027d1): "EmptyFixedUint8Array",
|
||||
("RO_SPACE", 0x027f1): "EmptyFixedInt8Array",
|
||||
("RO_SPACE", 0x02811): "EmptyFixedUint16Array",
|
||||
("RO_SPACE", 0x02831): "EmptyFixedInt16Array",
|
||||
("RO_SPACE", 0x02851): "EmptyFixedUint32Array",
|
||||
("RO_SPACE", 0x02871): "EmptyFixedInt32Array",
|
||||
("RO_SPACE", 0x02891): "EmptyFixedFloat32Array",
|
||||
("RO_SPACE", 0x028b1): "EmptyFixedFloat64Array",
|
||||
("RO_SPACE", 0x028d1): "EmptyFixedUint8ClampedArray",
|
||||
("RO_SPACE", 0x028f1): "EmptyFixedBigUint64Array",
|
||||
("RO_SPACE", 0x02911): "EmptyFixedBigInt64Array",
|
||||
("RO_SPACE", 0x02931): "EmptySloppyArgumentsElements",
|
||||
("RO_SPACE", 0x02951): "EmptySlowElementDictionary",
|
||||
("RO_SPACE", 0x02999): "EmptyOrderedHashMap",
|
||||
("RO_SPACE", 0x029c1): "EmptyOrderedHashSet",
|
||||
("RO_SPACE", 0x029e9): "EmptyFeedbackMetadata",
|
||||
("RO_SPACE", 0x029f9): "EmptyPropertyCell",
|
||||
("RO_SPACE", 0x02a21): "EmptyPropertyDictionary",
|
||||
("RO_SPACE", 0x02a71): "NoOpInterceptorInfo",
|
||||
("RO_SPACE", 0x02b11): "EmptyWeakArrayList",
|
||||
("RO_SPACE", 0x02b29): "InfinityValue",
|
||||
("RO_SPACE", 0x02b39): "MinusZeroValue",
|
||||
("RO_SPACE", 0x02b49): "MinusInfinityValue",
|
||||
("RO_SPACE", 0x02b59): "SelfReferenceMarker",
|
||||
("RO_SPACE", 0x02bb1): "OffHeapTrampolineRelocationInfo",
|
||||
("RO_SPACE", 0x02bc9): "HashSeed",
|
||||
("RO_SPACE", 0x02719): "EmptyEnumCache",
|
||||
("RO_SPACE", 0x02781): "EmptyPropertyArray",
|
||||
("RO_SPACE", 0x02791): "EmptyByteArray",
|
||||
("RO_SPACE", 0x027a1): "EmptyObjectBoilerplateDescription",
|
||||
("RO_SPACE", 0x027b9): "EmptyArrayBoilerplateDescription",
|
||||
("RO_SPACE", 0x02821): "EmptyFixedUint8Array",
|
||||
("RO_SPACE", 0x02841): "EmptyFixedInt8Array",
|
||||
("RO_SPACE", 0x02861): "EmptyFixedUint16Array",
|
||||
("RO_SPACE", 0x02881): "EmptyFixedInt16Array",
|
||||
("RO_SPACE", 0x028a1): "EmptyFixedUint32Array",
|
||||
("RO_SPACE", 0x028c1): "EmptyFixedInt32Array",
|
||||
("RO_SPACE", 0x028e1): "EmptyFixedFloat32Array",
|
||||
("RO_SPACE", 0x02901): "EmptyFixedFloat64Array",
|
||||
("RO_SPACE", 0x02921): "EmptyFixedUint8ClampedArray",
|
||||
("RO_SPACE", 0x02941): "EmptyFixedBigUint64Array",
|
||||
("RO_SPACE", 0x02961): "EmptyFixedBigInt64Array",
|
||||
("RO_SPACE", 0x02981): "EmptySloppyArgumentsElements",
|
||||
("RO_SPACE", 0x029a1): "EmptySlowElementDictionary",
|
||||
("RO_SPACE", 0x029e9): "EmptyOrderedHashMap",
|
||||
("RO_SPACE", 0x02a11): "EmptyOrderedHashSet",
|
||||
("RO_SPACE", 0x02a39): "EmptyFeedbackMetadata",
|
||||
("RO_SPACE", 0x02a49): "EmptyPropertyCell",
|
||||
("RO_SPACE", 0x02a71): "EmptyPropertyDictionary",
|
||||
("RO_SPACE", 0x02ac1): "NoOpInterceptorInfo",
|
||||
("RO_SPACE", 0x02b61): "EmptyWeakArrayList",
|
||||
("RO_SPACE", 0x02b79): "InfinityValue",
|
||||
("RO_SPACE", 0x02b89): "MinusZeroValue",
|
||||
("RO_SPACE", 0x02b99): "MinusInfinityValue",
|
||||
("RO_SPACE", 0x02ba9): "SelfReferenceMarker",
|
||||
("RO_SPACE", 0x02c01): "OffHeapTrampolineRelocationInfo",
|
||||
("RO_SPACE", 0x02c19): "HashSeed",
|
||||
("OLD_SPACE", 0x00139): "ArgumentsIteratorAccessor",
|
||||
("OLD_SPACE", 0x001a9): "ArrayLengthAccessor",
|
||||
("OLD_SPACE", 0x00219): "BoundFunctionLengthAccessor",
|
||||
|
Loading…
Reference in New Issue
Block a user