Commit 31ac67ee authored by jyan's avatar jyan Committed by Commit bot

PPC/S390: [Interpreter] Support compiling for baseline on return from interpreted function.

port f241a61a

Original Commit Message:
    We cannot tier up from interpreted to baseline code when there is an
    activation of the function on the stack. This significantly regresses
    the performance of recursive functions since they are unlikely to get
    tiered up.

    This CL adds the ability for a function to be marked for baseline
    compilation when it returns. To do this we patch the
    InterpreterEntryTrampoline return address to point to
    InterpreterMarkBaselineOnReturn, which leaves the
    interpreted frame and recompile the function for
    baseline.

    This improves the score of EarlyBoyer by ~8x for Ignition.

R=rmcilroy@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com
BUG=v8:4280
LOG=N

Review-Url: https://codereview.chromium.org/1993343002
Cr-Commit-Position: refs/heads/master@{#36384}
parent fd39fdc5
......@@ -968,6 +968,20 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
Generate_JSEntryTrampolineHelper(masm, true);
}
static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
Register args_count = scratch;
// Get the arguments + receiver count.
__ LoadP(args_count,
MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
__ lwz(args_count,
FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
// Leave the frame (also dropping the register file).
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
__ add(sp, sp, args_count);
}
// Generate code for entering a JS function with the interpreter.
// On entry to the function the receiver and arguments have been pushed on the
......@@ -1077,15 +1091,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
// The return value is in r3.
// Get the arguments + reciever count.
__ LoadP(r5, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
__ lwz(r5, FieldMemOperand(r5, BytecodeArray::kParameterSizeOffset));
// Leave the frame (also dropping the register file).
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
__ add(sp, sp, r5);
LeaveInterpreterFrame(masm, r5);
__ blr();
// If the bytecode array is no longer present, then the underlying function
......@@ -1101,6 +1107,30 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ JumpToJSEntry(r7);
}
void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
// Save the function and context for call to CompileBaseline.
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ LoadP(kContextRegister,
MemOperand(fp, StandardFrameConstants::kContextOffset));
// Leave the frame before recompiling for baseline so that we don't count as
// an activation on the stack.
LeaveInterpreterFrame(masm, r5);
{
FrameScope frame_scope(masm, StackFrame::INTERNAL);
// Push return value.
__ push(r3);
// Push function as argument and compile for baseline.
__ push(r4);
__ CallRuntime(Runtime::kCompileBaseline);
// Restore return value.
__ pop(r3);
}
__ blr();
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register count, Register scratch) {
......
......@@ -957,6 +957,21 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
Generate_JSEntryTrampolineHelper(masm, true);
}
static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
Register args_count = scratch;
// Get the arguments + receiver count.
__ LoadP(args_count,
MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
__ LoadlW(args_count,
FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
// Leave the frame (also dropping the register file).
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
__ AddP(sp, sp, args_count);
}
// Generate code for entering a JS function with the interpreter.
// On entry to the function the receiver and arguments have been pushed on the
// stack left to right. The actual argument count matches the formal parameter
......@@ -1067,15 +1082,7 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
// The return value is in r2.
// Get the arguments + reciever count.
__ LoadP(r4, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
__ LoadlW(r4, FieldMemOperand(r4, BytecodeArray::kParameterSizeOffset));
// Leave the frame (also dropping the register file).
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
__ lay(sp, MemOperand(sp, r4));
LeaveInterpreterFrame(masm, r4);
__ Ret();
// If the bytecode array is no longer present, then the underlying function
......@@ -1091,6 +1098,31 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ JumpToJSEntry(r6);
}
void Builtins::Generate_InterpreterMarkBaselineOnReturn(MacroAssembler* masm) {
// Save the function and context for call to CompileBaseline.
__ LoadP(r3, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ LoadP(kContextRegister,
MemOperand(fp, StandardFrameConstants::kContextOffset));
// Leave the frame before recompiling for baseline so that we don't count as
// an activation on the stack.
LeaveInterpreterFrame(masm, r4);
{
FrameScope frame_scope(masm, StackFrame::INTERNAL);
// Push return value.
__ push(r2);
// Push function as argument and compile for baseline.
__ push(r3);
__ CallRuntime(Runtime::kCompileBaseline);
// Restore return value.
__ pop(r2);
}
__ Ret();
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register count, Register scratch) {
Label loop;
......
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