interpreter: make interpreted frames distinguishable in the native stack
Before Turbofan/Ignition it was possible to use external profilers to sample running V8/Node.js processes and generate reports/FlameGraphs from that. It's still possible to do so, but non-optimized JavaScript functions appear in the stack as InterpreterEntryTrampoline. This commit adds a runtime flag which makes interpreted frames visible on the process' native stack as distinguishable functions, making the sampled data gathered by external profilers such as Linux perf and DTrace more useful. R=bmeurer@google.com, franzih@google.com, jarin@google.com, yangguo@google.com Bug: v8:7155 Change-Id: I3dc8876aa3cd9f1b9766624842a7cc354ccca415 Reviewed-on: https://chromium-review.googlesource.com/959081 Commit-Queue: Yang Guo <yangguo@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#52533}
This commit is contained in:
parent
4b0644f501
commit
ada64b58bf
1
AUTHORS
1
AUTHORS
@ -98,6 +98,7 @@ Maciej Małecki <me@mmalecki.com>
|
||||
Marcin Cieślak <saper@marcincieslak.com>
|
||||
Marcin Wiącek <marcin@mwiacek.com>
|
||||
Mateusz Czeladka <mateusz.szczap@gmail.com>
|
||||
Matheus Marchini <matheus@sthima.com.br>
|
||||
Mathias Bynens <mathias@qiwi.be>
|
||||
Matt Hanselman <mjhanselman@gmail.com>
|
||||
Matthew Sporleder <msporleder@gmail.com>
|
||||
|
@ -445,6 +445,19 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
|
||||
static void GetSharedFunctionInfoBytecode(MacroAssembler* masm,
|
||||
Register sfi_data,
|
||||
Register scratch1) {
|
||||
Label done;
|
||||
|
||||
__ CompareObjectType(sfi_data, scratch1, scratch1, INTERPRETER_DATA_TYPE);
|
||||
__ b(ne, &done);
|
||||
__ ldr(sfi_data,
|
||||
FieldMemOperand(sfi_data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -524,6 +537,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
if (FLAG_debug_code) {
|
||||
__ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, r3, r0);
|
||||
__ CompareObjectType(r3, r3, r3, BYTECODE_ARRAY_TYPE);
|
||||
__ Assert(eq, AbortReason::kMissingBytecodeArray);
|
||||
}
|
||||
@ -915,6 +929,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ ldr(r0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(kInterpreterBytecodeArrayRegister,
|
||||
FieldMemOperand(r0, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, r4);
|
||||
__ ldr(r4, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset));
|
||||
__ SmiTst(r4);
|
||||
__ b(ne, &maybe_load_debug_bytecode_array);
|
||||
@ -1185,10 +1200,29 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
// Set the return address to the correct point in the interpreter entry
|
||||
// trampoline.
|
||||
Label builtin_trampoline, trampoline_loaded;
|
||||
Smi* interpreter_entry_return_pc_offset(
|
||||
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
|
||||
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
|
||||
|
||||
// If the SFI function_data is an InterpreterData, get the trampoline stored
|
||||
// in it, otherwise get the trampoline from the builtins list.
|
||||
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ ldr(r2, FieldMemOperand(r2, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ CompareObjectType(r2, kInterpreterDispatchTableRegister,
|
||||
kInterpreterDispatchTableRegister,
|
||||
INTERPRETER_DATA_TYPE);
|
||||
__ b(ne, &builtin_trampoline);
|
||||
|
||||
__ ldr(r2,
|
||||
FieldMemOperand(r2, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ b(&trampoline_loaded);
|
||||
|
||||
__ bind(&builtin_trampoline);
|
||||
__ Move(r2, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline));
|
||||
|
||||
__ bind(&trampoline_loaded);
|
||||
__ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() +
|
||||
Code::kHeaderSize - kHeapObjectTag));
|
||||
|
||||
@ -1280,6 +1314,7 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
Label check_is_fixed_array;
|
||||
Label check_is_pre_parsed_scope_data;
|
||||
Label check_is_function_template_info;
|
||||
Label check_is_interpreter_data;
|
||||
|
||||
Register data_type = scratch1;
|
||||
|
||||
@ -1322,11 +1357,20 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
__ bind(&check_is_function_template_info);
|
||||
__ cmp(data_type, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ b(ne, &check_is_interpreter_data);
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ b(&done);
|
||||
|
||||
// IsInterpreterData: Interpret bytecode
|
||||
__ bind(&check_is_interpreter_data);
|
||||
if (FLAG_debug_code) {
|
||||
__ cmp(data_type, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ cmp(data_type, Operand(INTERPRETER_DATA_TYPE));
|
||||
__ Assert(eq, AbortReason::kInvalidSharedFunctionInfoData);
|
||||
}
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ ldr(
|
||||
sfi_data,
|
||||
FieldMemOperand(sfi_data, InterpreterData::kInterpreterTrampolineOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
@ -581,8 +581,13 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
|
||||
// Underlying function needs to have bytecode available.
|
||||
if (FLAG_debug_code) {
|
||||
Label check_has_bytecode_array;
|
||||
__ Ldr(x3, FieldMemOperand(x4, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldr(x3, FieldMemOperand(x3, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ CompareObjectType(x3, x0, x0, INTERPRETER_DATA_TYPE);
|
||||
__ B(ne, &check_has_bytecode_array);
|
||||
__ Ldr(x3, FieldMemOperand(x3, InterpreterData::kBytecodeArrayOffset));
|
||||
__ Bind(&check_has_bytecode_array);
|
||||
__ CompareObjectType(x3, x3, x3, BYTECODE_ARRAY_TYPE);
|
||||
__ Assert(eq, AbortReason::kMissingBytecodeArray);
|
||||
}
|
||||
@ -1004,10 +1009,18 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
|
||||
// Get the bytecode array from the function object (or from the DebugInfo if
|
||||
// it is present) and load it into kInterpreterBytecodeArrayRegister.
|
||||
Label maybe_load_debug_bytecode_array, bytecode_array_loaded;
|
||||
Label maybe_load_debug_bytecode_array, bytecode_array_loaded,
|
||||
has_bytecode_array;
|
||||
__ Ldr(x0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldr(kInterpreterBytecodeArrayRegister,
|
||||
FieldMemOperand(x0, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ CompareObjectType(kInterpreterBytecodeArrayRegister, x11, x11,
|
||||
INTERPRETER_DATA_TYPE);
|
||||
__ B(ne, &has_bytecode_array);
|
||||
__ Ldr(kInterpreterBytecodeArrayRegister,
|
||||
FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
||||
InterpreterData::kBytecodeArrayOffset));
|
||||
__ Bind(&has_bytecode_array);
|
||||
__ Ldr(x11, FieldMemOperand(x0, SharedFunctionInfo::kDebugInfoOffset));
|
||||
__ JumpIfNotSmi(x11, &maybe_load_debug_bytecode_array);
|
||||
__ Bind(&bytecode_array_loaded);
|
||||
@ -1301,10 +1314,29 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
// Set the return address to the correct point in the interpreter entry
|
||||
// trampoline.
|
||||
Label builtin_trampoline, trampoline_loaded;
|
||||
Smi* interpreter_entry_return_pc_offset(
|
||||
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
|
||||
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
|
||||
|
||||
// If the SFI function_data is an InterpreterData, get the trampoline stored
|
||||
// in it, otherwise get the trampoline from the builtins list.
|
||||
__ Ldr(x1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ Ldr(x1, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldr(x1, FieldMemOperand(x1, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ CompareObjectType(x1, kInterpreterDispatchTableRegister,
|
||||
kInterpreterDispatchTableRegister,
|
||||
INTERPRETER_DATA_TYPE);
|
||||
__ B(ne, &builtin_trampoline);
|
||||
|
||||
__ Ldr(x1,
|
||||
FieldMemOperand(x1, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ B(&trampoline_loaded);
|
||||
|
||||
__ Bind(&builtin_trampoline);
|
||||
__ LoadObject(x1, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline));
|
||||
|
||||
__ Bind(&trampoline_loaded);
|
||||
__ Add(lr, x1, Operand(interpreter_entry_return_pc_offset->value() +
|
||||
Code::kHeaderSize - kHeapObjectTag));
|
||||
|
||||
@ -1394,6 +1426,7 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
Label check_is_fixed_array;
|
||||
Label check_is_pre_parsed_scope_data;
|
||||
Label check_is_function_template_info;
|
||||
Label check_is_interpreter_data;
|
||||
|
||||
Register data_type = scratch1;
|
||||
|
||||
@ -1436,11 +1469,20 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
__ Bind(&check_is_function_template_info);
|
||||
__ Cmp(data_type, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ B(ne, &check_is_interpreter_data);
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ B(&done);
|
||||
|
||||
// IsInterpreterData: Interpret bytecode
|
||||
__ Bind(&check_is_interpreter_data);
|
||||
if (FLAG_debug_code) {
|
||||
__ Cmp(data_type, Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ Cmp(data_type, Operand(INTERPRETER_DATA_TYPE));
|
||||
__ Assert(eq, AbortReason::kInvalidSharedFunctionInfoData);
|
||||
}
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ Ldr(
|
||||
sfi_data,
|
||||
FieldMemOperand(sfi_data, InterpreterData::kInterpreterTrampolineOffset));
|
||||
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
@ -1075,8 +1075,8 @@ TF_BUILTIN(CreateGeneratorObject, ObjectBuiltinsAssembler) {
|
||||
|
||||
Node* shared =
|
||||
LoadObjectField(closure, JSFunction::kSharedFunctionInfoOffset);
|
||||
Node* bytecode_array =
|
||||
LoadObjectField(shared, SharedFunctionInfo::kFunctionDataOffset);
|
||||
Node* bytecode_array = LoadSharedFunctionInfoBytecodeArray(shared);
|
||||
|
||||
Node* frame_size = ChangeInt32ToIntPtr(LoadObjectField(
|
||||
bytecode_array, BytecodeArray::kFrameSizeOffset, MachineType::Int32()));
|
||||
Node* size = WordSar(frame_size, IntPtrConstant(kPointerSizeLog2));
|
||||
|
@ -494,6 +494,19 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
|
||||
Generate_JSEntryTrampolineHelper(masm, true);
|
||||
}
|
||||
|
||||
static void GetSharedFunctionInfoBytecode(MacroAssembler* masm,
|
||||
Register sfi_data,
|
||||
Register scratch1) {
|
||||
Label done;
|
||||
|
||||
__ CmpObjectType(sfi_data, INTERPRETER_DATA_TYPE, scratch1);
|
||||
__ j(not_equal, &done, Label::kNear);
|
||||
__ mov(sfi_data,
|
||||
FieldOperand(sfi_data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -568,6 +581,9 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
if (FLAG_debug_code) {
|
||||
__ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ Push(eax);
|
||||
GetSharedFunctionInfoBytecode(masm, ecx, eax);
|
||||
__ Pop(eax);
|
||||
__ CmpObjectType(ecx, BYTECODE_ARRAY_TYPE, ecx);
|
||||
__ Assert(equal, AbortReason::kMissingBytecodeArray);
|
||||
}
|
||||
@ -855,6 +871,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(kInterpreterBytecodeArrayRegister,
|
||||
FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ Push(eax);
|
||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, eax);
|
||||
__ Pop(eax);
|
||||
__ JumpIfNotSmi(FieldOperand(eax, SharedFunctionInfo::kDebugInfoOffset),
|
||||
&maybe_load_debug_bytecode_array);
|
||||
__ bind(&bytecode_array_loaded);
|
||||
@ -1239,10 +1258,28 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
// Set the return address to the correct point in the interpreter entry
|
||||
// trampoline.
|
||||
Label builtin_trampoline, trampoline_loaded;
|
||||
Smi* interpreter_entry_return_pc_offset(
|
||||
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
|
||||
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
|
||||
|
||||
// If the SFI function_data is an InterpreterData, get the trampoline stored
|
||||
// in it, otherwise get the trampoline from the builtins list.
|
||||
__ mov(ebx, Operand(ebp, StandardFrameConstants::kFunctionOffset));
|
||||
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ Push(eax);
|
||||
__ CmpObjectType(ebx, INTERPRETER_DATA_TYPE, eax);
|
||||
__ j(not_equal, &builtin_trampoline, Label::kNear);
|
||||
|
||||
__ mov(ebx, FieldOperand(ebx, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ jmp(&trampoline_loaded, Label::kNear);
|
||||
|
||||
__ bind(&builtin_trampoline);
|
||||
__ Move(ebx, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline));
|
||||
|
||||
__ bind(&trampoline_loaded);
|
||||
__ Pop(eax);
|
||||
__ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() +
|
||||
Code::kHeaderSize - kHeapObjectTag));
|
||||
__ push(ebx);
|
||||
@ -1333,6 +1370,7 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
Label check_is_fixed_array;
|
||||
Label check_is_pre_parsed_scope_data;
|
||||
Label check_is_function_template_info;
|
||||
Label check_is_interpreter_data;
|
||||
|
||||
Register data_type = scratch1;
|
||||
|
||||
@ -1377,11 +1415,19 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
__ bind(&check_is_function_template_info);
|
||||
__ cmpw(data_type, Immediate(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ j(not_equal, &check_is_interpreter_data);
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ jmp(&done);
|
||||
|
||||
// IsInterpreterData: Interpret bytecode
|
||||
__ bind(&check_is_interpreter_data);
|
||||
if (FLAG_debug_code) {
|
||||
__ cmpw(data_type, Immediate(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ cmpw(data_type, Immediate(INTERPRETER_DATA_TYPE));
|
||||
__ Check(equal, AbortReason::kInvalidSharedFunctionInfoData);
|
||||
}
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ mov(sfi_data,
|
||||
FieldOperand(sfi_data, InterpreterData::kInterpreterTrampolineOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
@ -548,6 +548,19 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
|
||||
Generate_JSEntryTrampolineHelper(masm, true);
|
||||
}
|
||||
|
||||
static void GetSharedFunctionInfoBytecode(MacroAssembler* masm,
|
||||
Register sfi_data,
|
||||
Register scratch1) {
|
||||
Label done;
|
||||
|
||||
__ GetObjectType(sfi_data, scratch1, scratch1);
|
||||
__ Branch(&done, ne, scratch1, Operand(INTERPRETER_DATA_TYPE));
|
||||
__ lw(sfi_data,
|
||||
FieldMemOperand(sfi_data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -623,6 +636,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
if (FLAG_debug_code) {
|
||||
__ lw(a3, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, a3, a0);
|
||||
__ GetObjectType(a3, a3, a3);
|
||||
__ Assert(eq, AbortReason::kMissingBytecodeArray, a3,
|
||||
Operand(BYTECODE_ARRAY_TYPE));
|
||||
@ -899,6 +913,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ lw(a0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(kInterpreterBytecodeArrayRegister,
|
||||
FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, t0);
|
||||
__ lw(t0, FieldMemOperand(a0, SharedFunctionInfo::kDebugInfoOffset));
|
||||
__ JumpIfNotSmi(t0, &maybe_load_debug_bytecode_array);
|
||||
__ bind(&bytecode_array_loaded);
|
||||
@ -1188,10 +1203,28 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
// Set the return address to the correct point in the interpreter entry
|
||||
// trampoline.
|
||||
Label builtin_trampoline, trampoline_loaded;
|
||||
Smi* interpreter_entry_return_pc_offset(
|
||||
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
|
||||
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
|
||||
|
||||
// If the SFI function_data is an InterpreterData, get the trampoline stored
|
||||
// in it, otherwise get the trampoline from the builtins list.
|
||||
__ lw(t0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ lw(t0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ GetObjectType(t0, kInterpreterDispatchTableRegister,
|
||||
kInterpreterDispatchTableRegister);
|
||||
__ Branch(&builtin_trampoline, ne, kInterpreterDispatchTableRegister,
|
||||
Operand(INTERPRETER_DATA_TYPE));
|
||||
|
||||
__ lw(t0, FieldMemOperand(t0, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ Branch(&trampoline_loaded);
|
||||
|
||||
__ bind(&builtin_trampoline);
|
||||
__ li(t0, Operand(BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)));
|
||||
|
||||
__ bind(&trampoline_loaded);
|
||||
__ Addu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() +
|
||||
Code::kHeaderSize - kHeapObjectTag));
|
||||
|
||||
@ -1285,6 +1318,7 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
Label check_is_fixed_array;
|
||||
Label check_is_pre_parsed_scope_data;
|
||||
Label check_is_function_template_info;
|
||||
Label check_is_interpreter_data;
|
||||
|
||||
Register data_type = scratch1;
|
||||
|
||||
@ -1329,11 +1363,18 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
__ bind(&check_is_function_template_info);
|
||||
__ Branch(&check_is_interpreter_data, ne, data_type,
|
||||
Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
|
||||
// IsInterpreterData: Interpret bytecode
|
||||
__ bind(&check_is_interpreter_data);
|
||||
if (FLAG_debug_code) {
|
||||
__ Assert(eq, AbortReason::kInvalidSharedFunctionInfoData, data_type,
|
||||
Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
Operand(INTERPRETER_DATA_TYPE));
|
||||
}
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ lw(sfi_data, FieldMemOperand(
|
||||
sfi_data, InterpreterData::kInterpreterTrampolineOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
@ -438,6 +438,19 @@ void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
|
||||
static void GetSharedFunctionInfoBytecode(MacroAssembler* masm,
|
||||
Register sfi_data,
|
||||
Register scratch1) {
|
||||
Label done;
|
||||
|
||||
__ GetObjectType(sfi_data, scratch1, scratch1);
|
||||
__ Branch(&done, ne, scratch1, Operand(INTERPRETER_DATA_TYPE));
|
||||
__ Ld(sfi_data,
|
||||
FieldMemOperand(sfi_data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -512,6 +525,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
if (FLAG_debug_code) {
|
||||
__ Ld(a3, FieldMemOperand(a4, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ld(a3, FieldMemOperand(a3, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, a3, a0);
|
||||
__ GetObjectType(a3, a3, a3);
|
||||
__ Assert(eq, AbortReason::kMissingBytecodeArray, a3,
|
||||
Operand(BYTECODE_ARRAY_TYPE));
|
||||
@ -896,6 +910,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ Ld(a0, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ld(kInterpreterBytecodeArrayRegister,
|
||||
FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister, a4);
|
||||
__ Ld(a4, FieldMemOperand(a0, SharedFunctionInfo::kDebugInfoOffset));
|
||||
__ JumpIfNotSmi(a4, &maybe_load_debug_bytecode_array);
|
||||
__ bind(&bytecode_array_loaded);
|
||||
@ -1185,10 +1200,28 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
// Set the return address to the correct point in the interpreter entry
|
||||
// trampoline.
|
||||
Label builtin_trampoline, trampoline_loaded;
|
||||
Smi* interpreter_entry_return_pc_offset(
|
||||
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
|
||||
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
|
||||
|
||||
// If the SFI function_data is an InterpreterData, get the trampoline stored
|
||||
// in it, otherwise get the trampoline from the builtins list.
|
||||
__ Ld(t0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
|
||||
__ Ld(t0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ld(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ GetObjectType(t0, kInterpreterDispatchTableRegister,
|
||||
kInterpreterDispatchTableRegister);
|
||||
__ Branch(&builtin_trampoline, ne, kInterpreterDispatchTableRegister,
|
||||
Operand(INTERPRETER_DATA_TYPE));
|
||||
|
||||
__ Ld(t0, FieldMemOperand(t0, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ Branch(&trampoline_loaded);
|
||||
|
||||
__ bind(&builtin_trampoline);
|
||||
__ li(t0, Operand(BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)));
|
||||
|
||||
__ bind(&trampoline_loaded);
|
||||
__ Daddu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() +
|
||||
Code::kHeaderSize - kHeapObjectTag));
|
||||
|
||||
@ -1282,6 +1315,7 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
Label check_is_fixed_array;
|
||||
Label check_is_pre_parsed_scope_data;
|
||||
Label check_is_function_template_info;
|
||||
Label check_is_interpreter_data;
|
||||
|
||||
Register data_type = scratch1;
|
||||
|
||||
@ -1326,11 +1360,18 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
__ bind(&check_is_function_template_info);
|
||||
__ Branch(&check_is_interpreter_data, ne, data_type,
|
||||
Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
|
||||
// IsInterpreterData: Interpret bytecode
|
||||
__ bind(&check_is_interpreter_data);
|
||||
if (FLAG_debug_code) {
|
||||
__ Assert(eq, AbortReason::kInvalidSharedFunctionInfoData, data_type,
|
||||
Operand(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
Operand(INTERPRETER_DATA_TYPE));
|
||||
}
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ Ld(sfi_data, FieldMemOperand(
|
||||
sfi_data, InterpreterData::kInterpreterTrampolineOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
@ -559,6 +559,19 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
|
||||
Generate_JSEntryTrampolineHelper(masm, true);
|
||||
}
|
||||
|
||||
static void GetSharedFunctionInfoBytecode(MacroAssembler* masm,
|
||||
Register sfi_data,
|
||||
Register scratch1) {
|
||||
Label done;
|
||||
|
||||
__ CmpObjectType(sfi_data, INTERPRETER_DATA_TYPE, scratch1);
|
||||
__ j(not_equal, &done, Label::kNear);
|
||||
__ movp(sfi_data,
|
||||
FieldOperand(sfi_data, InterpreterData::kBytecodeArrayOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
@ -636,6 +649,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
|
||||
if (FLAG_debug_code) {
|
||||
__ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, rcx, kScratchRegister);
|
||||
__ CmpObjectType(rcx, BYTECODE_ARRAY_TYPE, rcx);
|
||||
__ Assert(equal, AbortReason::kMissingBytecodeArray);
|
||||
}
|
||||
@ -867,7 +881,7 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm,
|
||||
#define JUMP_IF_EQUAL(NAME) \
|
||||
__ cmpb(bytecode, \
|
||||
Immediate(static_cast<int>(interpreter::Bytecode::k##NAME))); \
|
||||
__ j(equal, if_return, Label::kNear);
|
||||
__ j(equal, if_return, Label::kFar);
|
||||
RETURN_BYTECODE_LIST(JUMP_IF_EQUAL)
|
||||
#undef JUMP_IF_EQUAL
|
||||
|
||||
@ -918,6 +932,8 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
|
||||
__ movp(rax, FieldOperand(closure, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movp(kInterpreterBytecodeArrayRegister,
|
||||
FieldOperand(rax, SharedFunctionInfo::kFunctionDataOffset));
|
||||
GetSharedFunctionInfoBytecode(masm, kInterpreterBytecodeArrayRegister,
|
||||
kScratchRegister);
|
||||
__ JumpIfNotSmi(FieldOperand(rax, SharedFunctionInfo::kDebugInfoOffset),
|
||||
&maybe_load_debug_bytecode_array);
|
||||
__ bind(&bytecode_array_loaded);
|
||||
@ -1214,13 +1230,30 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
|
||||
// Set the return address to the correct point in the interpreter entry
|
||||
// trampoline.
|
||||
Label builtin_trampoline, trampoline_loaded;
|
||||
// TODO(jgruber,v8:6666): Update logic once builtin is isolate-independent.
|
||||
DCHECK(
|
||||
!Builtins::IsIsolateIndependent(Builtins::kInterpreterEntryTrampoline));
|
||||
Smi* interpreter_entry_return_pc_offset(
|
||||
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
|
||||
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
|
||||
|
||||
// If the SFI function_data is an InterpreterData, get the trampoline stored
|
||||
// in it, otherwise get the trampoline from the builtins list.
|
||||
__ movp(rbx, Operand(rbp, StandardFrameConstants::kFunctionOffset));
|
||||
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset));
|
||||
__ CmpObjectType(rbx, INTERPRETER_DATA_TYPE, kScratchRegister);
|
||||
__ j(not_equal, &builtin_trampoline, Label::kNear);
|
||||
|
||||
__ movp(rbx,
|
||||
FieldOperand(rbx, InterpreterData::kInterpreterTrampolineOffset));
|
||||
__ jmp(&trampoline_loaded, Label::kNear);
|
||||
|
||||
__ bind(&builtin_trampoline);
|
||||
__ Move(rbx, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline));
|
||||
|
||||
__ bind(&trampoline_loaded);
|
||||
__ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value() +
|
||||
Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Push(rbx);
|
||||
@ -1315,6 +1348,7 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
Label check_is_fixed_array;
|
||||
Label check_is_pre_parsed_scope_data;
|
||||
Label check_is_function_template_info;
|
||||
Label check_is_interpreter_data;
|
||||
|
||||
Register data_type = scratch1;
|
||||
|
||||
@ -1357,11 +1391,20 @@ static void GetSharedFunctionInfoCode(MacroAssembler* masm, Register sfi_data,
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
__ bind(&check_is_function_template_info);
|
||||
__ cmpw(data_type, Immediate(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ j(not_equal, &check_is_interpreter_data);
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ j(always, &done);
|
||||
|
||||
// IsInterpreterData: Interpret bytecode with unique interpreter
|
||||
__ bind(&check_is_interpreter_data);
|
||||
if (FLAG_debug_code) {
|
||||
__ cmpw(data_type, Immediate(FUNCTION_TEMPLATE_INFO_TYPE));
|
||||
__ cmpw(data_type, Immediate(INTERPRETER_DATA_TYPE));
|
||||
__ Check(equal, AbortReason::kInvalidSharedFunctionInfoData);
|
||||
}
|
||||
__ Move(sfi_data, BUILTIN_CODE(masm->isolate(), HandleApiCall));
|
||||
__ movp(
|
||||
sfi_data,
|
||||
FieldOperand(sfi_data, InterpreterData::kInterpreterTrampolineOffset));
|
||||
|
||||
__ bind(&done);
|
||||
}
|
||||
|
@ -24,27 +24,28 @@ class WasmCode;
|
||||
using WasmName = Vector<const char>;
|
||||
} // namespace wasm
|
||||
|
||||
#define LOG_EVENTS_AND_TAGS_LIST(V) \
|
||||
V(CODE_CREATION_EVENT, "code-creation") \
|
||||
V(CODE_DISABLE_OPT_EVENT, "code-disable-optimization") \
|
||||
V(CODE_MOVE_EVENT, "code-move") \
|
||||
V(CODE_DELETE_EVENT, "code-delete") \
|
||||
V(CODE_MOVING_GC, "code-moving-gc") \
|
||||
V(SHARED_FUNC_MOVE_EVENT, "sfi-move") \
|
||||
V(SNAPSHOT_CODE_NAME_EVENT, "snapshot-code-name") \
|
||||
V(TICK_EVENT, "tick") \
|
||||
V(BUILTIN_TAG, "Builtin") \
|
||||
V(CALLBACK_TAG, "Callback") \
|
||||
V(EVAL_TAG, "Eval") \
|
||||
V(FUNCTION_TAG, "Function") \
|
||||
V(HANDLER_TAG, "Handler") \
|
||||
V(BYTECODE_HANDLER_TAG, "BytecodeHandler") \
|
||||
V(LAZY_COMPILE_TAG, "LazyCompile") \
|
||||
V(REG_EXP_TAG, "RegExp") \
|
||||
V(SCRIPT_TAG, "Script") \
|
||||
V(STUB_TAG, "Stub") \
|
||||
V(NATIVE_FUNCTION_TAG, "Function") \
|
||||
V(NATIVE_LAZY_COMPILE_TAG, "LazyCompile") \
|
||||
#define LOG_EVENTS_AND_TAGS_LIST(V) \
|
||||
V(CODE_CREATION_EVENT, "code-creation") \
|
||||
V(CODE_DISABLE_OPT_EVENT, "code-disable-optimization") \
|
||||
V(CODE_MOVE_EVENT, "code-move") \
|
||||
V(CODE_DELETE_EVENT, "code-delete") \
|
||||
V(CODE_MOVING_GC, "code-moving-gc") \
|
||||
V(SHARED_FUNC_MOVE_EVENT, "sfi-move") \
|
||||
V(SNAPSHOT_CODE_NAME_EVENT, "snapshot-code-name") \
|
||||
V(TICK_EVENT, "tick") \
|
||||
V(BUILTIN_TAG, "Builtin") \
|
||||
V(CALLBACK_TAG, "Callback") \
|
||||
V(EVAL_TAG, "Eval") \
|
||||
V(FUNCTION_TAG, "Function") \
|
||||
V(INTERPRETED_FUNCTION_TAG, "InterpretedFunction") \
|
||||
V(HANDLER_TAG, "Handler") \
|
||||
V(BYTECODE_HANDLER_TAG, "BytecodeHandler") \
|
||||
V(LAZY_COMPILE_TAG, "LazyCompile") \
|
||||
V(REG_EXP_TAG, "RegExp") \
|
||||
V(SCRIPT_TAG, "Script") \
|
||||
V(STUB_TAG, "Stub") \
|
||||
V(NATIVE_FUNCTION_TAG, "Function") \
|
||||
V(NATIVE_LAZY_COMPILE_TAG, "LazyCompile") \
|
||||
V(NATIVE_SCRIPT_TAG, "Script")
|
||||
// Note that 'NATIVE_' cases for functions and scripts are mapped onto
|
||||
// original tags when writing to the log.
|
||||
|
@ -2110,6 +2110,26 @@ Node* CodeStubAssembler::LoadJSFunctionPrototype(Node* function,
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::LoadSharedFunctionInfoBytecodeArray(Node* shared) {
|
||||
CSA_ASSERT(this, TaggedIsNotSmi(shared));
|
||||
CSA_ASSERT(this, IsSharedFunctionInfo(shared));
|
||||
|
||||
Node* function_data =
|
||||
LoadObjectField(shared, SharedFunctionInfo::kFunctionDataOffset);
|
||||
|
||||
VARIABLE(var_result, MachineRepresentation::kTagged, function_data);
|
||||
Label done(this, &var_result);
|
||||
|
||||
GotoIfNot(HasInstanceType(function_data, INTERPRETER_DATA_TYPE), &done);
|
||||
Node* bytecode_array =
|
||||
LoadObjectField(function_data, InterpreterData::kBytecodeArrayOffset);
|
||||
var_result.Bind(bytecode_array);
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
void CodeStubAssembler::StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
|
||||
SloppyTNode<Float64T> value) {
|
||||
StoreObjectFieldNoWriteBarrier(object, HeapNumber::kValueOffset, value,
|
||||
@ -11024,17 +11044,18 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
TNode<Int32T> data_type = LoadInstanceType(CAST(sfi_data));
|
||||
|
||||
int32_t case_values[] = {BYTECODE_ARRAY_TYPE, CODE_TYPE, FIXED_ARRAY_TYPE,
|
||||
TUPLE2_TYPE};
|
||||
TUPLE2_TYPE, FUNCTION_TEMPLATE_INFO_TYPE};
|
||||
Label check_is_bytecode_array(this);
|
||||
Label check_is_code(this);
|
||||
Label check_is_fixed_array(this);
|
||||
Label check_is_pre_parsed_scope_data(this);
|
||||
Label check_is_function_template_info(this);
|
||||
Label* case_labels[] = {&check_is_bytecode_array, &check_is_code,
|
||||
&check_is_fixed_array,
|
||||
&check_is_pre_parsed_scope_data};
|
||||
Label check_is_interpreter_data(this);
|
||||
Label* case_labels[] = {
|
||||
&check_is_bytecode_array, &check_is_code, &check_is_fixed_array,
|
||||
&check_is_pre_parsed_scope_data, &check_is_function_template_info};
|
||||
STATIC_ASSERT(arraysize(case_values) == arraysize(case_labels));
|
||||
Switch(data_type, &check_is_function_template_info, case_values, case_labels,
|
||||
Switch(data_type, &check_is_interpreter_data, case_values, case_labels,
|
||||
arraysize(case_labels));
|
||||
|
||||
// IsBytecodeArray: Interpret bytecode
|
||||
@ -11062,13 +11083,19 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
|
||||
// IsFunctionTemplateInfo: API call
|
||||
BIND(&check_is_function_template_info);
|
||||
// This is the default branch, so assert that we have the expected data type.
|
||||
CSA_ASSERT(
|
||||
this, Word32Equal(data_type, Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)));
|
||||
DCHECK(!Builtins::IsLazy(Builtins::kHandleApiCall));
|
||||
sfi_code = HeapConstant(BUILTIN_CODE(isolate(), HandleApiCall));
|
||||
Goto(&done);
|
||||
|
||||
// IsInterpreterData: Interpret bytecode
|
||||
BIND(&check_is_interpreter_data);
|
||||
// This is the default branch, so assert that we have the expected data type.
|
||||
CSA_ASSERT(this,
|
||||
Word32Equal(data_type, Int32Constant(INTERPRETER_DATA_TYPE)));
|
||||
sfi_code = CAST(LoadObjectField(
|
||||
CAST(sfi_data), InterpreterData::kInterpreterTrampolineOffset));
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
return sfi_code.value();
|
||||
}
|
||||
|
@ -749,6 +749,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// Load the "prototype" property of a JSFunction.
|
||||
Node* LoadJSFunctionPrototype(Node* function, Label* if_bailout);
|
||||
|
||||
Node* LoadSharedFunctionInfoBytecodeArray(Node* shared);
|
||||
|
||||
// Store the floating point value of a HeapNumber.
|
||||
void StoreHeapNumberValue(SloppyTNode<HeapNumber> object,
|
||||
SloppyTNode<Float64T> value);
|
||||
|
@ -309,9 +309,48 @@ bool UseAsmWasm(FunctionLiteral* literal, bool asm_wasm_broken) {
|
||||
return literal->scope()->IsAsmModule();
|
||||
}
|
||||
|
||||
void InstallBytecodeArray(Handle<BytecodeArray> bytecode_array,
|
||||
Handle<SharedFunctionInfo> shared_info,
|
||||
ParseInfo* parse_info, Isolate* isolate) {
|
||||
if (!FLAG_interpreted_frames_native_stack) {
|
||||
shared_info->set_bytecode_array(*bytecode_array);
|
||||
return;
|
||||
}
|
||||
|
||||
Handle<Code> code;
|
||||
{
|
||||
CodeSpaceMemoryModificationScope code_allocation(isolate->heap());
|
||||
|
||||
code = isolate->factory()->CopyCode(
|
||||
BUILTIN_CODE(isolate, InterpreterEntryTrampoline));
|
||||
}
|
||||
|
||||
Handle<InterpreterData> interpreter_data = Handle<InterpreterData>::cast(
|
||||
isolate->factory()->NewStruct(INTERPRETER_DATA_TYPE, TENURED));
|
||||
|
||||
interpreter_data->set_bytecode_array(*bytecode_array);
|
||||
interpreter_data->set_interpreter_trampoline(*code);
|
||||
|
||||
shared_info->set_interpreter_data(*interpreter_data);
|
||||
|
||||
Handle<Script> script = parse_info->script();
|
||||
Handle<AbstractCode> abstract_code = Handle<AbstractCode>::cast(code);
|
||||
int line_num =
|
||||
Script::GetLineNumber(script, shared_info->StartPosition()) + 1;
|
||||
int column_num =
|
||||
Script::GetColumnNumber(script, shared_info->StartPosition()) + 1;
|
||||
String* script_name = script->name()->IsString()
|
||||
? String::cast(script->name())
|
||||
: isolate->heap()->empty_string();
|
||||
CodeEventListener::LogEventsAndTags log_tag = Logger::ToNativeByScript(
|
||||
CodeEventListener::INTERPRETED_FUNCTION_TAG, *script);
|
||||
PROFILE(isolate, CodeCreateEvent(log_tag, *abstract_code, *shared_info,
|
||||
script_name, line_num, column_num));
|
||||
}
|
||||
|
||||
void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
|
||||
Handle<SharedFunctionInfo> shared_info,
|
||||
Isolate* isolate) {
|
||||
ParseInfo* parse_info, Isolate* isolate) {
|
||||
DCHECK_EQ(shared_info->language_mode(),
|
||||
compilation_info->literal()->language_mode());
|
||||
|
||||
@ -327,7 +366,8 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
|
||||
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
|
||||
isolate, compilation_info->feedback_vector_spec());
|
||||
|
||||
shared_info->set_bytecode_array(*compilation_info->bytecode_array());
|
||||
InstallBytecodeArray(compilation_info->bytecode_array(), shared_info,
|
||||
parse_info, isolate);
|
||||
shared_info->set_feedback_metadata(*feedback_metadata);
|
||||
} else {
|
||||
DCHECK(compilation_info->has_asm_wasm_data());
|
||||
@ -382,7 +422,7 @@ CompilationJob::Status FinalizeUnoptimizedCompilationJob(
|
||||
|
||||
CompilationJob::Status status = job->FinalizeJob(shared_info, isolate);
|
||||
if (status == CompilationJob::SUCCEEDED) {
|
||||
InstallUnoptimizedCode(compilation_info, shared_info, isolate);
|
||||
InstallUnoptimizedCode(compilation_info, shared_info, parse_info, isolate);
|
||||
CodeEventListener::LogEventsAndTags log_tag;
|
||||
if (parse_info->is_toplevel()) {
|
||||
log_tag = compilation_info->is_eval() ? CodeEventListener::EVAL_TAG
|
||||
|
@ -521,7 +521,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(
|
||||
: local_zone_(local_zone),
|
||||
jsgraph_(jsgraph),
|
||||
invocation_frequency_(invocation_frequency),
|
||||
bytecode_array_(handle(shared_info->bytecode_array())),
|
||||
bytecode_array_(handle(shared_info->GetBytecodeArray())),
|
||||
feedback_vector_(feedback_vector),
|
||||
type_hint_lowering_(jsgraph, feedback_vector, flags),
|
||||
frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
|
||||
|
@ -38,6 +38,7 @@ class PromiseFulfillReactionJobTask;
|
||||
class PromiseReaction;
|
||||
class PromiseReactionJobTask;
|
||||
class PromiseRejectReactionJobTask;
|
||||
class InterpreterData;
|
||||
class Factory;
|
||||
class Zone;
|
||||
|
||||
|
@ -495,7 +495,7 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
|
||||
|
||||
// Allocate a register file.
|
||||
DCHECK(js_function->shared()->HasBytecodeArray());
|
||||
int size = js_function->shared()->bytecode_array()->register_count();
|
||||
int size = js_function->shared()->GetBytecodeArray()->register_count();
|
||||
AllocationBuilder ab(jsgraph(), effect, control);
|
||||
ab.AllocateArray(size, factory()->fixed_array_map());
|
||||
for (int i = 0; i < size; ++i) {
|
||||
|
@ -62,7 +62,7 @@ bool CanInlineFunction(Handle<SharedFunctionInfo> shared) {
|
||||
if (!shared->HasBytecodeArray()) return false;
|
||||
|
||||
// Quick check on the size of the bytecode to avoid inlining large functions.
|
||||
if (shared->bytecode_array()->length() > FLAG_max_inlined_bytecode_size) {
|
||||
if (shared->GetBytecodeArray()->length() > FLAG_max_inlined_bytecode_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ bool CanInlineFunction(Handle<SharedFunctionInfo> shared) {
|
||||
bool IsSmallInlineFunction(Handle<SharedFunctionInfo> shared) {
|
||||
// Forcibly inline small functions.
|
||||
// Don't forcibly inline functions that weren't compiled yet.
|
||||
if (shared->HasBytecodeArray() && shared->bytecode_array()->length() <=
|
||||
if (shared->HasBytecodeArray() && shared->GetBytecodeArray()->length() <=
|
||||
FLAG_max_inlined_bytecode_size_small) {
|
||||
return true;
|
||||
}
|
||||
@ -132,7 +132,7 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
|
||||
}
|
||||
if (candidate.can_inline_function[i]) {
|
||||
can_inline = true;
|
||||
candidate.total_size += shared->bytecode_array()->length();
|
||||
candidate.total_size += shared->GetBytecodeArray()->length();
|
||||
}
|
||||
if (!IsSmallInlineFunction(shared)) {
|
||||
small_inline = false;
|
||||
@ -610,7 +610,7 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate,
|
||||
: handle(candidate.functions[0]->shared());
|
||||
Reduction const reduction = inliner_.ReduceJSCall(node);
|
||||
if (reduction.Changed()) {
|
||||
cumulative_count_ += shared->bytecode_array()->length();
|
||||
cumulative_count_ += shared->GetBytecodeArray()->length();
|
||||
}
|
||||
return reduction;
|
||||
}
|
||||
@ -679,7 +679,7 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate,
|
||||
// Killing the call node is not strictly necessary, but it is safer to
|
||||
// make sure we do not resurrect the node.
|
||||
node->Kill();
|
||||
cumulative_count_ += function->shared()->bytecode_array()->length();
|
||||
cumulative_count_ += function->shared()->GetBytecodeArray()->length();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -720,7 +720,7 @@ void JSInliningHeuristic::PrintCandidates() {
|
||||
candidate.functions[i].is_null()
|
||||
? candidate.shared_info
|
||||
: handle(candidate.functions[i]->shared());
|
||||
PrintF(" - size:%d, name: %s\n", shared->bytecode_array()->length(),
|
||||
PrintF(" - size:%d, name: %s\n", shared->GetBytecodeArray()->length(),
|
||||
shared->DebugName()->ToCString().get());
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,10 @@ namespace compiler {
|
||||
|
||||
OsrHelper::OsrHelper(OptimizedCompilationInfo* info)
|
||||
: parameter_count_(
|
||||
info->shared_info()->bytecode_array()->parameter_count()),
|
||||
info->shared_info()->GetBytecodeArray()->parameter_count()),
|
||||
stack_slot_count_(
|
||||
InterpreterFrameConstants::RegisterStackSlotCount(
|
||||
info->shared_info()->bytecode_array()->register_count()) +
|
||||
info->shared_info()->GetBytecodeArray()->register_count()) +
|
||||
InterpreterFrameConstants::kExtraSlotCount) {}
|
||||
|
||||
void OsrHelper::SetupFrame(Frame* frame) {
|
||||
|
@ -794,7 +794,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
|
||||
|
||||
PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl(
|
||||
Isolate* isolate) {
|
||||
if (compilation_info()->shared_info()->bytecode_array()->length() >
|
||||
if (compilation_info()->shared_info()->GetBytecodeArray()->length() >
|
||||
kMaxBytecodeSizeForTurbofan) {
|
||||
return AbortOptimization(BailoutReason::kFunctionTooBig);
|
||||
}
|
||||
|
@ -318,6 +318,7 @@ Type::bitset BitsetType::Lub(i::Map* map) {
|
||||
case SMALL_ORDERED_HASH_MAP_TYPE:
|
||||
case SMALL_ORDERED_HASH_SET_TYPE:
|
||||
case PROTOTYPE_INFO_TYPE:
|
||||
case INTERPRETER_DATA_TYPE:
|
||||
case TUPLE2_TYPE:
|
||||
case TUPLE3_TYPE:
|
||||
case WASM_COMPILED_MODULE_TYPE:
|
||||
|
@ -890,7 +890,7 @@ DebugEvaluate::SideEffectState DebugEvaluate::FunctionGetSideEffectState(
|
||||
DCHECK(info->is_compiled());
|
||||
if (info->HasBytecodeArray()) {
|
||||
// Check bytecodes against whitelist.
|
||||
Handle<BytecodeArray> bytecode_array(info->bytecode_array());
|
||||
Handle<BytecodeArray> bytecode_array(info->GetBytecodeArray());
|
||||
if (FLAG_trace_side_effect_free_debug_evaluate) bytecode_array->Print();
|
||||
bool requires_runtime_checks = false;
|
||||
for (interpreter::BytecodeArrayIterator it(bytecode_array); !it.done();
|
||||
|
@ -1232,7 +1232,7 @@ void Debug::PrepareFunctionForDebugExecution(
|
||||
Handle<Object> maybe_debug_bytecode_array =
|
||||
isolate_->factory()->undefined_value();
|
||||
if (shared->HasBytecodeArray()) {
|
||||
Handle<BytecodeArray> original(shared->bytecode_array());
|
||||
Handle<BytecodeArray> original(shared->GetBytecodeArray());
|
||||
maybe_debug_bytecode_array =
|
||||
isolate_->factory()->CopyBytecodeArray(original);
|
||||
}
|
||||
@ -2418,7 +2418,7 @@ bool Debug::PerformSideEffectCheckAtBytecode(InterpretedFrame* frame) {
|
||||
|
||||
DCHECK_EQ(isolate_->debug_execution_mode(), DebugInfo::kSideEffects);
|
||||
SharedFunctionInfo* shared = frame->function()->shared();
|
||||
BytecodeArray* bytecode_array = shared->bytecode_array();
|
||||
BytecodeArray* bytecode_array = shared->GetBytecodeArray();
|
||||
int offset = frame->GetBytecodeOffset();
|
||||
interpreter::BytecodeArrayAccessor bytecode_accessor(handle(bytecode_array),
|
||||
offset);
|
||||
|
@ -827,7 +827,11 @@ void LiveEdit::ReplaceFunctionCode(
|
||||
// Clear old bytecode. This will trigger self-healing if we do not install
|
||||
// new bytecode.
|
||||
shared_info->FlushCompiled();
|
||||
shared_info->set_bytecode_array(new_shared_info->bytecode_array());
|
||||
if (new_shared_info->HasInterpreterData()) {
|
||||
shared_info->set_interpreter_data(new_shared_info->interpreter_data());
|
||||
} else {
|
||||
shared_info->set_bytecode_array(new_shared_info->GetBytecodeArray());
|
||||
}
|
||||
|
||||
if (shared_info->HasBreakInfo()) {
|
||||
// Existing break points will be re-applied. Reset the debug info here.
|
||||
@ -989,7 +993,7 @@ void LiveEdit::PatchFunctionPositions(Handle<JSArray> shared_info_array,
|
||||
info->set_function_token_position(new_function_token_pos);
|
||||
|
||||
if (info->HasBytecodeArray()) {
|
||||
TranslateSourcePositionTable(handle(info->bytecode_array()),
|
||||
TranslateSourcePositionTable(handle(info->GetBytecodeArray()),
|
||||
position_change_array);
|
||||
}
|
||||
if (info->HasBreakInfo()) {
|
||||
|
@ -548,7 +548,8 @@ int LookupCatchHandler(TranslatedFrame* translated_frame, int* data_out) {
|
||||
switch (translated_frame->kind()) {
|
||||
case TranslatedFrame::kInterpretedFunction: {
|
||||
int bytecode_offset = translated_frame->node_id().ToInt();
|
||||
HandlerTable table(translated_frame->raw_shared_info()->bytecode_array());
|
||||
HandlerTable table(
|
||||
translated_frame->raw_shared_info()->GetBytecodeArray());
|
||||
return table.LookupRange(bytecode_offset, data_out, nullptr);
|
||||
}
|
||||
case TranslatedFrame::kJavaScriptBuiltinContinuationWithCatch: {
|
||||
@ -891,7 +892,7 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
|
||||
output_offset -= kPointerSize;
|
||||
Object* bytecode_array = shared->HasBreakInfo()
|
||||
? shared->GetDebugInfo()->DebugBytecodeArray()
|
||||
: shared->bytecode_array();
|
||||
: shared->GetBytecodeArray();
|
||||
WriteValueToOutput(bytecode_array, 0, frame_index, output_offset,
|
||||
"bytecode array ");
|
||||
|
||||
@ -2462,7 +2463,7 @@ Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) {
|
||||
int Deoptimizer::ComputeSourcePositionFromBytecodeArray(
|
||||
SharedFunctionInfo* shared, BailoutId node_id) {
|
||||
DCHECK(shared->HasBytecodeArray());
|
||||
return AbstractCode::cast(shared->bytecode_array())
|
||||
return AbstractCode::cast(shared->GetBytecodeArray())
|
||||
->SourcePosition(node_id.ToInt());
|
||||
}
|
||||
|
||||
|
@ -1229,6 +1229,9 @@ DEFINE_BOOL(prof_browser_mode, true,
|
||||
DEFINE_STRING(logfile, "v8.log", "Specify the name of the log file.")
|
||||
DEFINE_BOOL(logfile_per_isolate, true, "Separate log files for each isolate.")
|
||||
DEFINE_BOOL(ll_prof, false, "Enable low-level linux profiler.")
|
||||
DEFINE_BOOL(interpreted_frames_native_stack, false,
|
||||
"Show interpreted frames on the native stack (useful for external "
|
||||
"profilers).")
|
||||
DEFINE_BOOL(perf_basic_prof, false,
|
||||
"Enable perf linux profiler (basic support).")
|
||||
DEFINE_NEG_IMPLICATION(perf_basic_prof, compact_code_space)
|
||||
|
@ -169,7 +169,8 @@ bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
|
||||
bool IsInterpreterFramePc(Isolate* isolate, Address pc,
|
||||
StackFrame::State* state) {
|
||||
Code* interpreter_entry_trampoline =
|
||||
isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline);
|
||||
Code* interpreter_bytecode_advance =
|
||||
@ -177,12 +178,30 @@ bool IsInterpreterFramePc(Isolate* isolate, Address pc) {
|
||||
Code* interpreter_bytecode_dispatch =
|
||||
isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
|
||||
|
||||
return (pc >= interpreter_entry_trampoline->InstructionStart() &&
|
||||
pc < interpreter_entry_trampoline->InstructionEnd()) ||
|
||||
(pc >= interpreter_bytecode_advance->InstructionStart() &&
|
||||
pc < interpreter_bytecode_advance->InstructionEnd()) ||
|
||||
(pc >= interpreter_bytecode_dispatch->InstructionStart() &&
|
||||
pc < interpreter_bytecode_dispatch->InstructionEnd());
|
||||
if (interpreter_entry_trampoline->contains(pc) ||
|
||||
interpreter_bytecode_advance->contains(pc) ||
|
||||
interpreter_bytecode_dispatch->contains(pc)) {
|
||||
return true;
|
||||
} else if (FLAG_interpreted_frames_native_stack) {
|
||||
intptr_t marker = Memory::intptr_at(
|
||||
state->fp + CommonFrameConstants::kContextOrFrameTypeOffset);
|
||||
MSAN_MEMORY_IS_INITIALIZED(
|
||||
state->fp + StandardFrameConstants::kFunctionOffset, kPointerSize);
|
||||
Object* maybe_function =
|
||||
Memory::Object_at(state->fp + StandardFrameConstants::kFunctionOffset);
|
||||
// There's no need to run a full ContainsSlow if we know the frame can't be
|
||||
// an InterpretedFrame, so we do these fast checks first
|
||||
if (StackFrame::IsTypeMarker(marker) || maybe_function->IsSmi()) {
|
||||
return false;
|
||||
} else if (!isolate->heap()->code_space()->ContainsSlow(pc)) {
|
||||
return false;
|
||||
}
|
||||
interpreter_entry_trampoline =
|
||||
isolate->heap()->GcSafeFindCodeForInnerPointer(pc);
|
||||
return interpreter_entry_trampoline->is_interpreter_trampoline_builtin();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DISABLE_ASAN Address ReadMemoryAt(Address address) {
|
||||
@ -229,7 +248,7 @@ SafeStackFrameIterator::SafeStackFrameIterator(
|
||||
if (IsValidStackAddress(sp)) {
|
||||
MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
|
||||
Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
|
||||
if (IsInterpreterFramePc(isolate, tos)) {
|
||||
if (IsInterpreterFramePc(isolate, tos, &state)) {
|
||||
state.pc_address = reinterpret_cast<Address*>(sp);
|
||||
advance_frame = false;
|
||||
}
|
||||
@ -436,8 +455,8 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
|
||||
if (!StackFrame::IsTypeMarker(marker)) {
|
||||
if (maybe_function->IsSmi()) {
|
||||
return NATIVE;
|
||||
} else if (IsInterpreterFramePc(iterator->isolate(),
|
||||
*(state->pc_address))) {
|
||||
} else if (IsInterpreterFramePc(iterator->isolate(), *(state->pc_address),
|
||||
state)) {
|
||||
return INTERPRETED;
|
||||
} else {
|
||||
return OPTIMIZED;
|
||||
@ -1641,7 +1660,7 @@ int InterpretedFrame::position() const {
|
||||
|
||||
int InterpretedFrame::LookupExceptionHandlerInTable(
|
||||
int* context_register, HandlerTable::CatchPrediction* prediction) {
|
||||
HandlerTable table(function()->shared()->bytecode_array());
|
||||
HandlerTable table(function()->shared()->GetBytecodeArray());
|
||||
return table.LookupRange(GetBytecodeOffset(), context_register, prediction);
|
||||
}
|
||||
|
||||
@ -1710,7 +1729,7 @@ void InterpretedFrame::WriteInterpreterRegister(int register_index,
|
||||
void InterpretedFrame::Summarize(std::vector<FrameSummary>* functions) const {
|
||||
DCHECK(functions->empty());
|
||||
AbstractCode* abstract_code =
|
||||
AbstractCode::cast(function()->shared()->bytecode_array());
|
||||
AbstractCode::cast(function()->shared()->GetBytecodeArray());
|
||||
FrameSummary::JavaScriptFrameSummary summary(
|
||||
isolate(), receiver(), function(), abstract_code, GetBytecodeOffset(),
|
||||
IsConstructor());
|
||||
|
@ -243,6 +243,7 @@
|
||||
V(intl_initialized_marker_symbol) \
|
||||
V(intl_pattern_symbol) \
|
||||
V(intl_resolved_symbol) \
|
||||
V(interpreter_trampoline_symbol) \
|
||||
V(megamorphic_symbol) \
|
||||
V(native_context_index_symbol) \
|
||||
V(nonextensible_symbol) \
|
||||
|
@ -28,6 +28,7 @@ namespace interpreter {
|
||||
V(EmptyFixedArray, empty_fixed_array) \
|
||||
V(HomeObjectSymbol, home_object_symbol) \
|
||||
V(IteratorSymbol, iterator_symbol) \
|
||||
V(InterpreterTrampolineSymbol, interpreter_trampoline_symbol) \
|
||||
V(NaN, nan_value)
|
||||
|
||||
// A helper class for constructing constant arrays for the
|
||||
|
@ -1715,6 +1715,12 @@ void PreParsedScopeData::PreParsedScopeDataVerify() {
|
||||
CHECK(child_data()->IsFixedArray());
|
||||
}
|
||||
|
||||
void InterpreterData::InterpreterDataVerify() {
|
||||
CHECK(IsInterpreterData());
|
||||
CHECK(bytecode_array()->IsBytecodeArray());
|
||||
CHECK(interpreter_trampoline()->IsCode());
|
||||
}
|
||||
|
||||
#endif // VERIFY_HEAP
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -2609,7 +2609,7 @@ void JSFunction::CompleteInobjectSlackTrackingIfActive() {
|
||||
|
||||
AbstractCode* JSFunction::abstract_code() {
|
||||
if (IsInterpreted()) {
|
||||
return AbstractCode::cast(shared()->bytecode_array());
|
||||
return AbstractCode::cast(shared()->GetBytecodeArray());
|
||||
} else {
|
||||
return AbstractCode::cast(code());
|
||||
}
|
||||
|
@ -1214,7 +1214,7 @@ void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT
|
||||
if (IsInterpreted()) {
|
||||
os << "\n - interpreted";
|
||||
if (shared()->HasBytecodeArray()) {
|
||||
os << "\n - bytecode: " << shared()->bytecode_array();
|
||||
os << "\n - bytecode: " << shared()->GetBytecodeArray();
|
||||
}
|
||||
}
|
||||
if (WasmExportedFunction::IsWasmExportedFunction(this)) {
|
||||
@ -1893,6 +1893,13 @@ void PreParsedScopeData::PreParsedScopeDataPrint(std::ostream& os) { // NOLINT
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void InterpreterData::InterpreterDataPrint(std::ostream& os) { // NOLINT
|
||||
HeapObject::PrintHeader(os, "InterpreterData");
|
||||
os << "\n - bytecode_array: " << Brief(bytecode_array());
|
||||
os << "\n - interpreter_trampoline: " << Brief(interpreter_trampoline());
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
#endif // OBJECT_PRINT
|
||||
|
||||
// TODO(cbruni): remove once the new maptracer is in place.
|
||||
|
@ -17646,7 +17646,7 @@ void CompilationCacheTable::Age() {
|
||||
}
|
||||
} else if (get(entry_index)->IsFixedArray()) {
|
||||
SharedFunctionInfo* info = SharedFunctionInfo::cast(get(value_index));
|
||||
if (info->IsInterpreted() && info->bytecode_array()->IsOld()) {
|
||||
if (info->IsInterpreted() && info->GetBytecodeArray()->IsOld()) {
|
||||
for (int i = 0; i < kEntrySize; i++) {
|
||||
NoWriteBarrierSet(this, entry_index + i, the_hole_value);
|
||||
}
|
||||
@ -19436,7 +19436,7 @@ int JSGeneratorObject::source_position() const {
|
||||
// is used in the source position table, hence the subtraction.
|
||||
code_offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
|
||||
AbstractCode* code =
|
||||
AbstractCode::cast(function()->shared()->bytecode_array());
|
||||
AbstractCode::cast(function()->shared()->GetBytecodeArray());
|
||||
return code->SourcePosition(code_offset);
|
||||
}
|
||||
|
||||
|
@ -386,6 +386,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(DEBUG_INFO_TYPE) \
|
||||
V(FUNCTION_TEMPLATE_INFO_TYPE) \
|
||||
V(INTERCEPTOR_INFO_TYPE) \
|
||||
V(INTERPRETER_DATA_TYPE) \
|
||||
V(MODULE_INFO_ENTRY_TYPE) \
|
||||
V(MODULE_TYPE) \
|
||||
V(OBJECT_TEMPLATE_INFO_TYPE) \
|
||||
@ -558,6 +559,7 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
|
||||
V(DEBUG_INFO, DebugInfo, debug_info) \
|
||||
V(FUNCTION_TEMPLATE_INFO, FunctionTemplateInfo, function_template_info) \
|
||||
V(INTERCEPTOR_INFO, InterceptorInfo, interceptor_info) \
|
||||
V(INTERPRETER_DATA, InterpreterData, interpreter_data) \
|
||||
V(MODULE_INFO_ENTRY, ModuleInfoEntry, module_info_entry) \
|
||||
V(MODULE, Module, module) \
|
||||
V(OBJECT_TEMPLATE_INFO, ObjectTemplateInfo, object_template_info) \
|
||||
@ -752,6 +754,7 @@ enum InstanceType : uint16_t {
|
||||
DEBUG_INFO_TYPE,
|
||||
FUNCTION_TEMPLATE_INFO_TYPE,
|
||||
INTERCEPTOR_INFO_TYPE,
|
||||
INTERPRETER_DATA_TYPE,
|
||||
MODULE_INFO_ENTRY_TYPE,
|
||||
MODULE_TYPE,
|
||||
OBJECT_TEMPLATE_INFO_TYPE,
|
||||
|
@ -341,8 +341,10 @@ void Code::initialize_flags(Kind kind, bool has_unwinding_info,
|
||||
|
||||
inline bool Code::is_interpreter_trampoline_builtin() const {
|
||||
Builtins* builtins = GetIsolate()->builtins();
|
||||
Code* interpreter_entry_trampoline =
|
||||
builtins->builtin(Builtins::kInterpreterEntryTrampoline);
|
||||
bool is_interpreter_trampoline =
|
||||
(this == builtins->builtin(Builtins::kInterpreterEntryTrampoline) ||
|
||||
(builtin_index() == interpreter_entry_trampoline->builtin_index() ||
|
||||
this == builtins->builtin(Builtins::kInterpreterEnterBytecodeAdvance) ||
|
||||
this == builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch));
|
||||
DCHECK_IMPLIES(is_interpreter_trampoline, !Builtins::IsLazy(builtin_index()));
|
||||
@ -351,9 +353,11 @@ inline bool Code::is_interpreter_trampoline_builtin() const {
|
||||
|
||||
inline bool Code::checks_optimization_marker() const {
|
||||
Builtins* builtins = GetIsolate()->builtins();
|
||||
Code* interpreter_entry_trampoline =
|
||||
builtins->builtin(Builtins::kInterpreterEntryTrampoline);
|
||||
bool checks_marker =
|
||||
(this == builtins->builtin(Builtins::kCompileLazy) ||
|
||||
this == builtins->builtin(Builtins::kInterpreterEntryTrampoline));
|
||||
builtin_index() == interpreter_entry_trampoline->builtin_index());
|
||||
DCHECK_IMPLIES(checks_marker, !Builtins::IsLazy(builtin_index()));
|
||||
return checks_marker ||
|
||||
(kind() == OPTIMIZED_FUNCTION && marked_for_deoptimization());
|
||||
|
@ -39,7 +39,7 @@ bool DebugInfo::HasDebugBytecodeArray() {
|
||||
|
||||
BytecodeArray* DebugInfo::OriginalBytecodeArray() {
|
||||
DCHECK(HasDebugBytecodeArray());
|
||||
return shared()->bytecode_array();
|
||||
return shared()->GetBytecodeArray();
|
||||
}
|
||||
|
||||
BytecodeArray* DebugInfo::DebugBytecodeArray() {
|
||||
|
@ -19,6 +19,11 @@ CAST_ACCESSOR(PreParsedScopeData)
|
||||
ACCESSORS(PreParsedScopeData, scope_data, PodArray<uint8_t>, kScopeDataOffset)
|
||||
ACCESSORS(PreParsedScopeData, child_data, FixedArray, kChildDataOffset)
|
||||
|
||||
CAST_ACCESSOR(InterpreterData)
|
||||
ACCESSORS(InterpreterData, bytecode_array, BytecodeArray, kBytecodeArrayOffset)
|
||||
ACCESSORS(InterpreterData, interpreter_trampoline, Code,
|
||||
kInterpreterTrampolineOffset)
|
||||
|
||||
TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
|
||||
CAST_ACCESSOR(SharedFunctionInfo)
|
||||
DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
|
||||
@ -87,7 +92,7 @@ void SharedFunctionInfo::SetName(String* name) {
|
||||
|
||||
AbstractCode* SharedFunctionInfo::abstract_code() {
|
||||
if (HasBytecodeArray()) {
|
||||
return AbstractCode::cast(bytecode_array());
|
||||
return AbstractCode::cast(GetBytecodeArray());
|
||||
} else {
|
||||
return AbstractCode::cast(GetCode());
|
||||
}
|
||||
@ -291,6 +296,11 @@ Code* SharedFunctionInfo::GetCode() const {
|
||||
// Having a code object means we should run it.
|
||||
DCHECK(HasCodeObject());
|
||||
return Code::cast(data);
|
||||
} else if (data->IsInterpreterData()) {
|
||||
Code* code = InterpreterTrampoline();
|
||||
DCHECK(code->IsCode());
|
||||
DCHECK(code->is_interpreter_trampoline_builtin());
|
||||
return code;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -417,19 +427,45 @@ FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasBytecodeArray() const {
|
||||
return function_data()->IsBytecodeArray();
|
||||
return function_data()->IsBytecodeArray() ||
|
||||
function_data()->IsInterpreterData();
|
||||
}
|
||||
|
||||
BytecodeArray* SharedFunctionInfo::bytecode_array() const {
|
||||
BytecodeArray* SharedFunctionInfo::GetBytecodeArray() const {
|
||||
DCHECK(HasBytecodeArray());
|
||||
return BytecodeArray::cast(function_data());
|
||||
if (function_data()->IsBytecodeArray()) {
|
||||
return BytecodeArray::cast(function_data());
|
||||
} else {
|
||||
DCHECK(function_data()->IsInterpreterData());
|
||||
return InterpreterData::cast(function_data())->bytecode_array();
|
||||
}
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_bytecode_array(BytecodeArray* bytecode) {
|
||||
void SharedFunctionInfo::set_bytecode_array(class BytecodeArray* bytecode) {
|
||||
DCHECK(function_data() == Smi::FromEnum(Builtins::kCompileLazy));
|
||||
set_function_data(bytecode);
|
||||
}
|
||||
|
||||
Code* SharedFunctionInfo::InterpreterTrampoline() const {
|
||||
DCHECK(HasInterpreterData());
|
||||
return interpreter_data()->interpreter_trampoline();
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasInterpreterData() const {
|
||||
return function_data()->IsInterpreterData();
|
||||
}
|
||||
|
||||
InterpreterData* SharedFunctionInfo::interpreter_data() const {
|
||||
DCHECK(HasInterpreterData());
|
||||
return InterpreterData::cast(function_data());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_interpreter_data(
|
||||
InterpreterData* interpreter_data) {
|
||||
DCHECK(FLAG_interpreted_frames_native_stack);
|
||||
set_function_data(interpreter_data);
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasAsmWasmData() const {
|
||||
return function_data()->IsFixedArray();
|
||||
}
|
||||
|
@ -35,6 +35,24 @@ class PreParsedScopeData : public Struct {
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(PreParsedScopeData);
|
||||
};
|
||||
|
||||
class InterpreterData : public Struct {
|
||||
public:
|
||||
DECL_ACCESSORS(bytecode_array, BytecodeArray)
|
||||
DECL_ACCESSORS(interpreter_trampoline, Code)
|
||||
|
||||
static const int kBytecodeArrayOffset = Struct::kHeaderSize;
|
||||
static const int kInterpreterTrampolineOffset =
|
||||
kBytecodeArrayOffset + kPointerSize;
|
||||
static const int kSize = kInterpreterTrampolineOffset + kPointerSize;
|
||||
|
||||
DECL_CAST(InterpreterData)
|
||||
DECL_PRINTER(InterpreterData)
|
||||
DECL_VERIFIER(InterpreterData)
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(InterpreterData);
|
||||
};
|
||||
|
||||
// SharedFunctionInfo describes the JSFunction information that can be
|
||||
// shared by multiple instances of the function.
|
||||
class SharedFunctionInfo : public HeapObject {
|
||||
@ -143,6 +161,8 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// Currently it has one of:
|
||||
// - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
|
||||
// - a BytecodeArray for the interpreter [HasBytecodeArray()].
|
||||
// - a InterpreterData with the BytecodeArray and a copy of the
|
||||
// interpreter trampoline [HasInterpreterData()]
|
||||
// - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()].
|
||||
// - a Smi containing the builtin id [HasBuiltinId()]
|
||||
// - a PreParsedScopeData for the parser [HasPreParsedScopeData()]
|
||||
@ -153,8 +173,12 @@ class SharedFunctionInfo : public HeapObject {
|
||||
inline FunctionTemplateInfo* get_api_func_data();
|
||||
inline void set_api_func_data(FunctionTemplateInfo* data);
|
||||
inline bool HasBytecodeArray() const;
|
||||
inline BytecodeArray* bytecode_array() const;
|
||||
inline void set_bytecode_array(BytecodeArray* bytecode);
|
||||
inline BytecodeArray* GetBytecodeArray() const;
|
||||
inline void set_bytecode_array(class BytecodeArray* bytecode);
|
||||
inline Code* InterpreterTrampoline() const;
|
||||
inline bool HasInterpreterData() const;
|
||||
inline InterpreterData* interpreter_data() const;
|
||||
inline void set_interpreter_data(InterpreterData* interpreter_data);
|
||||
inline bool HasAsmWasmData() const;
|
||||
inline FixedArray* asm_wasm_data() const;
|
||||
inline void set_asm_wasm_data(FixedArray* data);
|
||||
|
@ -134,8 +134,8 @@ void RuntimeProfiler::AttemptOnStackReplacement(JavaScriptFrame* frame,
|
||||
|
||||
DCHECK_EQ(StackFrame::INTERPRETED, frame->type());
|
||||
DCHECK(shared->HasBytecodeArray());
|
||||
int level = shared->bytecode_array()->osr_loop_nesting_level();
|
||||
shared->bytecode_array()->set_osr_loop_nesting_level(
|
||||
int level = shared->GetBytecodeArray()->osr_loop_nesting_level();
|
||||
shared->GetBytecodeArray()->set_osr_loop_nesting_level(
|
||||
Min(level + loop_nesting_levels, AbstractCode::kMaxLoopNestingMarker));
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ bool RuntimeProfiler::MaybeOSR(JSFunction* function, JavaScriptFrame* frame) {
|
||||
int64_t allowance =
|
||||
kOSRBytecodeSizeAllowanceBase +
|
||||
static_cast<int64_t>(ticks) * kOSRBytecodeSizeAllowancePerTick;
|
||||
if (shared->bytecode_array()->length() <= allowance) {
|
||||
if (shared->GetBytecodeArray()->length() <= allowance) {
|
||||
AttemptOnStackReplacement(frame);
|
||||
}
|
||||
return true;
|
||||
@ -197,17 +197,17 @@ OptimizationReason RuntimeProfiler::ShouldOptimize(JSFunction* function,
|
||||
SharedFunctionInfo* shared = function->shared();
|
||||
int ticks = function->feedback_vector()->profiler_ticks();
|
||||
|
||||
if (shared->bytecode_array()->length() > kMaxBytecodeSizeForOpt) {
|
||||
if (shared->GetBytecodeArray()->length() > kMaxBytecodeSizeForOpt) {
|
||||
return OptimizationReason::kDoNotOptimize;
|
||||
}
|
||||
|
||||
int ticks_for_optimization =
|
||||
kProfilerTicksBeforeOptimization +
|
||||
(shared->bytecode_array()->length() / kBytecodeSizeAllowancePerTick);
|
||||
(shared->GetBytecodeArray()->length() / kBytecodeSizeAllowancePerTick);
|
||||
if (ticks >= ticks_for_optimization) {
|
||||
return OptimizationReason::kHotAndStable;
|
||||
} else if (!any_ic_changed_ &&
|
||||
shared->bytecode_array()->length() < kMaxBytecodeSizeForEarlyOpt) {
|
||||
} else if (!any_ic_changed_ && shared->GetBytecodeArray()->length() <
|
||||
kMaxBytecodeSizeForEarlyOpt) {
|
||||
// If no IC was patched since the last tick and this function is very
|
||||
// small, optimistically optimize it now.
|
||||
return OptimizationReason::kSmallFunction;
|
||||
@ -220,7 +220,7 @@ OptimizationReason RuntimeProfiler::ShouldOptimize(JSFunction* function,
|
||||
PrintF("ICs changed]\n");
|
||||
} else {
|
||||
PrintF(" too large for small function optimization: %d/%d]\n",
|
||||
shared->bytecode_array()->length(), kMaxBytecodeSizeForEarlyOpt);
|
||||
shared->GetBytecodeArray()->length(), kMaxBytecodeSizeForEarlyOpt);
|
||||
}
|
||||
}
|
||||
return OptimizationReason::kDoNotOptimize;
|
||||
|
@ -53,7 +53,7 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_DebugBreakOnBytecode) {
|
||||
InterpretedFrame* interpreted_frame =
|
||||
reinterpret_cast<InterpretedFrame*>(it.frame());
|
||||
SharedFunctionInfo* shared = interpreted_frame->function()->shared();
|
||||
BytecodeArray* bytecode_array = shared->bytecode_array();
|
||||
BytecodeArray* bytecode_array = shared->GetBytecodeArray();
|
||||
int bytecode_offset = interpreted_frame->GetBytecodeOffset();
|
||||
Bytecode bytecode = Bytecodes::FromByte(bytecode_array->get(bytecode_offset));
|
||||
|
||||
|
@ -26,7 +26,7 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
|
||||
|
||||
// Underlying function needs to have bytecode available.
|
||||
DCHECK(function->shared()->HasBytecodeArray());
|
||||
int size = function->shared()->bytecode_array()->register_count();
|
||||
int size = function->shared()->GetBytecodeArray()->register_count();
|
||||
Handle<FixedArray> register_file = isolate->factory()->NewFixedArray(size);
|
||||
|
||||
Handle<JSGeneratorObject> generator =
|
||||
@ -153,7 +153,7 @@ RUNTIME_FUNCTION(Runtime_AsyncGeneratorHasCatchHandlerForPC) {
|
||||
|
||||
SharedFunctionInfo* shared = generator->function()->shared();
|
||||
DCHECK(shared->HasBytecodeArray());
|
||||
HandlerTable handler_table(shared->bytecode_array());
|
||||
HandlerTable handler_table(shared->GetBytecodeArray());
|
||||
|
||||
int pc = Smi::cast(generator->input_or_debug_pos())->value();
|
||||
HandlerTable::CatchPrediction catch_prediction = HandlerTable::ASYNC_AWAIT;
|
||||
|
@ -1352,7 +1352,7 @@ TEST(CompilationCacheCachingBehavior) {
|
||||
CHECK(shared->HasBytecodeArray());
|
||||
const int kAgingThreshold = 6;
|
||||
for (int i = 0; i < kAgingThreshold; i++) {
|
||||
shared->bytecode_array()->MakeOlder();
|
||||
shared->GetBytecodeArray()->MakeOlder();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ BytecodeExpectationsPrinter::GetBytecodeArrayForGlobal(
|
||||
i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
|
||||
|
||||
i::Handle<i::BytecodeArray> bytecodes =
|
||||
i::handle(js_function->shared()->bytecode_array(), i_isolate());
|
||||
i::handle(js_function->shared()->GetBytecodeArray(), i_isolate());
|
||||
|
||||
return bytecodes;
|
||||
}
|
||||
@ -104,15 +104,16 @@ i::Handle<i::BytecodeArray>
|
||||
BytecodeExpectationsPrinter::GetBytecodeArrayForModule(
|
||||
v8::Local<v8::Module> module) const {
|
||||
i::Handle<i::Module> i_module = v8::Utils::OpenHandle(*module);
|
||||
return i::handle(SharedFunctionInfo::cast(i_module->code())->bytecode_array(),
|
||||
i_isolate());
|
||||
return i::handle(
|
||||
SharedFunctionInfo::cast(i_module->code())->GetBytecodeArray(),
|
||||
i_isolate());
|
||||
}
|
||||
|
||||
i::Handle<i::BytecodeArray>
|
||||
BytecodeExpectationsPrinter::GetBytecodeArrayForScript(
|
||||
v8::Local<v8::Script> script) const {
|
||||
i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script);
|
||||
return i::handle(js_function->shared()->bytecode_array(), i_isolate());
|
||||
return i::handle(js_function->shared()->GetBytecodeArray(), i_isolate());
|
||||
}
|
||||
|
||||
void BytecodeExpectationsPrinter::PrintEscapedString(
|
||||
|
@ -5029,6 +5029,29 @@ TEST(InterpreterGenerators) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(InterpreterWithNativeStack) {
|
||||
i::FLAG_interpreted_frames_native_stack = true;
|
||||
|
||||
HandleAndZoneScope handles;
|
||||
i::Isolate* isolate = handles.main_isolate();
|
||||
|
||||
const char* source_text =
|
||||
"function testInterpreterWithNativeStack(a,b) { return a + b };";
|
||||
|
||||
i::Handle<i::Object> o = v8::Utils::OpenHandle(*v8_compile(source_text));
|
||||
i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
|
||||
|
||||
CHECK(f->shared()->HasBytecodeArray());
|
||||
i::Code* code = f->shared()->GetCode();
|
||||
i::Handle<i::Code> interpreter_entry_trampoline =
|
||||
BUILTIN_CODE(isolate, InterpreterEntryTrampoline);
|
||||
|
||||
CHECK(code->IsCode());
|
||||
CHECK(code->is_interpreter_trampoline_builtin());
|
||||
CHECK_NE(code->InstructionStart(),
|
||||
interpreter_entry_trampoline->InstructionStart());
|
||||
}
|
||||
|
||||
} // namespace interpreter
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -171,7 +171,7 @@ Handle<BytecodeArray> OptimizedBytecodeSourcePositionTester::MakeBytecode(
|
||||
.ToLocalChecked());
|
||||
Handle<JSFunction> function =
|
||||
Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function));
|
||||
return handle(function->shared()->bytecode_array());
|
||||
return handle(function->shared()->GetBytecodeArray());
|
||||
}
|
||||
|
||||
void OptimizedBytecodeSourcePositionTester::SetOptimizationFlags(
|
||||
|
@ -778,6 +778,29 @@ TEST(LogAll) {
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
||||
TEST(LogInterpretedFramesNativeStack) {
|
||||
SETUP_FLAGS();
|
||||
i::FLAG_interpreted_frames_native_stack = true;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
||||
|
||||
{
|
||||
ScopedLoggerInitializer logger(saved_log, saved_prof, isolate);
|
||||
|
||||
const char* source_text =
|
||||
"function testLogInterpretedFramesNativeStack(a,b) { return a + b };"
|
||||
"testLogInterpretedFramesNativeStack('1', 1);";
|
||||
CompileRun(source_text);
|
||||
|
||||
logger.StopLogging();
|
||||
|
||||
CHECK(logger.FindLine("InterpretedFunction",
|
||||
"testLogInterpretedFramesNativeStack"));
|
||||
}
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
||||
TEST(TraceMaps) {
|
||||
SETUP_FLAGS();
|
||||
i::FLAG_trace_maps = true;
|
||||
|
@ -2048,7 +2048,7 @@ TEST(CodeSerializerAfterExecute) {
|
||||
|
||||
Handle<SharedFunctionInfo> sfi = v8::Utils::OpenHandle(*script);
|
||||
CHECK(sfi->HasBytecodeArray());
|
||||
BytecodeArray* bytecode = sfi->bytecode_array();
|
||||
BytecodeArray* bytecode = sfi->GetBytecodeArray();
|
||||
CHECK_EQ(bytecode->interrupt_budget(),
|
||||
interpreter::Interpreter::InterruptBudget());
|
||||
CHECK_EQ(bytecode->osr_loop_nesting_level(), 0);
|
||||
|
@ -65,53 +65,54 @@ INSTANCE_TYPES = {
|
||||
161: "DEBUG_INFO_TYPE",
|
||||
162: "FUNCTION_TEMPLATE_INFO_TYPE",
|
||||
163: "INTERCEPTOR_INFO_TYPE",
|
||||
164: "MODULE_INFO_ENTRY_TYPE",
|
||||
165: "MODULE_TYPE",
|
||||
166: "OBJECT_TEMPLATE_INFO_TYPE",
|
||||
167: "PROMISE_CAPABILITY_TYPE",
|
||||
168: "PROMISE_REACTION_TYPE",
|
||||
169: "PROTOTYPE_INFO_TYPE",
|
||||
170: "SCRIPT_TYPE",
|
||||
171: "STACK_FRAME_INFO_TYPE",
|
||||
172: "TUPLE2_TYPE",
|
||||
173: "TUPLE3_TYPE",
|
||||
174: "WASM_COMPILED_MODULE_TYPE",
|
||||
175: "WASM_DEBUG_INFO_TYPE",
|
||||
176: "WASM_SHARED_MODULE_DATA_TYPE",
|
||||
177: "CALLABLE_TASK_TYPE",
|
||||
178: "CALLBACK_TASK_TYPE",
|
||||
179: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
|
||||
180: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
|
||||
181: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
|
||||
182: "FIXED_ARRAY_TYPE",
|
||||
183: "BOILERPLATE_DESCRIPTION_TYPE",
|
||||
184: "DESCRIPTOR_ARRAY_TYPE",
|
||||
185: "HASH_TABLE_TYPE",
|
||||
186: "SCOPE_INFO_TYPE",
|
||||
187: "TRANSITION_ARRAY_TYPE",
|
||||
188: "BLOCK_CONTEXT_TYPE",
|
||||
189: "CATCH_CONTEXT_TYPE",
|
||||
190: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||
191: "EVAL_CONTEXT_TYPE",
|
||||
192: "FUNCTION_CONTEXT_TYPE",
|
||||
193: "MODULE_CONTEXT_TYPE",
|
||||
194: "NATIVE_CONTEXT_TYPE",
|
||||
195: "SCRIPT_CONTEXT_TYPE",
|
||||
196: "WITH_CONTEXT_TYPE",
|
||||
197: "CALL_HANDLER_INFO_TYPE",
|
||||
198: "CELL_TYPE",
|
||||
199: "CODE_DATA_CONTAINER_TYPE",
|
||||
200: "FEEDBACK_CELL_TYPE",
|
||||
201: "FEEDBACK_VECTOR_TYPE",
|
||||
202: "LOAD_HANDLER_TYPE",
|
||||
203: "PROPERTY_ARRAY_TYPE",
|
||||
204: "PROPERTY_CELL_TYPE",
|
||||
205: "SHARED_FUNCTION_INFO_TYPE",
|
||||
206: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
207: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
208: "STORE_HANDLER_TYPE",
|
||||
209: "WEAK_CELL_TYPE",
|
||||
210: "WEAK_FIXED_ARRAY_TYPE",
|
||||
164: "INTERPRETER_DATA_TYPE",
|
||||
165: "MODULE_INFO_ENTRY_TYPE",
|
||||
166: "MODULE_TYPE",
|
||||
167: "OBJECT_TEMPLATE_INFO_TYPE",
|
||||
168: "PROMISE_CAPABILITY_TYPE",
|
||||
169: "PROMISE_REACTION_TYPE",
|
||||
170: "PROTOTYPE_INFO_TYPE",
|
||||
171: "SCRIPT_TYPE",
|
||||
172: "STACK_FRAME_INFO_TYPE",
|
||||
173: "TUPLE2_TYPE",
|
||||
174: "TUPLE3_TYPE",
|
||||
175: "WASM_COMPILED_MODULE_TYPE",
|
||||
176: "WASM_DEBUG_INFO_TYPE",
|
||||
177: "WASM_SHARED_MODULE_DATA_TYPE",
|
||||
178: "CALLABLE_TASK_TYPE",
|
||||
179: "CALLBACK_TASK_TYPE",
|
||||
180: "PROMISE_FULFILL_REACTION_JOB_TASK_TYPE",
|
||||
181: "PROMISE_REJECT_REACTION_JOB_TASK_TYPE",
|
||||
182: "PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE",
|
||||
183: "FIXED_ARRAY_TYPE",
|
||||
184: "BOILERPLATE_DESCRIPTION_TYPE",
|
||||
185: "DESCRIPTOR_ARRAY_TYPE",
|
||||
186: "HASH_TABLE_TYPE",
|
||||
187: "SCOPE_INFO_TYPE",
|
||||
188: "TRANSITION_ARRAY_TYPE",
|
||||
189: "BLOCK_CONTEXT_TYPE",
|
||||
190: "CATCH_CONTEXT_TYPE",
|
||||
191: "DEBUG_EVALUATE_CONTEXT_TYPE",
|
||||
192: "EVAL_CONTEXT_TYPE",
|
||||
193: "FUNCTION_CONTEXT_TYPE",
|
||||
194: "MODULE_CONTEXT_TYPE",
|
||||
195: "NATIVE_CONTEXT_TYPE",
|
||||
196: "SCRIPT_CONTEXT_TYPE",
|
||||
197: "WITH_CONTEXT_TYPE",
|
||||
198: "CALL_HANDLER_INFO_TYPE",
|
||||
199: "CELL_TYPE",
|
||||
200: "CODE_DATA_CONTAINER_TYPE",
|
||||
201: "FEEDBACK_CELL_TYPE",
|
||||
202: "FEEDBACK_VECTOR_TYPE",
|
||||
203: "LOAD_HANDLER_TYPE",
|
||||
204: "PROPERTY_ARRAY_TYPE",
|
||||
205: "PROPERTY_CELL_TYPE",
|
||||
206: "SHARED_FUNCTION_INFO_TYPE",
|
||||
207: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
208: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
209: "STORE_HANDLER_TYPE",
|
||||
210: "WEAK_CELL_TYPE",
|
||||
211: "WEAK_FIXED_ARRAY_TYPE",
|
||||
1024: "JS_PROXY_TYPE",
|
||||
1025: "JS_GLOBAL_OBJECT_TYPE",
|
||||
1026: "JS_GLOBAL_PROXY_TYPE",
|
||||
@ -160,8 +161,8 @@ KNOWN_MAPS = {
|
||||
("MAP_SPACE", 0x02201): (138, "FreeSpaceMap"),
|
||||
("MAP_SPACE", 0x02251): (132, "MetaMap"),
|
||||
("MAP_SPACE", 0x022a1): (131, "NullMap"),
|
||||
("MAP_SPACE", 0x022f1): (184, "DescriptorArrayMap"),
|
||||
("MAP_SPACE", 0x02341): (182, "FixedArrayMap"),
|
||||
("MAP_SPACE", 0x022f1): (185, "DescriptorArrayMap"),
|
||||
("MAP_SPACE", 0x02341): (183, "FixedArrayMap"),
|
||||
("MAP_SPACE", 0x02391): (152, "OnePointerFillerMap"),
|
||||
("MAP_SPACE", 0x023e1): (152, "TwoPointerFillerMap"),
|
||||
("MAP_SPACE", 0x02431): (131, "UninitializedMap"),
|
||||
@ -171,62 +172,62 @@ KNOWN_MAPS = {
|
||||
("MAP_SPACE", 0x02571): (131, "TheHoleMap"),
|
||||
("MAP_SPACE", 0x025c1): (131, "BooleanMap"),
|
||||
("MAP_SPACE", 0x02611): (136, "ByteArrayMap"),
|
||||
("MAP_SPACE", 0x02661): (182, "FixedCOWArrayMap"),
|
||||
("MAP_SPACE", 0x026b1): (185, "HashTableMap"),
|
||||
("MAP_SPACE", 0x02661): (183, "FixedCOWArrayMap"),
|
||||
("MAP_SPACE", 0x026b1): (186, "HashTableMap"),
|
||||
("MAP_SPACE", 0x02701): (128, "SymbolMap"),
|
||||
("MAP_SPACE", 0x02751): (72, "OneByteStringMap"),
|
||||
("MAP_SPACE", 0x027a1): (186, "ScopeInfoMap"),
|
||||
("MAP_SPACE", 0x027f1): (205, "SharedFunctionInfoMap"),
|
||||
("MAP_SPACE", 0x027a1): (187, "ScopeInfoMap"),
|
||||
("MAP_SPACE", 0x027f1): (206, "SharedFunctionInfoMap"),
|
||||
("MAP_SPACE", 0x02841): (133, "CodeMap"),
|
||||
("MAP_SPACE", 0x02891): (192, "FunctionContextMap"),
|
||||
("MAP_SPACE", 0x028e1): (198, "CellMap"),
|
||||
("MAP_SPACE", 0x02931): (209, "WeakCellMap"),
|
||||
("MAP_SPACE", 0x02981): (204, "GlobalPropertyCellMap"),
|
||||
("MAP_SPACE", 0x02891): (193, "FunctionContextMap"),
|
||||
("MAP_SPACE", 0x028e1): (199, "CellMap"),
|
||||
("MAP_SPACE", 0x02931): (210, "WeakCellMap"),
|
||||
("MAP_SPACE", 0x02981): (205, "GlobalPropertyCellMap"),
|
||||
("MAP_SPACE", 0x029d1): (135, "ForeignMap"),
|
||||
("MAP_SPACE", 0x02a21): (187, "TransitionArrayMap"),
|
||||
("MAP_SPACE", 0x02a71): (201, "FeedbackVectorMap"),
|
||||
("MAP_SPACE", 0x02a21): (188, "TransitionArrayMap"),
|
||||
("MAP_SPACE", 0x02a71): (202, "FeedbackVectorMap"),
|
||||
("MAP_SPACE", 0x02ac1): (131, "ArgumentsMarkerMap"),
|
||||
("MAP_SPACE", 0x02b11): (131, "ExceptionMap"),
|
||||
("MAP_SPACE", 0x02b61): (131, "TerminationExceptionMap"),
|
||||
("MAP_SPACE", 0x02bb1): (131, "OptimizedOutMap"),
|
||||
("MAP_SPACE", 0x02c01): (131, "StaleRegisterMap"),
|
||||
("MAP_SPACE", 0x02c51): (194, "NativeContextMap"),
|
||||
("MAP_SPACE", 0x02ca1): (193, "ModuleContextMap"),
|
||||
("MAP_SPACE", 0x02cf1): (191, "EvalContextMap"),
|
||||
("MAP_SPACE", 0x02d41): (195, "ScriptContextMap"),
|
||||
("MAP_SPACE", 0x02d91): (188, "BlockContextMap"),
|
||||
("MAP_SPACE", 0x02de1): (189, "CatchContextMap"),
|
||||
("MAP_SPACE", 0x02e31): (196, "WithContextMap"),
|
||||
("MAP_SPACE", 0x02e81): (190, "DebugEvaluateContextMap"),
|
||||
("MAP_SPACE", 0x02ed1): (182, "ScriptContextTableMap"),
|
||||
("MAP_SPACE", 0x02c51): (195, "NativeContextMap"),
|
||||
("MAP_SPACE", 0x02ca1): (194, "ModuleContextMap"),
|
||||
("MAP_SPACE", 0x02cf1): (192, "EvalContextMap"),
|
||||
("MAP_SPACE", 0x02d41): (196, "ScriptContextMap"),
|
||||
("MAP_SPACE", 0x02d91): (189, "BlockContextMap"),
|
||||
("MAP_SPACE", 0x02de1): (190, "CatchContextMap"),
|
||||
("MAP_SPACE", 0x02e31): (197, "WithContextMap"),
|
||||
("MAP_SPACE", 0x02e81): (191, "DebugEvaluateContextMap"),
|
||||
("MAP_SPACE", 0x02ed1): (183, "ScriptContextTableMap"),
|
||||
("MAP_SPACE", 0x02f21): (151, "FeedbackMetadataArrayMap"),
|
||||
("MAP_SPACE", 0x02f71): (182, "ArrayListMap"),
|
||||
("MAP_SPACE", 0x02f71): (183, "ArrayListMap"),
|
||||
("MAP_SPACE", 0x02fc1): (130, "BigIntMap"),
|
||||
("MAP_SPACE", 0x03011): (183, "BoilerplateDescriptionMap"),
|
||||
("MAP_SPACE", 0x03011): (184, "BoilerplateDescriptionMap"),
|
||||
("MAP_SPACE", 0x03061): (137, "BytecodeArrayMap"),
|
||||
("MAP_SPACE", 0x030b1): (199, "CodeDataContainerMap"),
|
||||
("MAP_SPACE", 0x030b1): (200, "CodeDataContainerMap"),
|
||||
("MAP_SPACE", 0x03101): (1057, "ExternalMap"),
|
||||
("MAP_SPACE", 0x03151): (150, "FixedDoubleArrayMap"),
|
||||
("MAP_SPACE", 0x031a1): (185, "GlobalDictionaryMap"),
|
||||
("MAP_SPACE", 0x031f1): (200, "ManyClosuresCellMap"),
|
||||
("MAP_SPACE", 0x031a1): (186, "GlobalDictionaryMap"),
|
||||
("MAP_SPACE", 0x031f1): (201, "ManyClosuresCellMap"),
|
||||
("MAP_SPACE", 0x03241): (1072, "JSMessageObjectMap"),
|
||||
("MAP_SPACE", 0x03291): (182, "ModuleInfoMap"),
|
||||
("MAP_SPACE", 0x03291): (183, "ModuleInfoMap"),
|
||||
("MAP_SPACE", 0x032e1): (134, "MutableHeapNumberMap"),
|
||||
("MAP_SPACE", 0x03331): (185, "NameDictionaryMap"),
|
||||
("MAP_SPACE", 0x03381): (200, "NoClosuresCellMap"),
|
||||
("MAP_SPACE", 0x033d1): (185, "NumberDictionaryMap"),
|
||||
("MAP_SPACE", 0x03421): (200, "OneClosureCellMap"),
|
||||
("MAP_SPACE", 0x03471): (185, "OrderedHashMapMap"),
|
||||
("MAP_SPACE", 0x034c1): (185, "OrderedHashSetMap"),
|
||||
("MAP_SPACE", 0x03511): (203, "PropertyArrayMap"),
|
||||
("MAP_SPACE", 0x03561): (197, "SideEffectCallHandlerInfoMap"),
|
||||
("MAP_SPACE", 0x035b1): (197, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("MAP_SPACE", 0x03601): (185, "SimpleNumberDictionaryMap"),
|
||||
("MAP_SPACE", 0x03651): (182, "SloppyArgumentsElementsMap"),
|
||||
("MAP_SPACE", 0x036a1): (206, "SmallOrderedHashMapMap"),
|
||||
("MAP_SPACE", 0x036f1): (207, "SmallOrderedHashSetMap"),
|
||||
("MAP_SPACE", 0x03741): (185, "StringTableMap"),
|
||||
("MAP_SPACE", 0x03791): (210, "WeakFixedArrayMap"),
|
||||
("MAP_SPACE", 0x03331): (186, "NameDictionaryMap"),
|
||||
("MAP_SPACE", 0x03381): (201, "NoClosuresCellMap"),
|
||||
("MAP_SPACE", 0x033d1): (186, "NumberDictionaryMap"),
|
||||
("MAP_SPACE", 0x03421): (201, "OneClosureCellMap"),
|
||||
("MAP_SPACE", 0x03471): (186, "OrderedHashMapMap"),
|
||||
("MAP_SPACE", 0x034c1): (186, "OrderedHashSetMap"),
|
||||
("MAP_SPACE", 0x03511): (204, "PropertyArrayMap"),
|
||||
("MAP_SPACE", 0x03561): (198, "SideEffectCallHandlerInfoMap"),
|
||||
("MAP_SPACE", 0x035b1): (198, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("MAP_SPACE", 0x03601): (186, "SimpleNumberDictionaryMap"),
|
||||
("MAP_SPACE", 0x03651): (183, "SloppyArgumentsElementsMap"),
|
||||
("MAP_SPACE", 0x036a1): (207, "SmallOrderedHashMapMap"),
|
||||
("MAP_SPACE", 0x036f1): (208, "SmallOrderedHashSetMap"),
|
||||
("MAP_SPACE", 0x03741): (186, "StringTableMap"),
|
||||
("MAP_SPACE", 0x03791): (211, "WeakFixedArrayMap"),
|
||||
("MAP_SPACE", 0x037e1): (106, "NativeSourceStringMap"),
|
||||
("MAP_SPACE", 0x03831): (64, "StringMap"),
|
||||
("MAP_SPACE", 0x03881): (73, "ConsOneByteStringMap"),
|
||||
@ -259,8 +260,8 @@ KNOWN_MAPS = {
|
||||
("MAP_SPACE", 0x040f1): (147, "FixedUint8ClampedArrayMap"),
|
||||
("MAP_SPACE", 0x04141): (149, "FixedBigUint64ArrayMap"),
|
||||
("MAP_SPACE", 0x04191): (148, "FixedBigInt64ArrayMap"),
|
||||
("MAP_SPACE", 0x041e1): (172, "Tuple2Map"),
|
||||
("MAP_SPACE", 0x04231): (170, "ScriptMap"),
|
||||
("MAP_SPACE", 0x041e1): (173, "Tuple2Map"),
|
||||
("MAP_SPACE", 0x04231): (171, "ScriptMap"),
|
||||
("MAP_SPACE", 0x04281): (163, "InterceptorInfoMap"),
|
||||
("MAP_SPACE", 0x042d1): (154, "AccessorInfoMap"),
|
||||
("MAP_SPACE", 0x04321): (153, "AccessCheckInfoMap"),
|
||||
@ -272,22 +273,23 @@ KNOWN_MAPS = {
|
||||
("MAP_SPACE", 0x04501): (160, "ContextExtensionMap"),
|
||||
("MAP_SPACE", 0x04551): (161, "DebugInfoMap"),
|
||||
("MAP_SPACE", 0x045a1): (162, "FunctionTemplateInfoMap"),
|
||||
("MAP_SPACE", 0x045f1): (164, "ModuleInfoEntryMap"),
|
||||
("MAP_SPACE", 0x04641): (165, "ModuleMap"),
|
||||
("MAP_SPACE", 0x04691): (166, "ObjectTemplateInfoMap"),
|
||||
("MAP_SPACE", 0x046e1): (167, "PromiseCapabilityMap"),
|
||||
("MAP_SPACE", 0x04731): (168, "PromiseReactionMap"),
|
||||
("MAP_SPACE", 0x04781): (169, "PrototypeInfoMap"),
|
||||
("MAP_SPACE", 0x047d1): (171, "StackFrameInfoMap"),
|
||||
("MAP_SPACE", 0x04821): (173, "Tuple3Map"),
|
||||
("MAP_SPACE", 0x04871): (174, "WasmCompiledModuleMap"),
|
||||
("MAP_SPACE", 0x048c1): (175, "WasmDebugInfoMap"),
|
||||
("MAP_SPACE", 0x04911): (176, "WasmSharedModuleDataMap"),
|
||||
("MAP_SPACE", 0x04961): (177, "CallableTaskMap"),
|
||||
("MAP_SPACE", 0x049b1): (178, "CallbackTaskMap"),
|
||||
("MAP_SPACE", 0x04a01): (179, "PromiseFulfillReactionJobTaskMap"),
|
||||
("MAP_SPACE", 0x04a51): (180, "PromiseRejectReactionJobTaskMap"),
|
||||
("MAP_SPACE", 0x04aa1): (181, "PromiseResolveThenableJobTaskMap"),
|
||||
("MAP_SPACE", 0x045f1): (164, "InterpreterDataMap"),
|
||||
("MAP_SPACE", 0x04641): (165, "ModuleInfoEntryMap"),
|
||||
("MAP_SPACE", 0x04691): (166, "ModuleMap"),
|
||||
("MAP_SPACE", 0x046e1): (167, "ObjectTemplateInfoMap"),
|
||||
("MAP_SPACE", 0x04731): (168, "PromiseCapabilityMap"),
|
||||
("MAP_SPACE", 0x04781): (169, "PromiseReactionMap"),
|
||||
("MAP_SPACE", 0x047d1): (170, "PrototypeInfoMap"),
|
||||
("MAP_SPACE", 0x04821): (172, "StackFrameInfoMap"),
|
||||
("MAP_SPACE", 0x04871): (174, "Tuple3Map"),
|
||||
("MAP_SPACE", 0x048c1): (175, "WasmCompiledModuleMap"),
|
||||
("MAP_SPACE", 0x04911): (176, "WasmDebugInfoMap"),
|
||||
("MAP_SPACE", 0x04961): (177, "WasmSharedModuleDataMap"),
|
||||
("MAP_SPACE", 0x049b1): (178, "CallableTaskMap"),
|
||||
("MAP_SPACE", 0x04a01): (179, "CallbackTaskMap"),
|
||||
("MAP_SPACE", 0x04a51): (180, "PromiseFulfillReactionJobTaskMap"),
|
||||
("MAP_SPACE", 0x04aa1): (181, "PromiseRejectReactionJobTaskMap"),
|
||||
("MAP_SPACE", 0x04af1): (182, "PromiseResolveThenableJobTaskMap"),
|
||||
}
|
||||
|
||||
# List of known V8 objects.
|
||||
|
Loading…
Reference in New Issue
Block a user