Commit 6e5671e1 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[nojit] Embed InterpreterEntryTrampoline

This marks the InterpreterEntryTrampoline as isolate-independent. With
this change, all builtins are now embedded.

Slight changes were needed to how we deopt into the trampoline. We now
store the entry address within the Interpreter class instead of
embedding the builtin code target.

Bug: v8:7777
Change-Id: If781bf6f06cb2efbab1369ece757f04c343a1b38
Reviewed-on: https://chromium-review.googlesource.com/c/1337734Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57563}
parent ca38b84b
...@@ -924,9 +924,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { ...@@ -924,9 +924,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
// handler at the current bytecode offset. // handler at the current bytecode offset.
Label do_dispatch; Label do_dispatch;
__ bind(&do_dispatch); __ bind(&do_dispatch);
__ mov(kInterpreterDispatchTableRegister, __ Move(
Operand(ExternalReference::interpreter_dispatch_table_address( kInterpreterDispatchTableRegister,
masm->isolate()))); ExternalReference::interpreter_dispatch_table_address(masm->isolate()));
__ ldrb(r4, MemOperand(kInterpreterBytecodeArrayRegister, __ ldrb(r4, MemOperand(kInterpreterBytecodeArrayRegister,
kInterpreterBytecodeOffsetRegister)); kInterpreterBytecodeOffsetRegister));
__ ldr( __ ldr(
...@@ -1088,8 +1088,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1088,8 +1088,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); __ ldr(r2, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ ldr(r2, FieldMemOperand(r2, JSFunction::kSharedFunctionInfoOffset)); __ ldr(r2, FieldMemOperand(r2, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kFunctionDataOffset)); __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1100,14 +1102,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1100,14 +1102,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ ldr(r2, __ ldr(r2,
FieldMemOperand(r2, InterpreterData::kInterpreterTrampolineOffset)); FieldMemOperand(r2, InterpreterData::kInterpreterTrampolineOffset));
__ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
__ b(&trampoline_loaded); __ b(&trampoline_loaded);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ Move(r2, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ Move(r2, ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()));
__ ldr(r2, MemOperand(r2));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() + __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
// Initialize the dispatch table register. // Initialize the dispatch table register.
__ Move( __ Move(
......
...@@ -1226,8 +1226,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1226,8 +1226,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ Ldr(x1, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); __ Ldr(x1, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Ldr(x1, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); __ Ldr(x1, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(x1, FieldMemOperand(x1, SharedFunctionInfo::kFunctionDataOffset)); __ Ldr(x1, FieldMemOperand(x1, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1238,14 +1240,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1238,14 +1240,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ Ldr(x1, __ Ldr(x1,
FieldMemOperand(x1, InterpreterData::kInterpreterTrampolineOffset)); FieldMemOperand(x1, InterpreterData::kInterpreterTrampolineOffset));
__ Add(x1, x1, Operand(Code::kHeaderSize - kHeapObjectTag));
__ B(&trampoline_loaded); __ B(&trampoline_loaded);
__ Bind(&builtin_trampoline); __ Bind(&builtin_trampoline);
__ LoadObject(x1, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ Mov(x1, ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()));
__ Ldr(x1, MemOperand(x1));
__ Bind(&trampoline_loaded); __ Bind(&trampoline_loaded);
__ Add(lr, x1, Operand(interpreter_entry_return_pc_offset->value() + __ Add(lr, x1, Operand(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
// Initialize the dispatch table register. // Initialize the dispatch table register.
__ Mov( __ Mov(
......
...@@ -220,23 +220,6 @@ bool Builtins::IsIsolateIndependentBuiltin(const Code code) { ...@@ -220,23 +220,6 @@ bool Builtins::IsIsolateIndependentBuiltin(const Code code) {
} }
} }
// static
bool Builtins::IsIsolateIndependent(int index) {
DCHECK(IsBuiltinId(index));
switch (index) {
// TODO(jgruber): InterpreterEnterBytecode calculates a pointer into the
// middle of InterpreterEntryTrampoline (see
// interpreter_entry_return_pc_offset). When the builtin is embedded, the
// pointer would need to be calculated at an offset from the embedded
// instruction stream (instead of the trampoline code object).
case kInterpreterEntryTrampoline:
return false;
default:
return true;
}
UNREACHABLE();
}
// static // static
bool Builtins::IsWasmRuntimeStub(int index) { bool Builtins::IsWasmRuntimeStub(int index) {
DCHECK(IsBuiltinId(index)); DCHECK(IsBuiltinId(index));
......
...@@ -123,9 +123,9 @@ class Builtins { ...@@ -123,9 +123,9 @@ class Builtins {
kNumberOfWideBytecodeHandlers == kNumberOfWideBytecodeHandlers ==
builtin_count); builtin_count);
// Helper methods used for testing isolate-independent builtins. // True, iff the given builtin contains no isolate-specific code and can be
// TODO(jgruber,v8:6666): Remove once all builtins have been migrated. // embedded into the binary.
static bool IsIsolateIndependent(int index); static bool IsIsolateIndependent(int index) { return true; }
// Wasm runtime stubs are treated specially by wasm. To guarantee reachability // Wasm runtime stubs are treated specially by wasm. To guarantee reachability
// through near jumps, their code is completely copied into a fresh off-heap // through near jumps, their code is completely copied into a fresh off-heap
......
...@@ -1189,8 +1189,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1189,8 +1189,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
static constexpr Register scratch = ecx; static constexpr Register scratch = ecx;
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ mov(scratch, Operand(ebp, StandardFrameConstants::kFunctionOffset)); __ mov(scratch, Operand(ebp, StandardFrameConstants::kFunctionOffset));
__ mov(scratch, FieldOperand(scratch, JSFunction::kSharedFunctionInfoOffset)); __ mov(scratch, FieldOperand(scratch, JSFunction::kSharedFunctionInfoOffset));
__ mov(scratch, __ mov(scratch,
...@@ -1201,15 +1203,20 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1201,15 +1203,20 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ mov(scratch, __ mov(scratch,
FieldOperand(scratch, InterpreterData::kInterpreterTrampolineOffset)); FieldOperand(scratch, InterpreterData::kInterpreterTrampolineOffset));
__ add(scratch, Immediate(Code::kHeaderSize - kHeapObjectTag));
__ jmp(&trampoline_loaded, Label::kNear); __ jmp(&trampoline_loaded, Label::kNear);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ Move(scratch, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ mov(scratch,
__ ExternalReferenceAsOperand(
ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()),
scratch));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ Pop(eax); __ Pop(eax);
__ add(scratch, Immediate(interpreter_entry_return_pc_offset->value() + __ add(scratch, Immediate(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
__ push(scratch); __ push(scratch);
// Initialize the dispatch table register. // Initialize the dispatch table register.
......
...@@ -1072,8 +1072,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1072,8 +1072,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero()); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero());
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ lw(t0, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); __ lw(t0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ lw(t0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset)); __ lw(t0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset)); __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1083,14 +1085,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1083,14 +1085,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
Operand(INTERPRETER_DATA_TYPE)); Operand(INTERPRETER_DATA_TYPE));
__ lw(t0, FieldMemOperand(t0, InterpreterData::kInterpreterTrampolineOffset)); __ lw(t0, FieldMemOperand(t0, InterpreterData::kInterpreterTrampolineOffset));
__ Addu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Branch(&trampoline_loaded); __ Branch(&trampoline_loaded);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ li(t0, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ li(t0, ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()));
__ lw(t0, MemOperand(t0));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ Addu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() + __ Addu(ra, t0, Operand(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
// Initialize the dispatch table register. // Initialize the dispatch table register.
__ li(kInterpreterDispatchTableRegister, __ li(kInterpreterDispatchTableRegister,
......
...@@ -1071,8 +1071,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1071,8 +1071,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero()); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero());
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ Ld(t0, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); __ Ld(t0, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Ld(t0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset)); __ Ld(t0, FieldMemOperand(t0, JSFunction::kSharedFunctionInfoOffset));
__ Ld(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset)); __ Ld(t0, FieldMemOperand(t0, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1082,14 +1084,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1082,14 +1084,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
Operand(INTERPRETER_DATA_TYPE)); Operand(INTERPRETER_DATA_TYPE));
__ Ld(t0, FieldMemOperand(t0, InterpreterData::kInterpreterTrampolineOffset)); __ Ld(t0, FieldMemOperand(t0, InterpreterData::kInterpreterTrampolineOffset));
__ Daddu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Branch(&trampoline_loaded); __ Branch(&trampoline_loaded);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ li(t0, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ li(t0, ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()));
__ Ld(t0, MemOperand(t0));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ Daddu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() + __ Daddu(ra, t0, Operand(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
// Initialize the dispatch table register. // Initialize the dispatch table register.
__ li(kInterpreterDispatchTableRegister, __ li(kInterpreterDispatchTableRegister,
......
...@@ -1119,8 +1119,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1119,8 +1119,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero()); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero());
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ LoadP(r5, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ LoadP(r5, FieldMemOperand(r5, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r5, FieldMemOperand(r5, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r5, FieldMemOperand(r5, SharedFunctionInfo::kFunctionDataOffset)); __ LoadP(r5, FieldMemOperand(r5, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1131,14 +1133,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1131,14 +1133,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ LoadP(r5, __ LoadP(r5,
FieldMemOperand(r5, InterpreterData::kInterpreterTrampolineOffset)); FieldMemOperand(r5, InterpreterData::kInterpreterTrampolineOffset));
__ addi(r5, r5, Operand(Code::kHeaderSize - kHeapObjectTag));
__ b(&trampoline_loaded); __ b(&trampoline_loaded);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ Move(r5, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ Move(r5, ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()));
__ LoadP(r5, MemOperand(r5));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ addi(r0, r5, Operand(interpreter_entry_return_pc_offset->value() + __ addi(r0, r5, Operand(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
__ mtlr(r0); __ mtlr(r0);
// Initialize the dispatch table register. // Initialize the dispatch table register.
......
...@@ -1124,8 +1124,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1124,8 +1124,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero()); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::zero());
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kFunctionOffset)); __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ LoadP(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ LoadP(r4, FieldMemOperand(r4, SharedFunctionInfo::kFunctionDataOffset)); __ LoadP(r4, FieldMemOperand(r4, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1136,14 +1138,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1136,14 +1138,17 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ LoadP(r4, __ LoadP(r4,
FieldMemOperand(r4, InterpreterData::kInterpreterTrampolineOffset)); FieldMemOperand(r4, InterpreterData::kInterpreterTrampolineOffset));
__ AddP(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
__ b(&trampoline_loaded); __ b(&trampoline_loaded);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ Move(r4, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ Move(r4, ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()));
__ LoadP(r4, MemOperand(r4));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ AddP(r14, r4, Operand(interpreter_entry_return_pc_offset->value() + __ AddP(r14, r4, Operand(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
// Initialize the dispatch table register. // Initialize the dispatch table register.
__ Move( __ Move(
......
...@@ -1146,8 +1146,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1146,8 +1146,10 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
masm->isolate()->heap()->interpreter_entry_return_pc_offset()); masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero); DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
// If the SFI function_data is an InterpreterData, get the trampoline stored // If the SFI function_data is an InterpreterData, the function will have a
// in it, otherwise get the trampoline from the builtins list. // custom copy of the interpreter entry trampoline for profiling. If so,
// get the custom trampoline, otherwise grab the entry address of the global
// trampoline.
__ movp(rbx, Operand(rbp, StandardFrameConstants::kFunctionOffset)); __ movp(rbx, Operand(rbp, StandardFrameConstants::kFunctionOffset));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset)); __ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset)); __ movp(rbx, FieldOperand(rbx, SharedFunctionInfo::kFunctionDataOffset));
...@@ -1156,14 +1158,19 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) { ...@@ -1156,14 +1158,19 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
__ movp(rbx, __ movp(rbx,
FieldOperand(rbx, InterpreterData::kInterpreterTrampolineOffset)); FieldOperand(rbx, InterpreterData::kInterpreterTrampolineOffset));
__ addp(rbx, Immediate(Code::kHeaderSize - kHeapObjectTag));
__ jmp(&trampoline_loaded, Label::kNear); __ jmp(&trampoline_loaded, Label::kNear);
__ bind(&builtin_trampoline); __ bind(&builtin_trampoline);
__ Move(rbx, BUILTIN_CODE(masm->isolate(), InterpreterEntryTrampoline)); __ movp(rbx,
__ ExternalReferenceAsOperand(
ExternalReference::
address_of_interpreter_entry_trampoline_instruction_start(
masm->isolate()),
kScratchRegister));
__ bind(&trampoline_loaded); __ bind(&trampoline_loaded);
__ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value() + __ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value()));
Code::kHeaderSize - kHeapObjectTag));
__ Push(rbx); __ Push(rbx);
// Initialize dispatch table register. // Initialize dispatch table register.
......
...@@ -146,6 +146,14 @@ ExternalReference ExternalReference::interpreter_dispatch_counters( ...@@ -146,6 +146,14 @@ ExternalReference ExternalReference::interpreter_dispatch_counters(
isolate->interpreter()->bytecode_dispatch_counters_table()); isolate->interpreter()->bytecode_dispatch_counters_table());
} }
ExternalReference
ExternalReference::address_of_interpreter_entry_trampoline_instruction_start(
Isolate* isolate) {
return ExternalReference(
isolate->interpreter()
->address_of_interpreter_entry_trampoline_instruction_start());
}
ExternalReference ExternalReference::bytecode_size_table_address() { ExternalReference ExternalReference::bytecode_size_table_address() {
return ExternalReference( return ExternalReference(
interpreter::Bytecodes::bytecode_size_table_address()); interpreter::Bytecodes::bytecode_size_table_address());
......
...@@ -27,6 +27,8 @@ class StatsCounter; ...@@ -27,6 +27,8 @@ class StatsCounter;
V(builtins_address, "builtins") \ V(builtins_address, "builtins") \
V(handle_scope_implementer_address, \ V(handle_scope_implementer_address, \
"Isolate::handle_scope_implementer_address") \ "Isolate::handle_scope_implementer_address") \
V(address_of_interpreter_entry_trampoline_instruction_start, \
"Address of the InterpreterEntryTrampoline instruction start") \
V(interpreter_dispatch_counters, "Interpreter::dispatch_counters") \ V(interpreter_dispatch_counters, "Interpreter::dispatch_counters") \
V(interpreter_dispatch_table_address, "Interpreter::dispatch_table_address") \ V(interpreter_dispatch_table_address, "Interpreter::dispatch_table_address") \
V(date_cache_stamp, "date_cache_stamp") \ V(date_cache_stamp, "date_cache_stamp") \
......
...@@ -50,7 +50,9 @@ class InterpreterCompilationJob final : public UnoptimizedCompilationJob { ...@@ -50,7 +50,9 @@ class InterpreterCompilationJob final : public UnoptimizedCompilationJob {
DISALLOW_COPY_AND_ASSIGN(InterpreterCompilationJob); DISALLOW_COPY_AND_ASSIGN(InterpreterCompilationJob);
}; };
Interpreter::Interpreter(Isolate* isolate) : isolate_(isolate) { Interpreter::Interpreter(Isolate* isolate)
: isolate_(isolate),
interpreter_entry_trampoline_instruction_start_(kNullAddress) {
memset(dispatch_table_, 0, sizeof(dispatch_table_)); memset(dispatch_table_, 0, sizeof(dispatch_table_));
if (FLAG_trace_ignition_dispatches) { if (FLAG_trace_ignition_dispatches) {
...@@ -251,8 +253,17 @@ void Interpreter::ForEachBytecode( ...@@ -251,8 +253,17 @@ void Interpreter::ForEachBytecode(
} }
} }
void Interpreter::InitializeDispatchTable() { void Interpreter::Initialize() {
Builtins* builtins = isolate_->builtins(); Builtins* builtins = isolate_->builtins();
// Set the interpreter entry trampoline entry point now that builtins are
// initialized.
Handle<Code> code = BUILTIN_CODE(isolate_, InterpreterEntryTrampoline);
DCHECK(builtins->is_initialized());
DCHECK(code->is_off_heap_trampoline() || Heap::IsImmovable(*code));
interpreter_entry_trampoline_instruction_start_ = code->InstructionStart();
// Initialize the dispatch table.
Code illegal = builtins->builtin(Builtins::kIllegalHandler); Code illegal = builtins->builtin(Builtins::kIllegalHandler);
int builtin_id = Builtins::kFirstBytecodeHandler; int builtin_id = Builtins::kFirstBytecodeHandler;
ForEachBytecode([=, &builtin_id](Bytecode bytecode, ForEachBytecode([=, &builtin_id](Bytecode bytecode,
......
...@@ -66,7 +66,7 @@ class Interpreter { ...@@ -66,7 +66,7 @@ class Interpreter {
void ForEachBytecode(const std::function<void(Bytecode, OperandScale)>& f); void ForEachBytecode(const std::function<void(Bytecode, OperandScale)>& f);
void InitializeDispatchTable(); void Initialize();
bool IsDispatchTableInitialized() const; bool IsDispatchTableInitialized() const;
...@@ -78,6 +78,11 @@ class Interpreter { ...@@ -78,6 +78,11 @@ class Interpreter {
return reinterpret_cast<Address>(bytecode_dispatch_counters_table_.get()); return reinterpret_cast<Address>(bytecode_dispatch_counters_table_.get());
} }
Address address_of_interpreter_entry_trampoline_instruction_start() const {
return reinterpret_cast<Address>(
&interpreter_entry_trampoline_instruction_start_);
}
private: private:
friend class SetupInterpreter; friend class SetupInterpreter;
friend class v8::internal::SetupIsolateDelegate; friend class v8::internal::SetupIsolateDelegate;
...@@ -95,6 +100,7 @@ class Interpreter { ...@@ -95,6 +100,7 @@ class Interpreter {
Isolate* isolate_; Isolate* isolate_;
Address dispatch_table_[kDispatchTableSize]; Address dispatch_table_[kDispatchTableSize];
std::unique_ptr<uintptr_t[]> bytecode_dispatch_counters_table_; std::unique_ptr<uintptr_t[]> bytecode_dispatch_counters_table_;
Address interpreter_entry_trampoline_instruction_start_;
DISALLOW_COPY_AND_ASSIGN(Interpreter); DISALLOW_COPY_AND_ASSIGN(Interpreter);
}; };
......
...@@ -3328,7 +3328,7 @@ bool Isolate::Init(StartupDeserializer* des) { ...@@ -3328,7 +3328,7 @@ bool Isolate::Init(StartupDeserializer* des) {
if (!create_heap_objects) des->DeserializeInto(this); if (!create_heap_objects) des->DeserializeInto(this);
load_stub_cache_->Initialize(); load_stub_cache_->Initialize();
store_stub_cache_->Initialize(); store_stub_cache_->Initialize();
interpreter_->InitializeDispatchTable(); interpreter_->Initialize();
heap_.NotifyDeserializationComplete(); heap_.NotifyDeserializationComplete();
} }
delete setup_delegate_; delete setup_delegate_;
......
...@@ -5001,8 +5001,7 @@ TEST(InterpreterWithNativeStack) { ...@@ -5001,8 +5001,7 @@ TEST(InterpreterWithNativeStack) {
CHECK(code->IsCode()); CHECK(code->IsCode());
CHECK(code->is_interpreter_trampoline_builtin()); CHECK(code->is_interpreter_trampoline_builtin());
CHECK_NE(code->InstructionStart(), CHECK_NE(code->address(), interpreter_entry_trampoline->address());
interpreter_entry_trampoline->InstructionStart());
} }
TEST(InterpreterGetBytecodeHandler) { TEST(InterpreterGetBytecodeHandler) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment