Commit a207b640 authored by jyan's avatar jyan Committed by Commit bot

PPC/S390: [Interpreter] Remove InterpreterExitTrampoline and replace with...

PPC/S390: [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline.

port 39738bc9

Original Commit Message:
  In order to support compiling to baseline on return we need to be able to
  return to the actual return address. With this change this is what the
  Return bytecode now does, removing the need for the
  InterpreterExitTrampoline.

  This change also removes the InterpreterNotifyDeoptXXX builtins and
  unifies FCG and Igntion to both use NotifyDeoptXXX. As part of this
  change, FullCodegenerator::State is moved to Deoptimize::BailoutState.

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/1989983002
Cr-Commit-Position: refs/heads/master@{#36336}
parent 0aa3707d
This diff is collapsed.
This diff is collapsed.
......@@ -1074,8 +1074,19 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ LoadPX(ip, MemOperand(kInterpreterDispatchTableRegister, ip));
__ Call(ip);
// Even though the first bytecode handler was called, we will never return.
__ Abort(kUnexpectedReturnFromBytecodeHandler);
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);
__ blr();
// If the bytecode array is no longer present, then the underlying function
// has been switched to a different kind of code and we heal the closure by
......@@ -1091,20 +1102,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
}
void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
// The return value is in accumulator, which is already in r3.
// Leave the frame (also dropping the register file).
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
// Drop receiver + arguments and return.
__ lwz(r0, FieldMemOperand(kInterpreterBytecodeArrayRegister,
BytecodeArray::kParameterSizeOffset));
__ add(sp, sp, r0);
__ blr();
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register count, Register scratch) {
Label loop;
......@@ -1116,7 +1113,6 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
__ bdnz(&loop);
}
// static
void Builtins::Generate_InterpreterPushArgsAndCallImpl(
MacroAssembler* masm, TailCallMode tail_call_mode) {
......@@ -1140,7 +1136,6 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl(
RelocInfo::CODE_TARGET);
}
// static
void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
// ----------- S t a t e -------------
......@@ -1165,8 +1160,17 @@ void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
// Set the return address to the correct point in the interpreter entry
// trampoline.
Smi* interpreter_entry_return_pc_offset(
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
__ Move(r5, masm->isolate()->builtins()->InterpreterEntryTrampoline());
__ addi(r0, r5, Operand(interpreter_entry_return_pc_offset->value() +
Code::kHeaderSize - kHeapObjectTag));
__ mtlr(r0);
static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
// Initialize the dispatch table register.
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
......@@ -1199,56 +1203,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
}
static void Generate_InterpreterNotifyDeoptimizedHelper(
MacroAssembler* masm, Deoptimizer::BailoutType type) {
// Enter an internal frame.
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass the deoptimization type to the runtime system.
__ LoadSmiLiteral(r4, Smi::FromInt(static_cast<int>(type)));
__ Push(r4);
__ CallRuntime(Runtime::kNotifyDeoptimized);
// Tear down internal frame.
}
// Drop state (we don't use these for interpreter deopts) and and pop the
// accumulator value into the accumulator register.
__ Drop(1);
__ Pop(kInterpreterAccumulatorRegister);
// Enter the bytecode dispatch.
Generate_EnterBytecodeDispatch(masm);
}
void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
}
void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
}
void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
// Set the address of the interpreter entry trampoline as a return address.
// This simulates the initial call to bytecode handlers in interpreter entry
// trampoline. The return will never actually be taken, but our stack walker
// uses this address to determine whether a frame is interpreted.
__ mov(r0,
Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline()));
__ mtlr(r0);
Generate_EnterBytecodeDispatch(masm);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r3 : argument count (preserved for callee)
......@@ -1541,14 +1495,17 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
__ SmiUntag(r9);
// Switch on the state.
Label with_tos_register, unknown_state;
__ cmpi(r9, Operand(FullCodeGenerator::NO_REGISTERS));
__ cmpi(r9,
Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
__ bne(&with_tos_register);
__ addi(sp, sp, Operand(1 * kPointerSize)); // Remove state.
__ Ret();
__ bind(&with_tos_register);
DCHECK_EQ(kInterpreterAccumulatorRegister.code(), r3.code());
__ LoadP(r3, MemOperand(sp, 1 * kPointerSize));
__ cmpi(r9, Operand(FullCodeGenerator::TOS_REG));
__ cmpi(r9,
Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
__ bne(&unknown_state);
__ addi(sp, sp, Operand(2 * kPointerSize)); // Remove state.
__ Ret();
......
......@@ -1064,8 +1064,19 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ LoadP(ip, MemOperand(kInterpreterDispatchTableRegister, ip));
__ Call(ip);
// Even though the first bytecode handler was called, we will never return.
__ Abort(kUnexpectedReturnFromBytecodeHandler);
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));
__ Ret();
// If the bytecode array is no longer present, then the underlying function
// has been switched to a different kind of code and we heal the closure by
......@@ -1080,19 +1091,6 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
__ JumpToJSEntry(r6);
}
void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
// The return value is in accumulator, which is already in r2.
// Leave the frame (also dropping the register file).
__ LeaveFrame(StackFrame::JAVA_SCRIPT);
// Drop receiver + arguments and return.
__ LoadlW(r0, FieldMemOperand(kInterpreterBytecodeArrayRegister,
BytecodeArray::kParameterSizeOffset));
__ AddP(sp, sp, r0);
__ Ret();
}
static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index,
Register count, Register scratch) {
Label loop;
......@@ -1153,7 +1151,16 @@ void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
__ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
}
static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
// Set the return address to the correct point in the interpreter entry
// trampoline.
Smi* interpreter_entry_return_pc_offset(
masm->isolate()->heap()->interpreter_entry_return_pc_offset());
DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
__ Move(r4, masm->isolate()->builtins()->InterpreterEntryTrampoline());
__ AddP(r14, r4, Operand(interpreter_entry_return_pc_offset->value() +
Code::kHeaderSize - kHeapObjectTag));
// Initialize the dispatch table register.
__ mov(kInterpreterDispatchTableRegister,
Operand(ExternalReference::interpreter_dispatch_table_address(
......@@ -1185,51 +1192,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
__ Jump(ip);
}
static void Generate_InterpreterNotifyDeoptimizedHelper(
MacroAssembler* masm, Deoptimizer::BailoutType type) {
// Enter an internal frame.
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass the deoptimization type to the runtime system.
__ LoadSmiLiteral(r3, Smi::FromInt(static_cast<int>(type)));
__ Push(r3);
__ CallRuntime(Runtime::kNotifyDeoptimized);
// Tear down internal frame.
}
// Drop state (we don't use these for interpreter deopts) and and pop the
// accumulator value into the accumulator register.
__ Drop(1);
__ Pop(kInterpreterAccumulatorRegister);
// Enter the bytecode dispatch.
Generate_EnterBytecodeDispatch(masm);
}
void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
}
void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
}
void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
}
void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
// Set the address of the interpreter entry trampoline as a return address.
// This simulates the initial call to bytecode handlers in interpreter entry
// trampoline. The return will never actually be taken, but our stack walker
// uses this address to determine whether a frame is interpreted.
__ mov(r14,
Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline()));
Generate_EnterBytecodeDispatch(masm);
}
void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r2 : argument count (preserved for callee)
......@@ -1517,14 +1479,17 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
__ SmiUntag(r8);
// Switch on the state.
Label with_tos_register, unknown_state;
__ CmpP(r8, Operand(FullCodeGenerator::NO_REGISTERS));
__ CmpP(r8,
Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
__ bne(&with_tos_register);
__ la(sp, MemOperand(sp, 1 * kPointerSize)); // Remove state.
__ Ret();
__ bind(&with_tos_register);
DCHECK_EQ(kInterpreterAccumulatorRegister.code(), r2.code());
__ LoadP(r2, MemOperand(sp, 1 * kPointerSize));
__ CmpP(r8, Operand(FullCodeGenerator::TOS_REG));
__ CmpP(r8,
Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
__ bne(&unknown_state);
__ la(sp, MemOperand(sp, 2 * kPointerSize)); // Remove state.
__ Ret();
......
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