Index: src/x64/builtins-x64.cc |
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc |
index a14fdf5b184a324196b06d39472a72fbe601d37d..bb9d56079b1223656c3068ad4285b6b8eff7d04c 100644 |
--- a/src/x64/builtins-x64.cc |
+++ b/src/x64/builtins-x64.cc |
@@ -725,22 +725,59 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
__ jmp(rcx); |
} |
- |
void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
// The return value is in accumulator, which is already in rax. |
- // Leave the frame (also dropping the register file). |
+ // Save the interpreter frame's function and callee pc to check if it has |
+ // been marked for baseline compilation on return. |
+ __ movp(rcx, Operand(rsp, 0)); |
+ __ movp(rdi, Operand(rbp, StandardFrameConstants::kFunctionOffset)); |
+ |
+ // Leave the frame (also dropping the register file). Do this before checking |
+ // for baseline compile so that we don't count as an activation on the stack. |
__ leave(); |
+ // Check if the function has been marked for baseline compilation on return. |
+ Label not_marked_for_baseline; |
+ ExternalReference external(Builtins::kInterpreterMarkBaselineOnReturn, |
+ masm->isolate()); |
+ __ movp(rbx, masm->ExternalOperand(external)); |
+ __ leap(rbx, FieldOperand(rbx, Code::kHeaderSize)); |
+ __ cmpp(rcx, rbx); |
+ __ j(not_equal, ¬_marked_for_baseline, Label::kNear); |
+ |
+ { |
+ FrameScope frame_scope(masm, StackFrame::INTERNAL); |
+ // Push bytecode array and rax for return. |
+ __ Push(kInterpreterBytecodeArrayRegister); |
+ __ Push(rax); |
+ |
+ // Push function as argument and compile for baseline. |
+ __ Push(rdi); |
+ __ CallRuntime(Runtime::kCompileBaseline); |
+ |
+ // Restore bytecode array and rax. |
+ __ Pop(rax); |
+ __ Pop(kInterpreterBytecodeArrayRegister); |
+ } |
+ |
+ __ bind(¬_marked_for_baseline); |
+ |
// Drop receiver + arguments and return. |
__ movl(rbx, FieldOperand(kInterpreterBytecodeArrayRegister, |
BytecodeArray::kParameterSizeOffset)); |
__ PopReturnAddressTo(rcx); |
__ addp(rsp, rbx); |
__ PushReturnAddressFrom(rcx); |
+ |
__ ret(0); |
} |
+void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) { |
+ // This builtin is only used as a marker to be checked in |
+ // InterpreterExitTrampoline and should never be called itself. |
+ __ Abort(kUnexpectedCallToMarkBaselineOnReturn); |
+} |
static void Generate_InterpreterPushArgs(MacroAssembler* masm, |
bool push_receiver) { |