From c473f2931d83fd8f77c4ea8a57e7f10abec02712 Mon Sep 17 00:00:00 2001 From: machenbach Date: Tue, 17 May 2016 12:44:12 -0700 Subject: [PATCH] Revert of [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. (patchset #6 id:170001 of https://codereview.chromium.org/1969423002/ ) Reason for revert: Breaks https://build.chromium.org/p/client.v8.ports/builders/V8%20Linux%20-%20arm%20-%20sim/builds/619 Might only affect pure release builds? Original issue's description: > [Interpreter] Remove InterpreterExitTrampoline and replace with returning to the entry trampoline. > > 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. > > BUG=v8:4280 > LOG=N > > Committed: https://crrev.com/34c9626e2ee56fe805de549697ca5323aed7cb66 > Cr-Commit-Position: refs/heads/master@{#36288} TBR=mstarzinger@chromium.org,oth@chromium.org,rmcilroy@chromium.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:4280 Review-Url: https://codereview.chromium.org/1986353002 Cr-Commit-Position: refs/heads/master@{#36294} --- src/arm/builtins-arm.cc | 98 ++++++-- src/arm64/builtins-arm64.cc | 233 +++++++++++------- src/bailout-reason.h | 2 + src/builtins.h | 10 +- src/deoptimizer.cc | 43 ++-- src/deoptimizer.h | 16 -- src/full-codegen/arm/full-codegen-arm.cc | 132 +++++----- src/full-codegen/arm64/full-codegen-arm64.cc | 132 +++++----- src/full-codegen/full-codegen.cc | 87 ++++--- src/full-codegen/full-codegen.h | 33 ++- src/full-codegen/ia32/full-codegen-ia32.cc | 132 +++++----- src/full-codegen/mips/full-codegen-mips.cc | 132 +++++----- .../mips64/full-codegen-mips64.cc | 132 +++++----- src/full-codegen/x64/full-codegen-x64.cc | 132 +++++----- src/heap/heap-inl.h | 8 +- src/heap/heap.h | 5 +- src/ia32/builtins-ia32.cc | 104 +++++--- src/interpreter/bytecodes.cc | 5 - src/interpreter/bytecodes.h | 5 +- src/interpreter/interpreter-assembler.cc | 9 +- src/interpreter/interpreter-assembler.h | 4 +- src/interpreter/interpreter.cc | 4 +- src/mips/builtins-mips.cc | 98 ++++++-- src/mips64/builtins-mips64.cc | 99 ++++++-- src/objects.cc | 5 +- src/x64/builtins-x64.cc | 106 +++++--- .../interpreter-assembler-unittest.cc | 26 ++ 27 files changed, 992 insertions(+), 800 deletions(-) diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc index 031b483cca..8e47025430 100644 --- a/src/arm/builtins-arm.cc +++ b/src/arm/builtins-arm.cc @@ -959,6 +959,7 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { Generate_JSEntryTrampolineHelper(masm, true); } + // 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 @@ -1059,19 +1060,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL, kPointerSizeLog2)); __ Call(ip); - masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); - // The return value is in r0. - - // Get the arguments + reciever count. - __ ldr(r2, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ ldr(r2, FieldMemOperand(r2, BytecodeArray::kParameterSizeOffset)); - - // Leave the frame (also dropping the register file). - __ LeaveFrame(StackFrame::JAVA_SCRIPT); - - __ add(sp, sp, r2, LeaveCC); - __ Jump(lr); + // Even though the first bytecode handler was called, we will never return. + __ Abort(kUnexpectedReturnFromBytecodeHandler); // 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 @@ -1086,6 +1077,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Jump(r4); } + +void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { + // The return value is in accumulator, which is already in r0. + + // Leave the frame (also dropping the register file). + __ LeaveFrame(StackFrame::JAVA_SCRIPT); + + // Drop receiver + arguments and return. + __ ldr(ip, FieldMemOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kParameterSizeOffset)); + __ add(sp, sp, ip, LeaveCC); + __ Jump(lr); +} + + static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index, Register limit, Register scratch) { Label loop_header, loop_check; @@ -1098,6 +1104,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register index, __ b(gt, &loop_header); } + // static void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode) { @@ -1123,6 +1130,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( RelocInfo::CODE_TARGET); } + // static void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { // ----------- S t a t e ------------- @@ -1147,16 +1155,8 @@ 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(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline()); - __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() + - Code::kHeaderSize - kHeapObjectTag)); +static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { // Initialize the dispatch table register. __ mov(kInterpreterDispatchTableRegister, Operand(ExternalReference::interpreter_dispatch_table_address( @@ -1188,6 +1188,55 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { __ mov(pc, ip); } + +static void Generate_InterpreterNotifyDeoptimizedHelper( + MacroAssembler* masm, Deoptimizer::BailoutType type) { + // Enter an internal frame. + { + FrameScope scope(masm, StackFrame::INTERNAL); + + // Pass the deoptimization type to the runtime system. + __ mov(r1, Operand(Smi::FromInt(static_cast(type)))); + __ push(r1); + __ 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. + __ Move(lr, masm->isolate()->builtins()->InterpreterEntryTrampoline()); + + Generate_EnterBytecodeDispatch(masm); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- r0 : argument count (preserved for callee) @@ -1477,17 +1526,14 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, __ SmiUntag(r6); // Switch on the state. Label with_tos_register, unknown_state; - __ cmp(r6, - Operand(static_cast(Deoptimizer::BailoutState::NO_REGISTERS))); + __ cmp(r6, Operand(FullCodeGenerator::NO_REGISTERS)); __ b(ne, &with_tos_register); __ add(sp, sp, Operand(1 * kPointerSize)); // Remove state. __ Ret(); __ bind(&with_tos_register); - DCHECK_EQ(kInterpreterAccumulatorRegister.code(), r0.code()); __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); - __ cmp(r6, - Operand(static_cast(Deoptimizer::BailoutState::TOS_REGISTER))); + __ cmp(r6, Operand(FullCodeGenerator::TOS_REG)); __ b(ne, &unknown_state); __ add(sp, sp, Operand(2 * kPointerSize)); // Remove state. __ Ret(); diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc index be372e65a6..71419cd90d 100644 --- a/src/arm64/builtins-arm64.cc +++ b/src/arm64/builtins-arm64.cc @@ -963,6 +963,7 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { Generate_JSEntryTrampolineHelper(masm, true); } + // 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 @@ -1061,20 +1062,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Mov(x1, Operand(x1, LSL, kPointerSizeLog2)); __ Ldr(ip0, MemOperand(kInterpreterDispatchTableRegister, x1)); __ Call(ip0); - masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); - // The return value is in x0. - - // Get the arguments + reciever count. - __ ldr(x1, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ Ldr(w1, FieldMemOperand(x1, BytecodeArray::kParameterSizeOffset)); - - // Leave the frame (also dropping the register file). - __ LeaveFrame(StackFrame::JAVA_SCRIPT); - - // Drop receiver + arguments and return. - __ Drop(x1, 1); - __ Ret(); + // Even though the first bytecode handler was called, we will never return. + __ Abort(kUnexpectedReturnFromBytecodeHandler); // Load debug copy of the bytecode array. __ Bind(&load_debug_bytecode_array); @@ -1095,87 +1085,22 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Jump(x7); } -// static -void Builtins::Generate_InterpreterPushArgsAndCallImpl( - MacroAssembler* masm, TailCallMode tail_call_mode) { - // ----------- S t a t e ------------- - // -- x0 : the number of arguments (not including the receiver) - // -- x2 : the address of the first argument to be pushed. Subsequent - // arguments should be consecutive above this, in the same order as - // they are to be pushed onto the stack. - // -- x1 : the target to call (can be any Object). - // ----------------------------------- - // Find the address of the last argument. - __ add(x3, x0, Operand(1)); // Add one for receiver. - __ lsl(x3, x3, kPointerSizeLog2); - __ sub(x4, x2, x3); +void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { + // The return value is in accumulator, which is already in x0. - // Push the arguments. - Label loop_header, loop_check; - __ Mov(x5, jssp); - __ Claim(x3, 1); - __ B(&loop_check); - __ Bind(&loop_header); - // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned. - __ Ldr(x3, MemOperand(x2, -kPointerSize, PostIndex)); - __ Str(x3, MemOperand(x5, -kPointerSize, PreIndex)); - __ Bind(&loop_check); - __ Cmp(x2, x4); - __ B(gt, &loop_header); + // Leave the frame (also dropping the register file). + __ LeaveFrame(StackFrame::JAVA_SCRIPT); - // Call the target. - __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, - tail_call_mode), - RelocInfo::CODE_TARGET); + // Drop receiver + arguments and return. + __ Ldr(w1, FieldMemOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kParameterSizeOffset)); + __ Drop(x1, 1); + __ Ret(); } -// static -void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { - // ----------- S t a t e ------------- - // -- x0 : argument count (not including receiver) - // -- x3 : new target - // -- x1 : constructor to call - // -- x2 : address of the first argument - // ----------------------------------- - - // Find the address of the last argument. - __ add(x5, x0, Operand(1)); // Add one for receiver (to be constructed). - __ lsl(x5, x5, kPointerSizeLog2); - - // Set stack pointer and where to stop. - __ Mov(x6, jssp); - __ Claim(x5, 1); - __ sub(x4, x6, x5); - - // Push a slot for the receiver. - __ Str(xzr, MemOperand(x6, -kPointerSize, PreIndex)); - - Label loop_header, loop_check; - // Push the arguments. - __ B(&loop_check); - __ Bind(&loop_header); - // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned. - __ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex)); - __ Str(x5, MemOperand(x6, -kPointerSize, PreIndex)); - __ Bind(&loop_check); - __ Cmp(x6, x4); - __ B(gt, &loop_header); - - // Call the constructor with x0, x1, and x3 unmodified. - __ 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)); - __ LoadObject(x1, masm->isolate()->builtins()->InterpreterEntryTrampoline()); - __ Add(lr, x1, Operand(interpreter_entry_return_pc_offset->value() + - Code::kHeaderSize - kHeapObjectTag)); +static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { // Initialize the dispatch table register. __ Mov(kInterpreterDispatchTableRegister, Operand(ExternalReference::interpreter_dispatch_table_address( @@ -1207,6 +1132,55 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { __ Jump(ip0); } + +static void Generate_InterpreterNotifyDeoptimizedHelper( + MacroAssembler* masm, Deoptimizer::BailoutType type) { + // Enter an internal frame. + { + FrameScope scope(masm, StackFrame::INTERNAL); + + // Pass the deoptimization type to the runtime system. + __ Mov(x1, Operand(Smi::FromInt(static_cast(type)))); + __ Push(x1); + __ 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. + __ LoadObject(lr, masm->isolate()->builtins()->InterpreterEntryTrampoline()); + + Generate_EnterBytecodeDispatch(masm); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- x0 : argument count (preserved for callee) @@ -1495,19 +1469,15 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, // Switch on the state. Label with_tos_register, unknown_state; - __ CompareAndBranch(state, - static_cast(Deoptimizer::BailoutState::NO_REGISTERS), - ne, &with_tos_register); + __ CompareAndBranch( + state, FullCodeGenerator::NO_REGISTERS, ne, &with_tos_register); __ Drop(1); // Remove state. __ Ret(); __ Bind(&with_tos_register); // Reload TOS register. - DCHECK_EQ(kInterpreterAccumulatorRegister.code(), x0.code()); __ Peek(x0, kPointerSize); - __ CompareAndBranch(state, - static_cast(Deoptimizer::BailoutState::TOS_REGISTER), - ne, &unknown_state); + __ CompareAndBranch(state, FullCodeGenerator::TOS_REG, ne, &unknown_state); __ Drop(2); // Remove state and TOS. __ Ret(); @@ -2684,6 +2654,79 @@ void Builtins::Generate_Construct(MacroAssembler* masm) { RelocInfo::CODE_TARGET); } + +// static +void Builtins::Generate_InterpreterPushArgsAndCallImpl( + MacroAssembler* masm, TailCallMode tail_call_mode) { + // ----------- S t a t e ------------- + // -- x0 : the number of arguments (not including the receiver) + // -- x2 : the address of the first argument to be pushed. Subsequent + // arguments should be consecutive above this, in the same order as + // they are to be pushed onto the stack. + // -- x1 : the target to call (can be any Object). + // ----------------------------------- + + // Find the address of the last argument. + __ add(x3, x0, Operand(1)); // Add one for receiver. + __ lsl(x3, x3, kPointerSizeLog2); + __ sub(x4, x2, x3); + + // Push the arguments. + Label loop_header, loop_check; + __ Mov(x5, jssp); + __ Claim(x3, 1); + __ B(&loop_check); + __ Bind(&loop_header); + // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned. + __ Ldr(x3, MemOperand(x2, -kPointerSize, PostIndex)); + __ Str(x3, MemOperand(x5, -kPointerSize, PreIndex)); + __ Bind(&loop_check); + __ Cmp(x2, x4); + __ B(gt, &loop_header); + + // Call the target. + __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, + tail_call_mode), + RelocInfo::CODE_TARGET); +} + + +// static +void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { + // ----------- S t a t e ------------- + // -- x0 : argument count (not including receiver) + // -- x3 : new target + // -- x1 : constructor to call + // -- x2 : address of the first argument + // ----------------------------------- + + // Find the address of the last argument. + __ add(x5, x0, Operand(1)); // Add one for receiver (to be constructed). + __ lsl(x5, x5, kPointerSizeLog2); + + // Set stack pointer and where to stop. + __ Mov(x6, jssp); + __ Claim(x5, 1); + __ sub(x4, x6, x5); + + // Push a slot for the receiver. + __ Str(xzr, MemOperand(x6, -kPointerSize, PreIndex)); + + Label loop_header, loop_check; + // Push the arguments. + __ B(&loop_check); + __ Bind(&loop_header); + // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned. + __ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex)); + __ Str(x5, MemOperand(x6, -kPointerSize, PreIndex)); + __ Bind(&loop_check); + __ Cmp(x6, x4); + __ B(gt, &loop_header); + + // Call the constructor with x0, x1, and x3 unmodified. + __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); +} + // static void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) { ASM_LOCATION("Builtins::Generate_AllocateInNewSpace"); diff --git a/src/bailout-reason.h b/src/bailout-reason.h index c1ec24cbd4..5b2cb0f6a1 100644 --- a/src/bailout-reason.h +++ b/src/bailout-reason.h @@ -253,6 +253,8 @@ namespace internal { V(kUnsupportedPhiUseOfArguments, "Unsupported phi use of arguments") \ V(kUnsupportedPhiUseOfConstVariable, \ "Unsupported phi use of const or let variable") \ + V(kUnexpectedReturnFromBytecodeHandler, \ + "Unexpectedly returned from a bytecode handler") \ V(kUnexpectedReturnFromThrow, "Unexpectedly returned from a throw") \ V(kUnsupportedSwitchStatement, "Unsupported switch statement") \ V(kUnsupportedTaggedImmediate, "Unsupported tagged immediate") \ diff --git a/src/builtins.h b/src/builtins.h index 2488f90c33..1e09ecceed 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -237,9 +237,13 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) { V(NotifyStubFailureSaveDoubles, BUILTIN, UNINITIALIZED, kNoExtraICState) \ \ V(InterpreterEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterExitTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterPushArgsAndCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterPushArgsAndTailCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterPushArgsAndConstruct, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterNotifyDeoptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterNotifySoftDeoptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ + V(InterpreterNotifyLazyDeoptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ V(InterpreterEnterBytecodeDispatch, BUILTIN, UNINITIALIZED, kNoExtraICState) \ \ V(LoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ @@ -656,7 +660,7 @@ class Builtins { static void Generate_StackCheck(MacroAssembler* masm); static void Generate_InterpreterEntryTrampoline(MacroAssembler* masm); - static void Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm); + static void Generate_InterpreterExitTrampoline(MacroAssembler* masm); static void Generate_InterpreterPushArgsAndCall(MacroAssembler* masm) { return Generate_InterpreterPushArgsAndCallImpl(masm, TailCallMode::kDisallow); @@ -667,6 +671,10 @@ class Builtins { static void Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode); static void Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm); + static void Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm); + static void Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm); + static void Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm); + static void Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm); #define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \ static void Generate_Make##C##CodeYoungAgainEvenMarking( \ diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index adf4cf1296..9719eb5b22 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -848,8 +848,9 @@ void Deoptimizer::DoComputeOutputFrames() { " @%d => node=%d, pc=0x%08" V8PRIxPTR ", caller sp=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n", bailout_id_, node_id.ToInt(), output_[index]->GetPc(), - caller_frame_top_, BailoutStateToString(static_cast( - output_[index]->GetState()->value())), + caller_frame_top_, FullCodeGenerator::State2String( + static_cast( + output_[index]->GetState()->value())), ms); } } @@ -1061,11 +1062,10 @@ void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame, // If we are going to the catch handler, then the exception lives in // the accumulator. - BailoutState state = - goto_catch_handler - ? BailoutState::TOS_REGISTER - : FullCodeGenerator::BailoutStateField::decode(pc_and_state); - output_frame->SetState(Smi::FromInt(static_cast(state))); + FullCodeGenerator::State state = + goto_catch_handler ? FullCodeGenerator::TOS_REG + : FullCodeGenerator::StateField::decode(pc_and_state); + output_frame->SetState(Smi::FromInt(state)); // Set the continuation for the topmost frame. if (is_topmost) { @@ -1281,9 +1281,7 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, Code* dispatch_builtin = builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); output_frame->SetPc(reinterpret_cast(dispatch_builtin->entry())); - // Restore accumulator (TOS) register. - output_frame->SetState( - Smi::FromInt(static_cast(BailoutState::TOS_REGISTER))); + output_frame->SetState(0); // Update constant pool. if (FLAG_enable_embedded_constant_pool) { @@ -1299,11 +1297,14 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, // Set the continuation for the topmost frame. if (is_topmost) { - Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); + Code* continuation = + builtins->builtin(Builtins::kInterpreterNotifyDeoptimized); if (bailout_type_ == LAZY) { - continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); + continuation = + builtins->builtin(Builtins::kInterpreterNotifyLazyDeoptimized); } else if (bailout_type_ == SOFT) { - continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); + continuation = + builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized); } else { CHECK_EQ(bailout_type_, EAGER); } @@ -1517,7 +1518,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame, // value of result register is preserved during continuation execution. // We do this here by "pushing" the result of the constructor function to the // top of the reconstructed stack and then using the - // BailoutState::TOS_REGISTER machinery. + // FullCodeGenerator::TOS_REG machinery. if (is_topmost) { height_in_bytes += kPointerSize; } @@ -1638,8 +1639,7 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame, DebugPrintOutputSlot(value, frame_index, output_offset, "constructor result\n"); - output_frame->SetState( - Smi::FromInt(static_cast(BailoutState::TOS_REGISTER))); + output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG)); } CHECK_EQ(0u, output_offset); @@ -1693,7 +1693,7 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame, // value of result register is preserved during continuation execution. // We do this here by "pushing" the result of the accessor function to the // top of the reconstructed stack and then using the - // BailoutState::TOS_REGISTER machinery. + // FullCodeGenerator::TOS_REG machinery. // We don't need to restore the result in case of a setter call because we // have to return the stored value but not the result of the setter function. bool should_preserve_result = is_topmost && !is_setter_stub_frame; @@ -1812,11 +1812,9 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame, DebugPrintOutputSlot(value, frame_index, output_offset, "accessor result\n"); - output_frame->SetState( - Smi::FromInt(static_cast(BailoutState::TOS_REGISTER))); + output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG)); } else { - output_frame->SetState( - Smi::FromInt(static_cast(BailoutState::NO_REGISTERS))); + output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); } CHECK_EQ(0u, output_offset); @@ -2071,8 +2069,7 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame, output_frame->SetConstantPool(constant_pool_value); output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); } - output_frame->SetState( - Smi::FromInt(static_cast(BailoutState::NO_REGISTERS))); + output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); Code* notify_failure = isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); output_frame->SetContinuation( diff --git a/src/deoptimizer.h b/src/deoptimizer.h index 1d413e6bab..ae65e0070f 100644 --- a/src/deoptimizer.h +++ b/src/deoptimizer.h @@ -402,22 +402,6 @@ class Deoptimizer : public Malloced { public: enum BailoutType { EAGER, LAZY, SOFT, kLastBailoutType = SOFT }; - enum class BailoutState { - NO_REGISTERS, - TOS_REGISTER, - }; - - static const char* BailoutStateToString(BailoutState state) { - switch (state) { - case BailoutState::NO_REGISTERS: - return "NO_REGISTERS"; - case BailoutState::TOS_REGISTER: - return "TOS_REGISTER"; - } - UNREACHABLE(); - return nullptr; - } - #define DEOPT_MESSAGES_CONSTANTS(C, T) C, enum DeoptReason { DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_CONSTANTS) kLastDeoptReason diff --git a/src/full-codegen/arm/full-codegen-arm.cc b/src/full-codegen/arm/full-codegen-arm.cc index 91253e3fd2..1ee6205019 100644 --- a/src/full-codegen/arm/full-codegen-arm.cc +++ b/src/full-codegen/arm/full-codegen-arm.cc @@ -176,8 +176,7 @@ void FullCodeGenerator::Generate() { __ push(r1); __ Push(info->scope()->GetScopeInfo(info->isolate())); __ CallRuntime(Runtime::kNewScriptContext); - PrepareForBailoutForId(BailoutId::ScriptContext(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); // The new target value is not used, clobbering is safe. DCHECK_NULL(info->scope()->new_target_var()); } else { @@ -233,8 +232,7 @@ void FullCodeGenerator::Generate() { // Register holding this function and new target are both trashed in case we // bailout here. But since that can happen only when new target is not used // and we allocate a context, the value of |function_in_register| is correct. - PrepareForBailoutForId(BailoutId::FunctionContext(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. @@ -296,8 +294,7 @@ void FullCodeGenerator::Generate() { } // Visit the declarations and body. - PrepareForBailoutForId(BailoutId::FunctionEntry(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); { Comment cmnt(masm_, "[ Declarations"); VisitDeclarations(scope()->declarations()); @@ -310,8 +307,7 @@ void FullCodeGenerator::Generate() { { Comment cmnt(masm_, "[ Stack check"); - PrepareForBailoutForId(BailoutId::Declarations(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); Label ok; __ LoadRoot(ip, Heap::kStackLimitRootIndex); __ cmp(sp, Operand(ip)); @@ -409,11 +405,11 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, EmitProfilingCounterReset(); __ bind(&ok); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR // entry becomes the target of a bailout. We don't expect it to be, but // we want it to work if it is. - PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); } void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( @@ -735,7 +731,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, Label skip; if (should_normalize) __ b(&skip); - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); if (should_normalize) { __ LoadRoot(ip, Heap::kTrueValueRootIndex); __ cmp(r0, ip); @@ -793,7 +789,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ LoadRoot(r0, Heap::kTheHoleValueRootIndex); __ str(r0, ContextMemOperand(cp, variable->index())); // No write barrier since the_hole_value is in old space. - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); } break; @@ -814,7 +810,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ Push(r2, r0); __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); __ CallRuntime(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -860,7 +856,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } @@ -872,7 +868,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( VisitForStackValue(declaration->fun()); PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -904,7 +900,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Keep the switch value on the stack until a case matches. VisitForStackValue(stmt->tag()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); ZoneList* clauses = stmt->cases(); CaseClause* default_clause = NULL; // Can occur anywhere in the list. @@ -953,7 +949,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Label skip; __ b(&skip); - PrepareForBailout(clause, BailoutState::TOS_REGISTER); + PrepareForBailout(clause, TOS_REG); __ LoadRoot(ip, Heap::kTrueValueRootIndex); __ cmp(r0, ip); __ b(ne, &next_test); @@ -982,12 +978,12 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ Case body"); CaseClause* clause = clauses->at(i); __ bind(clause->body_target()); - PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); VisitStatements(clause->statements()); } __ bind(nested_statement.break_label()); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -1020,7 +1016,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { ToObjectStub stub(isolate()); __ CallStub(&stub); __ bind(&done_convert); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); __ push(r0); // Check cache validity in generated code. If we cannot guarantee cache @@ -1040,7 +1036,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ bind(&call_runtime); __ push(r0); // Duplicate the enumerable object on the stack. __ CallRuntime(Runtime::kForInEnumerate); - PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->EnumId(), TOS_REG); // If we got a map from the runtime call, we can do a fast // modification check. Otherwise, we got a fixed array, and we have @@ -1081,7 +1077,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Push(r1, r0); // Smi and array __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset)); __ Push(r1); // Fixed array length (as smi). - PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); __ mov(r0, Operand(Smi::FromInt(0))); __ Push(r0); // Initial index. @@ -1123,7 +1119,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ push(r1); // Enumerable. __ push(r3); // Current entry. __ CallRuntime(Runtime::kForInFilter); - PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->FilterId(), TOS_REG); __ mov(r3, Operand(r0)); __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); __ cmp(r0, ip); @@ -1136,11 +1132,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); - PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1159,7 +1155,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { DropOperands(5); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(&exit); decrement_loop_depth(); } @@ -1318,7 +1314,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { // Record position before possible IC call. SetExpressionPosition(proxy); - PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); Variable* var = proxy->var(); // Three cases: global variables, lookup variables, and all other types of @@ -1425,7 +1421,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ CallStub(&stub); RestoreContext(); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); // If result_saved is true the result is on top of the stack. If // result_saved is false the result is in r0. @@ -1461,7 +1457,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); EmitLoadStoreICSlot(property->GetSlot(0)); CallStoreIC(); - PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(key->id(), NO_REGISTERS); if (NeedsHomeObject(value)) { EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); @@ -1495,7 +1491,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); break; case ObjectLiteral::Property::GETTER: @@ -1553,7 +1549,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); } else { EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); VisitForStackValue(value); @@ -1626,7 +1622,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); bool result_saved = false; // Is the result saved to the stack? ZoneList* subexprs = expr->values(); @@ -1656,8 +1652,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } // In case the array literal contains spread expressions it has two parts. The @@ -1677,8 +1672,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForStackValue(subexpr); CallRuntimeWithOperands(Runtime::kAppendElement); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } if (result_saved) { @@ -1761,27 +1755,23 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { switch (assign_type) { case VARIABLE: EmitVariableLoad(expr->target()->AsVariableProxy()); - PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->target(), TOS_REG); break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case NAMED_SUPER_PROPERTY: EmitNamedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_SUPER_PROPERTY: EmitKeyedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_PROPERTY: EmitKeyedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; } } @@ -1801,7 +1791,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { } // Deoptimization point in case the binary operation may have side effects. - PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->binary_operation(), TOS_REG); } else { VisitForAccumulatorValue(expr->value()); } @@ -1813,7 +1803,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), expr->op(), expr->AssignmentSlot()); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(r0); break; case NAMED_PROPERTY: @@ -2281,7 +2271,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(r0); } @@ -2326,7 +2316,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(r0); } @@ -2350,7 +2340,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); - PrepareForBailout(callee, BailoutState::NO_REGISTERS); + PrepareForBailout(callee, NO_REGISTERS); } // Push undefined as receiver. This is patched in the method prologue if it // is a sloppy mode method. @@ -2363,8 +2353,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { DCHECK(!callee->AsProperty()->IsSuperAccess()); __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. __ ldr(ip, MemOperand(sp, 0)); PushOperand(ip); @@ -2403,7 +2392,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ str(r0, MemOperand(sp, kPointerSize)); @@ -2428,8 +2417,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); __ Move(LoadDescriptor::NameRegister(), r0); EmitKeyedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. __ ldr(ip, MemOperand(sp, 0)); @@ -2465,7 +2453,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ str(r0, MemOperand(sp, kPointerSize)); @@ -2485,7 +2473,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); SetCallPosition(expr, expr->tail_call_mode()); if (expr->tail_call_mode() == TailCallMode::kAllow) { if (FLAG_trace) { @@ -2553,7 +2541,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { __ Push(callee->name()); __ CallRuntime(Runtime::kLoadLookupSlotForCall); PushOperands(r0, r1); // Function, receiver. - PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); // If fast case code has been generated, emit code to push the // function and receiver and have the slow path jump around this @@ -2602,7 +2590,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { // Touch up the stack with the resolved function. __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); - PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); // Record source position for debugger. SetCallPosition(expr); @@ -2652,7 +2640,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { CallConstructStub stub(isolate()); __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); OperandStackDepthDecrement(arg_count + 1); - PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ReturnId(), TOS_REG); RestoreContext(); context()->Plug(r0); } @@ -3085,7 +3073,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to r1. int const argc = args->length() - 2; __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); @@ -3289,14 +3277,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { &materialize_true); if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); __ bind(&materialize_true); - PrepareForBailoutForId(expr->MaterializeTrueId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); __ LoadRoot(r0, Heap::kTrueValueRootIndex); if (context()->IsStackValue()) __ push(r0); __ jmp(&done); __ bind(&materialize_false); - PrepareForBailoutForId(expr->MaterializeFalseId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); __ LoadRoot(r0, Heap::kFalseValueRootIndex); if (context()->IsStackValue()) __ push(r0); __ bind(&done); @@ -3398,9 +3384,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // We need a second deoptimization point after loading the value // in case evaluating the property load my have a side effect. if (assign_type == VARIABLE) { - PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->expression(), TOS_REG); } else { - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); } // Inline smi case if we are in a loop. @@ -3449,7 +3435,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Convert old value into a number. ToNumberStub convert_stub(isolate()); __ CallStub(&convert_stub); - PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); // Save result for postfix expressions. if (expr->is_postfix()) { @@ -3496,8 +3482,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { { EffectContext context(this); EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context.Plug(r0); } // For all contexts except EffectConstant We have the result on @@ -3508,8 +3493,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } else { EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(r0); } break; @@ -3519,7 +3503,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->CountSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); @@ -3558,7 +3542,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->CountSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); diff --git a/src/full-codegen/arm64/full-codegen-arm64.cc b/src/full-codegen/arm64/full-codegen-arm64.cc index 61cb141e19..ccf57e291e 100644 --- a/src/full-codegen/arm64/full-codegen-arm64.cc +++ b/src/full-codegen/arm64/full-codegen-arm64.cc @@ -179,8 +179,7 @@ void FullCodeGenerator::Generate() { __ Mov(x10, Operand(info->scope()->GetScopeInfo(info->isolate()))); __ Push(x1, x10); __ CallRuntime(Runtime::kNewScriptContext); - PrepareForBailoutForId(BailoutId::ScriptContext(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); // The new target value is not used, clobbering is safe. DCHECK_NULL(info->scope()->new_target_var()); } else { @@ -236,8 +235,7 @@ void FullCodeGenerator::Generate() { // Register holding this function and new target are both trashed in case we // bailout here. But since that can happen only when new target is not used // and we allocate a context, the value of |function_in_register| is correct. - PrepareForBailoutForId(BailoutId::FunctionContext(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. @@ -299,8 +297,7 @@ void FullCodeGenerator::Generate() { } // Visit the declarations and body. - PrepareForBailoutForId(BailoutId::FunctionEntry(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); { Comment cmnt(masm_, "[ Declarations"); VisitDeclarations(scope()->declarations()); @@ -313,8 +310,7 @@ void FullCodeGenerator::Generate() { { Comment cmnt(masm_, "[ Stack check"); - PrepareForBailoutForId(BailoutId::Declarations(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); Label ok; DCHECK(jssp.Is(__ StackPointer())); __ CompareRoot(jssp, Heap::kStackLimitRootIndex); @@ -397,11 +393,11 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, EmitProfilingCounterReset(); __ Bind(&ok); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR // entry becomes the target of a bailout. We don't expect it to be, but // we want it to work if it is. - PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); } void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( @@ -732,7 +728,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, if (should_normalize) { __ B(&skip); } - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); if (should_normalize) { __ CompareRoot(x0, Heap::kTrueValueRootIndex); Split(eq, if_true, if_false, NULL); @@ -790,7 +786,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ LoadRoot(x10, Heap::kTheHoleValueRootIndex); __ Str(x10, ContextMemOperand(cp, variable->index())); // No write barrier since the_hole_value is in old space. - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); } break; @@ -812,7 +808,7 @@ void FullCodeGenerator::VisitVariableDeclaration( } __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); __ CallRuntime(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -858,7 +854,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } @@ -870,7 +866,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( VisitForStackValue(declaration->fun()); PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -907,7 +903,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Keep the switch value on the stack until a case matches. VisitForStackValue(stmt->tag()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); ZoneList* clauses = stmt->cases(); CaseClause* default_clause = NULL; // Can occur anywhere in the list. @@ -954,7 +950,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Label skip; __ B(&skip); - PrepareForBailout(clause, BailoutState::TOS_REGISTER); + PrepareForBailout(clause, TOS_REG); __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); __ Drop(1); __ B(clause->body_target()); @@ -980,12 +976,12 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ Case body"); CaseClause* clause = clauses->at(i); __ Bind(clause->body_target()); - PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); VisitStatements(clause->statements()); } __ Bind(nested_statement.break_label()); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -1018,7 +1014,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { ToObjectStub stub(isolate()); __ CallStub(&stub); __ Bind(&done_convert); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); __ Push(x0); // Check cache validity in generated code. If we cannot guarantee cache @@ -1038,7 +1034,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Bind(&call_runtime); __ Push(x0); // Duplicate the enumerable object on the stack. __ CallRuntime(Runtime::kForInEnumerate); - PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->EnumId(), TOS_REG); // If we got a map from the runtime call, we can do a fast // modification check. Otherwise, we got a fixed array, and we have @@ -1074,7 +1070,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Mov(x1, Smi::FromInt(1)); // Smi(1) indicates slow check. __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); __ Push(x1, x0, x2); // Smi and array, fixed array length (as smi). - PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); __ Push(xzr); // Initial index. // Generate code for doing the condition check. @@ -1114,7 +1110,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // just skip it. __ Push(x1, x3); __ CallRuntime(Runtime::kForInFilter); - PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->FilterId(), TOS_REG); __ Mov(x3, x0); __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, loop_statement.continue_label()); @@ -1126,11 +1122,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); - PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1150,7 +1146,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { DropOperands(5); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ Bind(&exit); decrement_loop_depth(); } @@ -1303,7 +1299,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { // Record position before possible IC call. SetExpressionPosition(proxy); - PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); Variable* var = proxy->var(); // Three cases: global variables, lookup variables, and all other types of @@ -1411,7 +1407,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ CallStub(&stub); RestoreContext(); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); // If result_saved is true the result is on top of the stack. If // result_saved is false the result is in x0. @@ -1447,7 +1443,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ Peek(StoreDescriptor::ReceiverRegister(), 0); EmitLoadStoreICSlot(property->GetSlot(0)); CallStoreIC(); - PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(key->id(), NO_REGISTERS); if (NeedsHomeObject(value)) { EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); @@ -1480,7 +1476,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { VisitForStackValue(value); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); break; case ObjectLiteral::Property::GETTER: if (property->emit_store()) { @@ -1537,7 +1533,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); } else { EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); VisitForStackValue(value); @@ -1608,7 +1604,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); bool result_saved = false; // Is the result saved to the stack? ZoneList* subexprs = expr->values(); @@ -1638,8 +1634,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } // In case the array literal contains spread expressions it has two parts. The @@ -1659,8 +1654,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForStackValue(subexpr); CallRuntimeWithOperands(Runtime::kAppendElement); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } if (result_saved) { @@ -1740,27 +1734,23 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { switch (assign_type) { case VARIABLE: EmitVariableLoad(expr->target()->AsVariableProxy()); - PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->target(), TOS_REG); break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case NAMED_SUPER_PROPERTY: EmitNamedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_SUPER_PROPERTY: EmitKeyedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_PROPERTY: EmitKeyedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; } } @@ -1780,7 +1770,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { } // Deoptimization point in case the binary operation may have side effects. - PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->binary_operation(), TOS_REG); } else { VisitForAccumulatorValue(expr->value()); } @@ -1792,7 +1782,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), expr->op(), expr->AssignmentSlot()); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(x0); break; case NAMED_PROPERTY: @@ -2172,7 +2162,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(x0); } @@ -2220,7 +2210,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(x0); } @@ -2244,7 +2234,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); - PrepareForBailout(callee, BailoutState::NO_REGISTERS); + PrepareForBailout(callee, NO_REGISTERS); } // Push undefined as receiver. This is patched in the method prologue if it // is a sloppy mode method. @@ -2261,8 +2251,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { DCHECK(!callee->AsProperty()->IsSuperAccess()); __ Peek(LoadDescriptor::ReceiverRegister(), 0); EmitNamedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. PopOperand(x10); PushOperands(x0, x10); @@ -2302,7 +2291,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ Poke(x0, kPointerSize); @@ -2328,8 +2317,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ Peek(LoadDescriptor::ReceiverRegister(), 0); __ Move(LoadDescriptor::NameRegister(), x0); EmitKeyedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. PopOperand(x10); @@ -2365,7 +2353,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ Poke(x0, kPointerSize); @@ -2386,7 +2374,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); SetCallPosition(expr, expr->tail_call_mode()); if (expr->tail_call_mode() == TailCallMode::kAllow) { if (FLAG_trace) { @@ -2455,7 +2443,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { __ Push(callee->name()); __ CallRuntime(Runtime::kLoadLookupSlotForCall); PushOperands(x0, x1); // Receiver, function. - PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); // If fast case code has been generated, emit code to push the // function and receiver and have the slow path jump around this @@ -2504,7 +2492,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { // Touch up the stack with the resolved function. __ Poke(x0, (arg_count + 1) * kPointerSize); - PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); // Record source position for debugger. SetCallPosition(expr); @@ -2556,7 +2544,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { CallConstructStub stub(isolate()); __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); OperandStackDepthDecrement(arg_count + 1); - PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ReturnId(), TOS_REG); RestoreContext(); context()->Plug(x0); } @@ -2990,7 +2978,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to x1. int const argc = args->length() - 2; __ Peek(x1, (argc + 1) * kXRegSize); @@ -3203,14 +3191,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); __ Bind(&materialize_true); - PrepareForBailoutForId(expr->MaterializeTrueId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); __ LoadRoot(result_register(), Heap::kTrueValueRootIndex); __ B(&done); __ Bind(&materialize_false); - PrepareForBailoutForId(expr->MaterializeFalseId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); __ LoadRoot(result_register(), Heap::kFalseValueRootIndex); __ B(&done); @@ -3310,9 +3296,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // We need a second deoptimization point after loading the value // in case evaluating the property load my have a side effect. if (assign_type == VARIABLE) { - PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->expression(), TOS_REG); } else { - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); } // Inline smi case if we are in a loop. @@ -3361,7 +3347,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Convert old value into a number. ToNumberStub convert_stub(isolate()); __ CallStub(&convert_stub); - PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); // Save result for postfix expressions. if (expr->is_postfix()) { @@ -3410,8 +3396,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { { EffectContext context(this); EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context.Plug(x0); } // For all contexts except EffectConstant We have the result on @@ -3422,8 +3407,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } else { EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(x0); } break; @@ -3433,7 +3417,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->CountSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); @@ -3472,7 +3456,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->CountSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); diff --git a/src/full-codegen/full-codegen.cc b/src/full-codegen/full-codegen.cc index 2d7ad3255b..afd3a05e50 100644 --- a/src/full-codegen/full-codegen.cc +++ b/src/full-codegen/full-codegen.cc @@ -164,8 +164,8 @@ void FullCodeGenerator::Initialize() { masm_->set_predictable_code_size(true); } -void FullCodeGenerator::PrepareForBailout(Expression* node, - BailoutState state) { + +void FullCodeGenerator::PrepareForBailout(Expression* node, State state) { PrepareForBailoutForId(node->id(), state); } @@ -188,9 +188,9 @@ void FullCodeGenerator::RecordJSReturnSite(Call* call) { // if the function was inlined, i.e., this is the return address in the // inlined function's frame. // - // The bailout state is ignored. We defensively set it to TOS_REGISTER, which - // is the real state of the unoptimized code at the return site. - PrepareForBailoutForId(call->ReturnId(), BailoutState::TOS_REGISTER); + // The state is ignored. We defensively set it to TOS_REG, which is the + // real state of the unoptimized code at the return site. + PrepareForBailoutForId(call->ReturnId(), TOS_REG); #ifdef DEBUG // In debug builds, mark the return so we can verify that this function // was called. @@ -199,13 +199,13 @@ void FullCodeGenerator::RecordJSReturnSite(Call* call) { #endif } -void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, - BailoutState state) { + +void FullCodeGenerator::PrepareForBailoutForId(BailoutId id, State state) { // There's no need to prepare this code for bailouts from already optimized // code or code that can't be optimized. if (!info_->HasDeoptimizationSupport()) return; unsigned pc_and_state = - BailoutStateField::encode(state) | PcField::encode(masm_->pc_offset()); + StateField::encode(state) | PcField::encode(masm_->pc_offset()); DCHECK(Smi::IsValid(pc_and_state)); #ifdef DEBUG for (int i = 0; i < bailout_entries_.length(); ++i) { @@ -752,7 +752,7 @@ void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { } else { VisitForControl(left, test->true_label(), &eval_right, &eval_right); } - PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); + PrepareForBailoutForId(right_id, NO_REGISTERS); __ bind(&eval_right); } else if (context()->IsAccumulatorValue()) { @@ -771,7 +771,7 @@ void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { __ jmp(&done); __ bind(&discard); __ Drop(1); - PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); + PrepareForBailoutForId(right_id, NO_REGISTERS); } else if (context()->IsStackValue()) { VisitForAccumulatorValue(left); @@ -786,7 +786,7 @@ void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { } __ bind(&discard); __ Drop(1); - PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); + PrepareForBailoutForId(right_id, NO_REGISTERS); } else { DCHECK(context()->IsEffect()); @@ -796,7 +796,7 @@ void FullCodeGenerator::VisitLogicalExpression(BinaryOperation* expr) { } else { VisitForControl(left, &done, &eval_right, &eval_right); } - PrepareForBailoutForId(right_id, BailoutState::NO_REGISTERS); + PrepareForBailoutForId(right_id, NO_REGISTERS); __ bind(&eval_right); } @@ -854,7 +854,7 @@ void FullCodeGenerator::VisitProperty(Property* expr) { EmitKeyedSuperPropertyLoad(expr); } } - PrepareForBailoutForId(expr->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->LoadId(), TOS_REG); context()->Plug(result_register()); } @@ -866,7 +866,7 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { if (proxy != NULL && (proxy->var()->IsUnallocatedOrGlobalSlot() || proxy->var()->IsLookupSlot())) { EmitVariableLoad(proxy, INSIDE_TYPEOF); - PrepareForBailout(proxy, BailoutState::TOS_REGISTER); + PrepareForBailout(proxy, TOS_REG); } else { // This expression cannot throw a reference error at the top level. VisitInDuplicateContext(expr); @@ -914,24 +914,24 @@ void FullCodeGenerator::VisitIfStatement(IfStatement* stmt) { if (stmt->HasElseStatement()) { VisitForControl(stmt->condition(), &then_part, &else_part, &then_part); - PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); __ bind(&then_part); Visit(stmt->then_statement()); __ jmp(&done); - PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); __ bind(&else_part); Visit(stmt->else_statement()); } else { VisitForControl(stmt->condition(), &then_part, &done, &then_part); - PrepareForBailoutForId(stmt->ThenId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ThenId(), NO_REGISTERS); __ bind(&then_part); Visit(stmt->then_statement()); - PrepareForBailoutForId(stmt->ElseId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ElseId(), NO_REGISTERS); } __ bind(&done); - PrepareForBailoutForId(stmt->IfId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->IfId(), NO_REGISTERS); } void FullCodeGenerator::EmitContinue(Statement* target) { @@ -1095,7 +1095,7 @@ void FullCodeGenerator::EmitPropertyKey(ObjectLiteralProperty* property, BailoutId bailout_id) { VisitForStackValue(property->key()); CallRuntimeWithOperands(Runtime::kToName); - PrepareForBailoutForId(bailout_id, BailoutState::NO_REGISTERS); + PrepareForBailoutForId(bailout_id, NO_REGISTERS); PushOperand(result_register()); } @@ -1121,12 +1121,12 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { Callable callable = CodeFactory::ToObject(isolate()); __ Move(callable.descriptor().GetRegisterParameter(0), result_register()); __ Call(callable.code(), RelocInfo::CODE_TARGET); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ToObjectId(), NO_REGISTERS); PushOperand(result_register()); PushFunctionArgumentForContextAllocation(); CallRuntimeWithOperands(Runtime::kPushWithContext); StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); Scope* saved_scope = scope(); scope_ = stmt->scope(); @@ -1158,7 +1158,7 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { // Record the position of the do while condition and make sure it is // possible to break on the condition. __ bind(loop_statement.continue_label()); - PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); // Here is the actual 'while' keyword. SetExpressionAsStatementPosition(stmt->cond()); @@ -1168,12 +1168,12 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { &book_keeping); // Check stack before looping. - PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); __ bind(&book_keeping); EmitBackEdgeBookkeeping(stmt, &body); __ jmp(&body); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1194,7 +1194,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { loop_statement.break_label(), &body); - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); __ bind(&body); Visit(stmt->body()); @@ -1204,7 +1204,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { EmitBackEdgeBookkeeping(stmt, &loop); __ jmp(&loop); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1227,11 +1227,11 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { // Emit the test at the bottom of the loop (even if empty). __ jmp(&test); - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); __ bind(&body); Visit(stmt->body()); - PrepareForBailoutForId(stmt->ContinueId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); __ bind(loop_statement.continue_label()); if (stmt->next() != NULL) { SetStatementPosition(stmt->next()); @@ -1252,7 +1252,7 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { __ jmp(&body); } - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1288,12 +1288,12 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { Visit(stmt->body()); // Check stack before looping. - PrepareForBailoutForId(stmt->BackEdgeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); __ jmp(loop_statement.continue_label()); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(loop_statement.break_label()); decrement_loop_depth(); } @@ -1437,7 +1437,7 @@ void FullCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { __ DebugBreak(); // Ignore the return value. - PrepareForBailoutForId(stmt->DebugBreakId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->DebugBreakId(), NO_REGISTERS); } @@ -1452,7 +1452,7 @@ void FullCodeGenerator::VisitConditional(Conditional* expr) { VisitForControl(expr->condition(), &true_case, &false_case, &true_case); int original_stack_depth = operand_stack_depth_; - PrepareForBailoutForId(expr->ThenId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->ThenId(), NO_REGISTERS); __ bind(&true_case); SetExpressionPosition(expr->then_expression()); if (context()->IsTest()) { @@ -1467,7 +1467,7 @@ void FullCodeGenerator::VisitConditional(Conditional* expr) { } operand_stack_depth_ = original_stack_depth; - PrepareForBailoutForId(expr->ElseId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->ElseId(), NO_REGISTERS); __ bind(&false_case); SetExpressionPosition(expr->else_expression()); VisitInDuplicateContext(expr->else_expression()); @@ -1518,7 +1518,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { PushOperand(Smi::FromInt(lit->end_position())); CallRuntimeWithOperands(Runtime::kDefineClass); - PrepareForBailoutForId(lit->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG); PushOperand(result_register()); // Load the "prototype" from the constructor. @@ -1527,7 +1527,7 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) { Heap::kprototype_stringRootIndex); __ Move(LoadDescriptor::SlotRegister(), SmiFromSlot(lit->PrototypeSlot())); CallLoadIC(NOT_INSIDE_TYPEOF); - PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(lit->PrototypeId(), TOS_REG); PushOperand(result_register()); EmitClassDefineProperties(lit); @@ -1668,7 +1668,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); EmitCallJSRuntimeFunction(expr); context()->DropAndPlug(1, result_register()); @@ -1690,7 +1690,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { } // Call the C runtime function. - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); __ CallRuntime(expr->function(), arg_count); OperandStackDepthDecrement(arg_count); context()->Plug(result_register()); @@ -1879,7 +1879,7 @@ FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( saved_scope_ = codegen_->scope(); if (scope == NULL) { - codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS); + codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); needs_block_context_ = false; } else { needs_block_context_ = scope->NeedsContext(); @@ -1896,13 +1896,12 @@ FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded( codegen_->context_register()); } CHECK_EQ(0, scope->num_stack_slots()); - codegen_->PrepareForBailoutForId(entry_id, BailoutState::NO_REGISTERS); + codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS); } { Comment cmnt(masm(), "[ Declarations"); codegen_->VisitDeclarations(scope->declarations()); - codegen_->PrepareForBailoutForId(declarations_id, - BailoutState::NO_REGISTERS); + codegen_->PrepareForBailoutForId(declarations_id, NO_REGISTERS); } } } @@ -1916,7 +1915,7 @@ FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() { codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset, codegen_->context_register()); } - codegen_->PrepareForBailoutForId(exit_id_, BailoutState::NO_REGISTERS); + codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS); codegen_->scope_ = saved_scope_; } diff --git a/src/full-codegen/full-codegen.h b/src/full-codegen/full-codegen.h index 0a004a8dd4..1044f4038c 100644 --- a/src/full-codegen/full-codegen.h +++ b/src/full-codegen/full-codegen.h @@ -14,7 +14,6 @@ #include "src/code-stubs.h" #include "src/codegen.h" #include "src/compiler.h" -#include "src/deoptimizer.h" #include "src/globals.h" #include "src/objects.h" @@ -29,6 +28,11 @@ class JumpPatchSite; class FullCodeGenerator: public AstVisitor { public: + enum State { + NO_REGISTERS, + TOS_REG + }; + FullCodeGenerator(MacroAssembler* masm, CompilationInfo* info) : masm_(masm), info_(info), @@ -56,10 +60,19 @@ class FullCodeGenerator: public AstVisitor { static bool MakeCode(CompilationInfo* info); - // Encode bailout state and pc-offset as a BitField. + // Encode state and pc-offset as a BitField. // Only use 30 bits because we encode the result as a smi. - class BailoutStateField : public BitField {}; - class PcField : public BitField {}; + class StateField : public BitField { }; + class PcField : public BitField { }; + + static const char* State2String(State state) { + switch (state) { + case NO_REGISTERS: return "NO_REGISTERS"; + case TOS_REG: return "TOS_REG"; + } + UNREACHABLE(); + return NULL; + } static const int kMaxBackEdgeWeight = 127; @@ -93,8 +106,6 @@ class FullCodeGenerator: public AstVisitor { static Register result_register(); private: - typedef Deoptimizer::BailoutState BailoutState; - class Breakable; class Iteration; class TryFinally; @@ -355,21 +366,21 @@ class FullCodeGenerator: public AstVisitor { if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); EffectContext context(this); Visit(expr); - PrepareForBailout(expr, BailoutState::NO_REGISTERS); + PrepareForBailout(expr, NO_REGISTERS); } void VisitForAccumulatorValue(Expression* expr) { if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); AccumulatorValueContext context(this); Visit(expr); - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); } void VisitForStackValue(Expression* expr) { if (FLAG_verify_operand_stack_depth) EmitOperandStackDepthCheck(); StackValueContext context(this); Visit(expr); - PrepareForBailout(expr, BailoutState::NO_REGISTERS); + PrepareForBailout(expr, NO_REGISTERS); } void VisitForControl(Expression* expr, @@ -441,8 +452,8 @@ class FullCodeGenerator: public AstVisitor { NilValue nil); // Bailout support. - void PrepareForBailout(Expression* node, Deoptimizer::BailoutState state); - void PrepareForBailoutForId(BailoutId id, Deoptimizer::BailoutState state); + void PrepareForBailout(Expression* node, State state); + void PrepareForBailoutForId(BailoutId id, State state); // Returns a smi for the index into the FixedArray that backs the feedback // vector diff --git a/src/full-codegen/ia32/full-codegen-ia32.cc b/src/full-codegen/ia32/full-codegen-ia32.cc index 760a818552..82e213ea49 100644 --- a/src/full-codegen/ia32/full-codegen-ia32.cc +++ b/src/full-codegen/ia32/full-codegen-ia32.cc @@ -168,8 +168,7 @@ void FullCodeGenerator::Generate() { __ push(edi); __ Push(info->scope()->GetScopeInfo(info->isolate())); __ CallRuntime(Runtime::kNewScriptContext); - PrepareForBailoutForId(BailoutId::ScriptContext(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); // The new target value is not used, clobbering is safe. DCHECK_NULL(info->scope()->new_target_var()); } else { @@ -228,8 +227,7 @@ void FullCodeGenerator::Generate() { // Register holding this function and new target are both trashed in case we // bailout here. But since that can happen only when new target is not used // and we allocate a context, the value of |function_in_register| is correct. - PrepareForBailoutForId(BailoutId::FunctionContext(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. @@ -291,8 +289,7 @@ void FullCodeGenerator::Generate() { } // Visit the declarations and body. - PrepareForBailoutForId(BailoutId::FunctionEntry(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); { Comment cmnt(masm_, "[ Declarations"); VisitDeclarations(scope()->declarations()); @@ -305,8 +302,7 @@ void FullCodeGenerator::Generate() { { Comment cmnt(masm_, "[ Stack check"); - PrepareForBailoutForId(BailoutId::Declarations(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); Label ok; ExternalReference stack_limit = ExternalReference::address_of_stack_limit(isolate()); @@ -373,11 +369,11 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, EmitProfilingCounterReset(); __ bind(&ok); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR // entry becomes the target of a bailout. We don't expect it to be, but // we want it to work if it is. - PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); } void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( @@ -684,7 +680,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, Label skip; if (should_normalize) __ jmp(&skip, Label::kNear); - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); if (should_normalize) { __ cmp(eax, isolate()->factory()->true_value()); Split(equal, if_true, if_false, NULL); @@ -740,7 +736,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ mov(ContextOperand(esi, variable->index()), Immediate(isolate()->factory()->the_hole_value())); // No write barrier since the hole value is in old space. - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); } break; @@ -761,7 +757,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ push( Immediate(Smi::FromInt(variable->DeclarationPropertyAttributes()))); __ CallRuntime(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -805,7 +801,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } @@ -815,7 +811,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( VisitForStackValue(declaration->fun()); PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -846,7 +842,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Keep the switch value on the stack until a case matches. VisitForStackValue(stmt->tag()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); ZoneList* clauses = stmt->cases(); CaseClause* default_clause = NULL; // Can occur anywhere in the list. @@ -895,7 +891,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Label skip; __ jmp(&skip, Label::kNear); - PrepareForBailout(clause, BailoutState::TOS_REGISTER); + PrepareForBailout(clause, TOS_REG); __ cmp(eax, isolate()->factory()->true_value()); __ j(not_equal, &next_test); __ Drop(1); @@ -923,12 +919,12 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ Case body"); CaseClause* clause = clauses->at(i); __ bind(clause->body_target()); - PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); VisitStatements(clause->statements()); } __ bind(nested_statement.break_label()); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -961,7 +957,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { ToObjectStub stub(isolate()); __ CallStub(&stub); __ bind(&done_convert); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); __ push(eax); // Check cache validity in generated code. If we cannot guarantee cache @@ -978,7 +974,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ bind(&call_runtime); __ push(eax); __ CallRuntime(Runtime::kForInEnumerate); - PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->EnumId(), TOS_REG); __ cmp(FieldOperand(eax, HeapObject::kMapOffset), isolate()->factory()->meta_map()); __ j(not_equal, &fixed_array); @@ -1014,7 +1010,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ push(eax); // Array __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); __ push(eax); // Fixed array length (as smi). - PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); __ push(Immediate(Smi::FromInt(0))); // Initial index. // Generate code for doing the condition check. @@ -1052,7 +1048,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ push(ecx); // Enumerable. __ push(ebx); // Current entry. __ CallRuntime(Runtime::kForInFilter); - PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->FilterId(), TOS_REG); __ cmp(eax, isolate()->factory()->undefined_value()); __ j(equal, loop_statement.continue_label()); __ mov(ebx, eax); @@ -1064,11 +1060,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); - PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1085,7 +1081,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { DropOperands(5); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(&exit); decrement_loop_depth(); } @@ -1243,7 +1239,7 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { SetExpressionPosition(proxy); - PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); Variable* var = proxy->var(); // Three cases: global variables, lookup variables, and all other types of @@ -1355,7 +1351,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ CallStub(&stub); RestoreContext(); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); // If result_saved is true the result is on top of the stack. If // result_saved is false the result is in eax. @@ -1391,7 +1387,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); EmitLoadStoreICSlot(property->GetSlot(0)); CallStoreIC(); - PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(key->id(), NO_REGISTERS); if (NeedsHomeObject(value)) { EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); } @@ -1419,7 +1415,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); break; case ObjectLiteral::Property::GETTER: if (property->emit_store()) { @@ -1475,7 +1471,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); } else { EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); VisitForStackValue(value); @@ -1548,7 +1544,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); bool result_saved = false; // Is the result saved to the stack? ZoneList* subexprs = expr->values(); @@ -1578,8 +1574,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { Handle ic = CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } // In case the array literal contains spread expressions it has two parts. The @@ -1599,8 +1594,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForStackValue(subexpr); CallRuntimeWithOperands(Runtime::kAppendElement); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } if (result_saved) { @@ -1679,27 +1673,23 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { switch (assign_type) { case VARIABLE: EmitVariableLoad(expr->target()->AsVariableProxy()); - PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->target(), TOS_REG); break; case NAMED_SUPER_PROPERTY: EmitNamedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_SUPER_PROPERTY: EmitKeyedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_PROPERTY: EmitKeyedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; } } @@ -1718,7 +1708,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { } // Deoptimization point in case the binary operation may have side effects. - PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->binary_operation(), TOS_REG); } else { VisitForAccumulatorValue(expr->value()); } @@ -1730,7 +1720,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), expr->op(), expr->AssignmentSlot()); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(eax); break; case NAMED_PROPERTY: @@ -2189,7 +2179,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->AssignmentSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(eax); } @@ -2235,7 +2225,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->AssignmentSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(eax); } @@ -2256,7 +2246,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); - PrepareForBailout(callee, BailoutState::NO_REGISTERS); + PrepareForBailout(callee, NO_REGISTERS); } // Push undefined as receiver. This is patched in the method prologue if it // is a sloppy mode method. @@ -2268,8 +2258,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { DCHECK(!callee->AsProperty()->IsSuperAccess()); __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. PushOperand(Operand(esp, 0)); __ mov(Operand(esp, kPointerSize), eax); @@ -2304,7 +2293,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ mov(Operand(esp, kPointerSize), eax); @@ -2329,8 +2318,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); __ mov(LoadDescriptor::NameRegister(), eax); EmitKeyedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. PushOperand(Operand(esp, 0)); @@ -2362,7 +2350,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ mov(Operand(esp, kPointerSize), eax); @@ -2382,7 +2370,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); SetCallPosition(expr, expr->tail_call_mode()); if (expr->tail_call_mode() == TailCallMode::kAllow) { if (FLAG_trace) { @@ -2450,7 +2438,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { __ CallRuntime(Runtime::kLoadLookupSlotForCall); PushOperand(eax); // Function. PushOperand(edx); // Receiver. - PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); // If fast case code has been generated, emit code to push the function // and receiver and have the slow path jump around this code. @@ -2495,7 +2483,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { // Touch up the stack with the resolved function. __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); - PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); SetCallPosition(expr); __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); @@ -2544,7 +2532,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { CallConstructStub stub(isolate()); __ call(stub.GetCode(), RelocInfo::CODE_TARGET); OperandStackDepthDecrement(arg_count + 1); - PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ReturnId(), TOS_REG); RestoreContext(); context()->Plug(eax); } @@ -2980,7 +2968,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to edi. int const argc = args->length() - 2; __ mov(edi, Operand(esp, (argc + 1) * kPointerSize)); @@ -3187,8 +3175,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { &materialize_true); if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); __ bind(&materialize_true); - PrepareForBailoutForId(expr->MaterializeTrueId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); if (context()->IsAccumulatorValue()) { __ mov(eax, isolate()->factory()->true_value()); } else { @@ -3196,8 +3183,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { } __ jmp(&done, Label::kNear); __ bind(&materialize_false); - PrepareForBailoutForId(expr->MaterializeFalseId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); if (context()->IsAccumulatorValue()) { __ mov(eax, isolate()->factory()->false_value()); } else { @@ -3296,9 +3282,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // We need a second deoptimization point after loading the value // in case evaluating the property load my have a side effect. if (assign_type == VARIABLE) { - PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->expression(), TOS_REG); } else { - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); } // Inline smi case if we are in a loop. @@ -3353,7 +3339,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Convert old value into a number. ToNumberStub convert_stub(isolate()); __ CallStub(&convert_stub); - PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); // Save result for postfix expressions. if (expr->is_postfix()) { @@ -3401,8 +3387,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { { EffectContext context(this); EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context.Plug(eax); } // For all contexts except EffectContext We have the result on @@ -3414,8 +3399,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Perform the assignment as if via '='. EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(eax); } break; @@ -3425,7 +3409,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->CountSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); @@ -3464,7 +3448,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->CountSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { // Result is on the stack if (!context()->IsEffect()) { diff --git a/src/full-codegen/mips/full-codegen-mips.cc b/src/full-codegen/mips/full-codegen-mips.cc index e61c3e4e71..33a7e256bb 100644 --- a/src/full-codegen/mips/full-codegen-mips.cc +++ b/src/full-codegen/mips/full-codegen-mips.cc @@ -186,8 +186,7 @@ void FullCodeGenerator::Generate() { __ push(a1); __ Push(info->scope()->GetScopeInfo(info->isolate())); __ CallRuntime(Runtime::kNewScriptContext); - PrepareForBailoutForId(BailoutId::ScriptContext(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); // The new target value is not used, clobbering is safe. DCHECK_NULL(info->scope()->new_target_var()); } else { @@ -243,8 +242,7 @@ void FullCodeGenerator::Generate() { // Register holding this function and new target are both trashed in case we // bailout here. But since that can happen only when new target is not used // and we allocate a context, the value of |function_in_register| is correct. - PrepareForBailoutForId(BailoutId::FunctionContext(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. @@ -307,8 +305,7 @@ void FullCodeGenerator::Generate() { // Visit the declarations and body unless there is an illegal // redeclaration. - PrepareForBailoutForId(BailoutId::FunctionEntry(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); { Comment cmnt(masm_, "[ Declarations"); VisitDeclarations(scope()->declarations()); @@ -321,8 +318,7 @@ void FullCodeGenerator::Generate() { { Comment cmnt(masm_, "[ Stack check"); - PrepareForBailoutForId(BailoutId::Declarations(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); Label ok; __ LoadRoot(at, Heap::kStackLimitRootIndex); __ Branch(&ok, hs, sp, Operand(at)); @@ -401,11 +397,11 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, EmitProfilingCounterReset(); __ bind(&ok); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR // entry becomes the target of a bailout. We don't expect it to be, but // we want it to work if it is. - PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); } void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( @@ -731,7 +727,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, Label skip; if (should_normalize) __ Branch(&skip); - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); if (should_normalize) { __ LoadRoot(t0, Heap::kTrueValueRootIndex); Split(eq, a0, Operand(t0), if_true, if_false, NULL); @@ -790,7 +786,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ LoadRoot(at, Heap::kTheHoleValueRootIndex); __ sw(at, ContextMemOperand(cp, variable->index())); // No write barrier since the_hole_value is in old space. - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); } break; @@ -812,7 +808,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ Push(a2, a0); __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); __ CallRuntime(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -858,7 +854,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } @@ -870,7 +866,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( VisitForStackValue(declaration->fun()); PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -902,7 +898,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Keep the switch value on the stack until a case matches. VisitForStackValue(stmt->tag()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); ZoneList* clauses = stmt->cases(); CaseClause* default_clause = NULL; // Can occur anywhere in the list. @@ -952,7 +948,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Label skip; __ Branch(&skip); - PrepareForBailout(clause, BailoutState::TOS_REGISTER); + PrepareForBailout(clause, TOS_REG); __ LoadRoot(at, Heap::kTrueValueRootIndex); __ Branch(&next_test, ne, v0, Operand(at)); __ Drop(1); @@ -979,12 +975,12 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ Case body"); CaseClause* clause = clauses->at(i); __ bind(clause->body_target()); - PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); VisitStatements(clause->statements()); } __ bind(nested_statement.break_label()); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -1020,7 +1016,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ CallStub(&stub); __ mov(a0, v0); __ bind(&done_convert); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); __ push(a0); // Check cache validity in generated code. If we cannot guarantee cache @@ -1040,7 +1036,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ bind(&call_runtime); __ push(a0); // Duplicate the enumerable object on the stack. __ CallRuntime(Runtime::kForInEnumerate); - PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->EnumId(), TOS_REG); // If we got a map from the runtime call, we can do a fast // modification check. Otherwise, we got a fixed array, and we have @@ -1078,7 +1074,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Push(a1, v0); // Smi and array __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); __ Push(a1); // Fixed array length (as smi). - PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); __ li(a0, Operand(Smi::FromInt(0))); __ Push(a0); // Initial index. @@ -1119,7 +1115,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // just skip it. __ Push(a1, a3); // Enumerable and current entry. __ CallRuntime(Runtime::kForInFilter); - PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->FilterId(), TOS_REG); __ mov(a3, result_register()); __ LoadRoot(at, Heap::kUndefinedValueRootIndex); __ Branch(loop_statement.continue_label(), eq, a3, Operand(at)); @@ -1131,11 +1127,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); - PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1154,7 +1150,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { DropOperands(5); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(&exit); decrement_loop_depth(); } @@ -1313,7 +1309,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { // Record position before possible IC call. SetExpressionPosition(proxy); - PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); Variable* var = proxy->var(); // Three cases: global variables, lookup variables, and all other types of @@ -1420,7 +1416,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ CallStub(&stub); RestoreContext(); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); // If result_saved is true the result is on top of the stack. If // result_saved is false the result is in v0. @@ -1457,7 +1453,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); EmitLoadStoreICSlot(property->GetSlot(0)); CallStoreIC(); - PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(key->id(), NO_REGISTERS); if (NeedsHomeObject(value)) { EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); @@ -1491,7 +1487,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); break; case ObjectLiteral::Property::GETTER: if (property->emit_store()) { @@ -1548,7 +1544,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); } else { EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); VisitForStackValue(value); @@ -1620,7 +1616,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); bool result_saved = false; // Is the result saved to the stack? ZoneList* subexprs = expr->values(); @@ -1652,8 +1648,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } // In case the array literal contains spread expressions it has two parts. The @@ -1673,8 +1668,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForStackValue(subexpr); CallRuntimeWithOperands(Runtime::kAppendElement); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } if (result_saved) { @@ -1757,27 +1751,23 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { switch (assign_type) { case VARIABLE: EmitVariableLoad(expr->target()->AsVariableProxy()); - PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->target(), TOS_REG); break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case NAMED_SUPER_PROPERTY: EmitNamedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_SUPER_PROPERTY: EmitKeyedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_PROPERTY: EmitKeyedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; } } @@ -1797,7 +1787,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { } // Deoptimization point in case the binary operation may have side effects. - PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->binary_operation(), TOS_REG); } else { VisitForAccumulatorValue(expr->value()); } @@ -1809,7 +1799,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), expr->op(), expr->AssignmentSlot()); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); break; case NAMED_PROPERTY: @@ -2286,7 +2276,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); } @@ -2337,7 +2327,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); } @@ -2358,7 +2348,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); - PrepareForBailout(callee, BailoutState::NO_REGISTERS); + PrepareForBailout(callee, NO_REGISTERS); } // Push undefined as receiver. This is patched in the method prologue if it // is a sloppy mode method. @@ -2371,8 +2361,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { DCHECK(!callee->AsProperty()->IsSuperAccess()); __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. __ lw(at, MemOperand(sp, 0)); PushOperand(at); @@ -2409,7 +2398,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ sw(v0, MemOperand(sp, kPointerSize)); @@ -2434,8 +2423,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); __ Move(LoadDescriptor::NameRegister(), v0); EmitKeyedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. __ lw(at, MemOperand(sp, 0)); @@ -2469,7 +2457,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ sw(v0, MemOperand(sp, kPointerSize)); @@ -2489,7 +2477,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Record source position of the IC call. SetCallPosition(expr, expr->tail_call_mode()); if (expr->tail_call_mode() == TailCallMode::kAllow) { @@ -2559,7 +2547,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { __ Push(callee->name()); __ CallRuntime(Runtime::kLoadLookupSlotForCall); PushOperands(v0, v1); // Function, receiver. - PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); // If fast case code has been generated, emit code to push the // function and receiver and have the slow path jump around this @@ -2607,7 +2595,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { // Touch up the stack with the resolved function. __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); - PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); // Record source position for debugger. SetCallPosition(expr); __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); @@ -2656,7 +2644,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { CallConstructStub stub(isolate()); __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); OperandStackDepthDecrement(arg_count + 1); - PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ReturnId(), TOS_REG); RestoreContext(); context()->Plug(v0); } @@ -3104,7 +3092,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to a1. int const argc = args->length() - 2; __ lw(a1, MemOperand(sp, (argc + 1) * kPointerSize)); @@ -3308,14 +3296,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { &materialize_true); if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); __ bind(&materialize_true); - PrepareForBailoutForId(expr->MaterializeTrueId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); __ LoadRoot(v0, Heap::kTrueValueRootIndex); if (context()->IsStackValue()) __ push(v0); __ jmp(&done); __ bind(&materialize_false); - PrepareForBailoutForId(expr->MaterializeFalseId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); __ LoadRoot(v0, Heap::kFalseValueRootIndex); if (context()->IsStackValue()) __ push(v0); __ bind(&done); @@ -3415,9 +3401,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // We need a second deoptimization point after loading the value // in case evaluating the property load my have a side effect. if (assign_type == VARIABLE) { - PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->expression(), TOS_REG); } else { - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); } // Inline smi case if we are in a loop. @@ -3468,7 +3454,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Convert old value into a number. ToNumberStub convert_stub(isolate()); __ CallStub(&convert_stub); - PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); // Save result for postfix expressions. if (expr->is_postfix()) { @@ -3514,8 +3500,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { { EffectContext context(this); EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context.Plug(v0); } // For all contexts except EffectConstant we have the result on @@ -3526,8 +3511,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } else { EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); } break; @@ -3538,7 +3522,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->CountSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); @@ -3578,7 +3562,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->CountSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); diff --git a/src/full-codegen/mips64/full-codegen-mips64.cc b/src/full-codegen/mips64/full-codegen-mips64.cc index a93489da7f..e2ed637388 100644 --- a/src/full-codegen/mips64/full-codegen-mips64.cc +++ b/src/full-codegen/mips64/full-codegen-mips64.cc @@ -185,8 +185,7 @@ void FullCodeGenerator::Generate() { __ push(a1); __ Push(info->scope()->GetScopeInfo(info->isolate())); __ CallRuntime(Runtime::kNewScriptContext); - PrepareForBailoutForId(BailoutId::ScriptContext(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); // The new target value is not used, clobbering is safe. DCHECK_NULL(info->scope()->new_target_var()); } else { @@ -242,8 +241,7 @@ void FullCodeGenerator::Generate() { // Register holding this function and new target are both trashed in case we // bailout here. But since that can happen only when new target is not used // and we allocate a context, the value of |function_in_register| is correct. - PrepareForBailoutForId(BailoutId::FunctionContext(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. @@ -304,8 +302,7 @@ void FullCodeGenerator::Generate() { } // Visit the declarations and body. - PrepareForBailoutForId(BailoutId::FunctionEntry(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); { Comment cmnt(masm_, "[ Declarations"); VisitDeclarations(scope()->declarations()); @@ -318,8 +315,7 @@ void FullCodeGenerator::Generate() { { Comment cmnt(masm_, "[ Stack check"); - PrepareForBailoutForId(BailoutId::Declarations(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); Label ok; __ LoadRoot(at, Heap::kStackLimitRootIndex); __ Branch(&ok, hs, sp, Operand(at)); @@ -400,11 +396,11 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, EmitProfilingCounterReset(); __ bind(&ok); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR // entry becomes the target of a bailout. We don't expect it to be, but // we want it to work if it is. - PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); } void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( @@ -730,7 +726,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, Label skip; if (should_normalize) __ Branch(&skip); - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); if (should_normalize) { __ LoadRoot(a4, Heap::kTrueValueRootIndex); Split(eq, a0, Operand(a4), if_true, if_false, NULL); @@ -789,7 +785,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ LoadRoot(at, Heap::kTheHoleValueRootIndex); __ sd(at, ContextMemOperand(cp, variable->index())); // No write barrier since the_hole_value is in old space. - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); } break; @@ -811,7 +807,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ Push(a2, a0); __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); __ CallRuntime(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -857,7 +853,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } @@ -869,7 +865,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( VisitForStackValue(declaration->fun()); PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -901,7 +897,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Keep the switch value on the stack until a case matches. VisitForStackValue(stmt->tag()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); ZoneList* clauses = stmt->cases(); CaseClause* default_clause = NULL; // Can occur anywhere in the list. @@ -951,7 +947,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Label skip; __ Branch(&skip); - PrepareForBailout(clause, BailoutState::TOS_REGISTER); + PrepareForBailout(clause, TOS_REG); __ LoadRoot(at, Heap::kTrueValueRootIndex); __ Branch(&next_test, ne, v0, Operand(at)); __ Drop(1); @@ -978,12 +974,12 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ Case body"); CaseClause* clause = clauses->at(i); __ bind(clause->body_target()); - PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); VisitStatements(clause->statements()); } __ bind(nested_statement.break_label()); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -1020,7 +1016,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ CallStub(&stub); __ mov(a0, v0); __ bind(&done_convert); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); __ push(a0); // Check cache validity in generated code. If we cannot guarantee cache @@ -1040,7 +1036,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ bind(&call_runtime); __ push(a0); // Duplicate the enumerable object on the stack. __ CallRuntime(Runtime::kForInEnumerate); - PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->EnumId(), TOS_REG); // If we got a map from the runtime call, we can do a fast // modification check. Otherwise, we got a fixed array, and we have @@ -1078,7 +1074,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Push(a1, v0); // Smi and array __ ld(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); __ Push(a1); // Fixed array length (as smi). - PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); __ li(a0, Operand(Smi::FromInt(0))); __ Push(a0); // Initial index. @@ -1120,7 +1116,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // just skip it. __ Push(a1, a3); // Enumerable and current entry. __ CallRuntime(Runtime::kForInFilter); - PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->FilterId(), TOS_REG); __ mov(a3, result_register()); __ LoadRoot(at, Heap::kUndefinedValueRootIndex); __ Branch(loop_statement.continue_label(), eq, a3, Operand(at)); @@ -1132,11 +1128,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); - PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1155,7 +1151,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { DropOperands(5); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(&exit); decrement_loop_depth(); } @@ -1314,7 +1310,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { // Record position before possible IC call. SetExpressionPosition(proxy); - PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); Variable* var = proxy->var(); // Three cases: global variables, lookup variables, and all other types of @@ -1421,7 +1417,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ CallStub(&stub); RestoreContext(); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); // If result_saved is true the result is on top of the stack. If // result_saved is false the result is in v0. @@ -1458,7 +1454,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); EmitLoadStoreICSlot(property->GetSlot(0)); CallStoreIC(); - PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(key->id(), NO_REGISTERS); if (NeedsHomeObject(value)) { EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); @@ -1492,7 +1488,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); break; case ObjectLiteral::Property::GETTER: if (property->emit_store()) { @@ -1549,7 +1545,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); } else { EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); VisitForStackValue(value); @@ -1621,7 +1617,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); bool result_saved = false; // Is the result saved to the stack? ZoneList* subexprs = expr->values(); @@ -1653,8 +1649,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } // In case the array literal contains spread expressions it has two parts. The @@ -1674,8 +1669,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForStackValue(subexpr); CallRuntimeWithOperands(Runtime::kAppendElement); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } if (result_saved) { @@ -1758,27 +1752,23 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { switch (assign_type) { case VARIABLE: EmitVariableLoad(expr->target()->AsVariableProxy()); - PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->target(), TOS_REG); break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case NAMED_SUPER_PROPERTY: EmitNamedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_SUPER_PROPERTY: EmitKeyedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_PROPERTY: EmitKeyedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; } } @@ -1798,7 +1788,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { } // Deoptimization point in case the binary operation may have side effects. - PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->binary_operation(), TOS_REG); } else { VisitForAccumulatorValue(expr->value()); } @@ -1810,7 +1800,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), expr->op(), expr->AssignmentSlot()); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); break; case NAMED_PROPERTY: @@ -2285,7 +2275,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); } @@ -2336,7 +2326,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); } @@ -2357,7 +2347,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); - PrepareForBailout(callee, BailoutState::NO_REGISTERS); + PrepareForBailout(callee, NO_REGISTERS); } // Push undefined as receiver. This is patched in the method prologue if it // is a sloppy mode method. @@ -2370,8 +2360,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { DCHECK(!callee->AsProperty()->IsSuperAccess()); __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. __ ld(at, MemOperand(sp, 0)); PushOperand(at); @@ -2408,7 +2397,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ sd(v0, MemOperand(sp, kPointerSize)); @@ -2433,8 +2422,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); __ Move(LoadDescriptor::NameRegister(), v0); EmitKeyedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. __ ld(at, MemOperand(sp, 0)); @@ -2468,7 +2456,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ sd(v0, MemOperand(sp, kPointerSize)); @@ -2488,7 +2476,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Record source position of the IC call. SetCallPosition(expr, expr->tail_call_mode()); if (expr->tail_call_mode() == TailCallMode::kAllow) { @@ -2558,7 +2546,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { __ Push(callee->name()); __ CallRuntime(Runtime::kLoadLookupSlotForCall); PushOperands(v0, v1); // Function, receiver. - PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); // If fast case code has been generated, emit code to push the // function and receiver and have the slow path jump around this @@ -2606,7 +2594,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { // Touch up the stack with the resolved function. __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); - PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); // Record source position for debugger. SetCallPosition(expr); __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); @@ -2655,7 +2643,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { CallConstructStub stub(isolate()); __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); OperandStackDepthDecrement(arg_count + 1); - PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ReturnId(), TOS_REG); RestoreContext(); context()->Plug(v0); } @@ -3104,7 +3092,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to a1. int const argc = args->length() - 2; __ ld(a1, MemOperand(sp, (argc + 1) * kPointerSize)); @@ -3309,14 +3297,12 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { &materialize_true); if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); __ bind(&materialize_true); - PrepareForBailoutForId(expr->MaterializeTrueId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); __ LoadRoot(v0, Heap::kTrueValueRootIndex); if (context()->IsStackValue()) __ push(v0); __ jmp(&done); __ bind(&materialize_false); - PrepareForBailoutForId(expr->MaterializeFalseId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); __ LoadRoot(v0, Heap::kFalseValueRootIndex); if (context()->IsStackValue()) __ push(v0); __ bind(&done); @@ -3416,9 +3402,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // We need a second deoptimization point after loading the value // in case evaluating the property load my have a side effect. if (assign_type == VARIABLE) { - PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->expression(), TOS_REG); } else { - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); } // Inline smi case if we are in a loop. @@ -3469,7 +3455,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Convert old value into a number. ToNumberStub convert_stub(isolate()); __ CallStub(&convert_stub); - PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); // Save result for postfix expressions. if (expr->is_postfix()) { @@ -3515,8 +3501,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { { EffectContext context(this); EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context.Plug(v0); } // For all contexts except EffectConstant we have the result on @@ -3527,8 +3512,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { } else { EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(v0); } break; @@ -3539,7 +3523,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->CountSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); @@ -3579,7 +3563,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->CountSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); diff --git a/src/full-codegen/x64/full-codegen-x64.cc b/src/full-codegen/x64/full-codegen-x64.cc index 1ef9ceebac..8f05b01a8d 100644 --- a/src/full-codegen/x64/full-codegen-x64.cc +++ b/src/full-codegen/x64/full-codegen-x64.cc @@ -166,8 +166,7 @@ void FullCodeGenerator::Generate() { __ Push(rdi); __ Push(info->scope()->GetScopeInfo(info->isolate())); __ CallRuntime(Runtime::kNewScriptContext); - PrepareForBailoutForId(BailoutId::ScriptContext(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(BailoutId::ScriptContext(), TOS_REG); // The new target value is not used, clobbering is safe. DCHECK_NULL(info->scope()->new_target_var()); } else { @@ -223,8 +222,7 @@ void FullCodeGenerator::Generate() { // Register holding this function and new target are both trashed in case we // bailout here. But since that can happen only when new target is not used // and we allocate a context, the value of |function_in_register| is correct. - PrepareForBailoutForId(BailoutId::FunctionContext(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionContext(), NO_REGISTERS); // Possibly set up a local binding to the this function which is used in // derived constructors with super calls. @@ -288,8 +286,7 @@ void FullCodeGenerator::Generate() { // Visit the declarations and body unless there is an illegal // redeclaration. - PrepareForBailoutForId(BailoutId::FunctionEntry(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); { Comment cmnt(masm_, "[ Declarations"); VisitDeclarations(scope()->declarations()); @@ -302,8 +299,7 @@ void FullCodeGenerator::Generate() { { Comment cmnt(masm_, "[ Stack check"); - PrepareForBailoutForId(BailoutId::Declarations(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); Label ok; __ CompareRoot(rsp, Heap::kStackLimitRootIndex); __ j(above_equal, &ok, Label::kNear); @@ -376,11 +372,11 @@ void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, } __ bind(&ok); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); // Record a mapping of the OSR id to this PC. This is used if the OSR // entry becomes the target of a bailout. We don't expect it to be, but // we want it to work if it is. - PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); } void FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence( @@ -696,7 +692,7 @@ void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, Label skip; if (should_normalize) __ jmp(&skip, Label::kNear); - PrepareForBailout(expr, BailoutState::TOS_REGISTER); + PrepareForBailout(expr, TOS_REG); if (should_normalize) { __ CompareRoot(rax, Heap::kTrueValueRootIndex); Split(equal, if_true, if_false, NULL); @@ -752,7 +748,7 @@ void FullCodeGenerator::VisitVariableDeclaration( __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); __ movp(ContextOperand(rsi, variable->index()), kScratchRegister); // No write barrier since the hole value is in old space. - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); } break; @@ -772,7 +768,7 @@ void FullCodeGenerator::VisitVariableDeclaration( } __ Push(Smi::FromInt(variable->DeclarationPropertyAttributes())); __ CallRuntime(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -817,7 +813,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } @@ -827,7 +823,7 @@ void FullCodeGenerator::VisitFunctionDeclaration( VisitForStackValue(declaration->fun()); PushOperand(Smi::FromInt(variable->DeclarationPropertyAttributes())); CallRuntimeWithOperands(Runtime::kDeclareLookupSlot); - PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->id(), NO_REGISTERS); break; } } @@ -858,7 +854,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { // Keep the switch value on the stack until a case matches. VisitForStackValue(stmt->tag()); - PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); ZoneList* clauses = stmt->cases(); CaseClause* default_clause = NULL; // Can occur anywhere in the list. @@ -908,7 +904,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Label skip; __ jmp(&skip, Label::kNear); - PrepareForBailout(clause, BailoutState::TOS_REGISTER); + PrepareForBailout(clause, TOS_REG); __ CompareRoot(rax, Heap::kTrueValueRootIndex); __ j(not_equal, &next_test); __ Drop(1); @@ -936,12 +932,12 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { Comment cmnt(masm_, "[ Case body"); CaseClause* clause = clauses->at(i); __ bind(clause->body_target()); - PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); VisitStatements(clause->statements()); } __ bind(nested_statement.break_label()); - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); } @@ -974,7 +970,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { ToObjectStub stub(isolate()); __ CallStub(&stub); __ bind(&done_convert); - PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG); __ Push(rax); // Check cache validity in generated code. If we cannot guarantee cache @@ -994,7 +990,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ bind(&call_runtime); __ Push(rax); // Duplicate the enumerable object on the stack. __ CallRuntime(Runtime::kForInEnumerate); - PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->EnumId(), TOS_REG); // If we got a map from the runtime call, we can do a fast // modification check. Otherwise, we got a fixed array, and we have @@ -1036,7 +1032,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Push(rax); // Array __ movp(rax, FieldOperand(rax, FixedArray::kLengthOffset)); __ Push(rax); // Fixed array length (as smi). - PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->PrepareId(), NO_REGISTERS); __ Push(Smi::FromInt(0)); // Initial index. // Generate code for doing the condition check. @@ -1078,7 +1074,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { __ Push(rcx); // Enumerable. __ Push(rbx); // Current entry. __ CallRuntime(Runtime::kForInFilter); - PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(stmt->FilterId(), TOS_REG); __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); __ j(equal, loop_statement.continue_label()); __ movp(rbx, rax); @@ -1090,11 +1086,11 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { // Perform the assignment as if via '='. { EffectContext context(this); EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); - PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); } // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body(). - PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); // Generate code for the body of the loop. Visit(stmt->body()); @@ -1111,7 +1107,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { DropOperands(5); // Exit and decrement the loop depth. - PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); __ bind(&exit); decrement_loop_depth(); } @@ -1270,7 +1266,7 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, TypeofMode typeof_mode) { // Record position before possible IC call. SetExpressionPosition(proxy); - PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); Variable* var = proxy->var(); // Three cases: global variables, lookup variables, and all other types of @@ -1380,7 +1376,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ CallStub(&stub); RestoreContext(); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); // If result_saved is true the result is on top of the stack. If // result_saved is false the result is in rax. @@ -1416,7 +1412,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); EmitLoadStoreICSlot(property->GetSlot(0)); CallStoreIC(); - PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(key->id(), NO_REGISTERS); if (NeedsHomeObject(value)) { EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1)); @@ -1445,7 +1441,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); break; case ObjectLiteral::Property::GETTER: if (property->emit_store()) { @@ -1499,7 +1495,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { DCHECK(property->emit_store()); CallRuntimeWithOperands(Runtime::kInternalSetPrototype); PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), - BailoutState::NO_REGISTERS); + NO_REGISTERS); } else { EmitPropertyKey(property, expr->GetIdForPropertyName(property_index)); VisitForStackValue(value); @@ -1572,7 +1568,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); __ CallStub(&stub); } - PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); bool result_saved = false; // Is the result saved to the stack? ZoneList* subexprs = expr->values(); @@ -1602,8 +1598,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); CallIC(ic); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } // In case the array literal contains spread expressions it has two parts. The @@ -1623,8 +1618,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { VisitForStackValue(subexpr); CallRuntimeWithOperands(Runtime::kAppendElement); - PrepareForBailoutForId(expr->GetIdForElement(array_index), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->GetIdForElement(array_index), NO_REGISTERS); } if (result_saved) { @@ -1702,27 +1696,23 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { switch (assign_type) { case VARIABLE: EmitVariableLoad(expr->target()->AsVariableProxy()); - PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->target(), TOS_REG); break; case NAMED_PROPERTY: EmitNamedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case NAMED_SUPER_PROPERTY: EmitNamedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_SUPER_PROPERTY: EmitKeyedSuperPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; case KEYED_PROPERTY: EmitKeyedPropertyLoad(property); - PrepareForBailoutForId(property->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(property->LoadId(), TOS_REG); break; } } @@ -1741,7 +1731,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { EmitBinaryOp(expr->binary_operation(), op); } // Deoptimization point in case the binary operation may have side effects. - PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->binary_operation(), TOS_REG); } else { VisitForAccumulatorValue(expr->value()); } @@ -1753,7 +1743,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) { case VARIABLE: EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), expr->op(), expr->AssignmentSlot()); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(rax); break; case NAMED_PROPERTY: @@ -2176,7 +2166,7 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(rax); } @@ -2220,7 +2210,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { EmitLoadStoreICSlot(expr->AssignmentSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(rax); } @@ -2241,7 +2231,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { if (callee->IsVariableProxy()) { { StackValueContext context(this); EmitVariableLoad(callee->AsVariableProxy()); - PrepareForBailout(callee, BailoutState::NO_REGISTERS); + PrepareForBailout(callee, NO_REGISTERS); } // Push undefined as receiver. This is patched in the Call builtin if it // is a sloppy mode method. @@ -2253,8 +2243,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { DCHECK(!callee->AsProperty()->IsSuperAccess()); __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); EmitNamedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. PushOperand(Operand(rsp, 0)); __ movp(Operand(rsp, kPointerSize), rax); @@ -2290,7 +2279,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ movp(Operand(rsp, kPointerSize), rax); @@ -2315,8 +2304,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); __ Move(LoadDescriptor::NameRegister(), rax); EmitKeyedPropertyLoad(callee->AsProperty()); - PrepareForBailoutForId(callee->AsProperty()->LoadId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); // Push the target function under the receiver. PushOperand(Operand(rsp, 0)); @@ -2349,7 +2337,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { // - home_object // - key CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); // Replace home_object with target function. __ movp(Operand(rsp, kPointerSize), rax); @@ -2369,7 +2357,7 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { VisitForStackValue(args->at(i)); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); SetCallPosition(expr, expr->tail_call_mode()); if (expr->tail_call_mode() == TailCallMode::kAllow) { if (FLAG_trace) { @@ -2437,7 +2425,7 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { __ CallRuntime(Runtime::kLoadLookupSlotForCall); PushOperand(rax); // Function. PushOperand(rdx); // Receiver. - PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); // If fast case code has been generated, emit code to push the function // and receiver and have the slow path jump around this code. @@ -2483,7 +2471,7 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { // Touch up the callee. __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax); - PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); SetCallPosition(expr); __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); @@ -2532,7 +2520,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) { CallConstructStub stub(isolate()); __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); OperandStackDepthDecrement(arg_count + 1); - PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ReturnId(), TOS_REG); RestoreContext(); context()->Plug(rax); } @@ -2966,7 +2954,7 @@ void FullCodeGenerator::EmitCall(CallRuntime* expr) { for (Expression* const arg : *args) { VisitForStackValue(arg); } - PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); // Move target to rdi. int const argc = args->length() - 2; __ movp(rdi, Operand(rsp, (argc + 1) * kPointerSize)); @@ -3173,8 +3161,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { &materialize_true); if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1); __ bind(&materialize_true); - PrepareForBailoutForId(expr->MaterializeTrueId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); if (context()->IsAccumulatorValue()) { __ LoadRoot(rax, Heap::kTrueValueRootIndex); } else { @@ -3182,8 +3169,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { } __ jmp(&done, Label::kNear); __ bind(&materialize_false); - PrepareForBailoutForId(expr->MaterializeFalseId(), - BailoutState::NO_REGISTERS); + PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); if (context()->IsAccumulatorValue()) { __ LoadRoot(rax, Heap::kFalseValueRootIndex); } else { @@ -3282,9 +3268,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // We need a second deoptimization point after loading the value // in case evaluating the property load my have a side effect. if (assign_type == VARIABLE) { - PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); + PrepareForBailout(expr->expression(), TOS_REG); } else { - PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(prop->LoadId(), TOS_REG); } // Inline smi case if we are in a loop. @@ -3337,7 +3323,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Convert old value into a number. ToNumberStub convert_stub(isolate()); __ CallStub(&convert_stub); - PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); // Save result for postfix expressions. if (expr->is_postfix()) { @@ -3385,8 +3371,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { { EffectContext context(this); EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context.Plug(rax); } // For all contexts except kEffect: We have the result on @@ -3398,8 +3383,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { // Perform the assignment as if via '='. EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), Token::ASSIGN, expr->CountSlot()); - PrepareForBailoutForId(expr->AssignmentId(), - BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); context()->Plug(rax); } break; @@ -3409,7 +3393,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { PopOperand(StoreDescriptor::ReceiverRegister()); EmitLoadStoreICSlot(expr->CountSlot()); CallStoreIC(); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); @@ -3448,7 +3432,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); EmitLoadStoreICSlot(expr->CountSlot()); CallIC(ic); - PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); + PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); if (expr->is_postfix()) { if (!context()->IsEffect()) { context()->PlugTOS(); diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h index f9c9235320..33b11ea5d0 100644 --- a/src/heap/heap-inl.h +++ b/src/heap/heap-inl.h @@ -685,30 +685,30 @@ int Heap::NextScriptId() { return last_id; } + void Heap::SetArgumentsAdaptorDeoptPCOffset(int pc_offset) { DCHECK(arguments_adaptor_deopt_pc_offset() == Smi::FromInt(0)); set_arguments_adaptor_deopt_pc_offset(Smi::FromInt(pc_offset)); } + void Heap::SetConstructStubDeoptPCOffset(int pc_offset) { DCHECK(construct_stub_deopt_pc_offset() == Smi::FromInt(0)); set_construct_stub_deopt_pc_offset(Smi::FromInt(pc_offset)); } + void Heap::SetGetterStubDeoptPCOffset(int pc_offset) { DCHECK(getter_stub_deopt_pc_offset() == Smi::FromInt(0)); set_getter_stub_deopt_pc_offset(Smi::FromInt(pc_offset)); } + void Heap::SetSetterStubDeoptPCOffset(int pc_offset) { DCHECK(setter_stub_deopt_pc_offset() == Smi::FromInt(0)); set_setter_stub_deopt_pc_offset(Smi::FromInt(pc_offset)); } -void Heap::SetInterpreterEntryReturnPCOffset(int pc_offset) { - DCHECK(interpreter_entry_return_pc_offset() == Smi::FromInt(0)); - set_interpreter_entry_return_pc_offset(Smi::FromInt(pc_offset)); -} AlwaysAllocateScope::AlwaysAllocateScope(Isolate* isolate) : heap_(isolate->heap()) { diff --git a/src/heap/heap.h b/src/heap/heap.h index 12ae76583d..e8f49de432 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -205,8 +205,8 @@ using v8::MemoryPressureLevel; V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \ V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \ V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \ - V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) \ - V(Smi, interpreter_entry_return_pc_offset, InterpreterEntryReturnPCOffset) + V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) + #define ROOT_LIST(V) \ STRONG_ROOT_LIST(V) \ @@ -794,7 +794,6 @@ class Heap { inline void SetConstructStubDeoptPCOffset(int pc_offset); inline void SetGetterStubDeoptPCOffset(int pc_offset); inline void SetSetterStubDeoptPCOffset(int pc_offset); - inline void SetInterpreterEntryReturnPCOffset(int pc_offset); // For post mortem debugging. void RememberUnmappedPage(Address page, bool compacted); diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc index 232c56bc76..fdf53acd32 100644 --- a/src/ia32/builtins-ia32.cc +++ b/src/ia32/builtins-ia32.cc @@ -620,22 +620,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ mov(ebx, Operand(kInterpreterDispatchTableRegister, ebx, times_pointer_size, 0)); __ call(ebx); - masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); - // The return value is in eax. - - // Get the arguments + reciever count. - __ mov(ebx, Operand(ebp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ mov(ebx, FieldOperand(ebx, BytecodeArray::kParameterSizeOffset)); - - // Leave the frame (also dropping the register file). - __ leave(); - - // Drop receiver + arguments and return. - __ pop(ecx); - __ add(esp, ebx); - __ push(ecx); - __ ret(0); + // Even though the first bytecode handler was called, we will never return. + __ Abort(kUnexpectedReturnFromBytecodeHandler); // Load debug copy of the bytecode array. __ bind(&load_debug_bytecode_array); @@ -661,6 +648,23 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ jmp(ecx); } + +void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { + // The return value is in accumulator, which is already in eax. + + // Leave the frame (also dropping the register file). + __ leave(); + + // Drop receiver + arguments and return. + __ mov(ebx, FieldOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kParameterSizeOffset)); + __ pop(ecx); + __ add(esp, ebx); + __ push(ecx); + __ ret(0); +} + + static void Generate_InterpreterPushArgs(MacroAssembler* masm, Register array_limit) { // ----------- S t a t e ------------- @@ -678,6 +682,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, __ j(greater, &loop_header, Label::kNear); } + // static void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode) { @@ -746,18 +751,8 @@ 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)); - __ LoadHeapObject(ebx, - masm->isolate()->builtins()->InterpreterEntryTrampoline()); - __ add(ebx, Immediate(interpreter_entry_return_pc_offset->value() + - Code::kHeaderSize - kHeapObjectTag)); - __ push(ebx); +static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { // Initialize the dispatch table register. __ mov(kInterpreterDispatchTableRegister, Immediate(ExternalReference::interpreter_dispatch_table_address( @@ -788,6 +783,58 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { __ jmp(ebx); } + +static void Generate_InterpreterNotifyDeoptimizedHelper( + MacroAssembler* masm, Deoptimizer::BailoutType type) { + // Enter an internal frame. + { + FrameScope scope(masm, StackFrame::INTERNAL); + + // Pass the deoptimization type to the runtime system. + __ Push(Smi::FromInt(static_cast(type))); + __ 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 and push PC at top + // of stack (to simulate initial call to bytecode handler in interpreter entry + // trampoline). + __ Pop(ebx); + __ Drop(1); + __ Pop(kInterpreterAccumulatorRegister); + __ Push(ebx); + + // 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. + __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline()); + + Generate_EnterBytecodeDispatch(masm); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : argument count (preserved for callee) @@ -1084,14 +1131,13 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, // Switch on the state. Label not_no_registers, not_tos_eax; - __ cmp(ecx, static_cast(Deoptimizer::BailoutState::NO_REGISTERS)); + __ cmp(ecx, FullCodeGenerator::NO_REGISTERS); __ j(not_equal, ¬_no_registers, Label::kNear); __ ret(1 * kPointerSize); // Remove state. __ bind(¬_no_registers); - DCHECK_EQ(kInterpreterAccumulatorRegister.code(), eax.code()); __ mov(eax, Operand(esp, 2 * kPointerSize)); - __ cmp(ecx, static_cast(Deoptimizer::BailoutState::TOS_REGISTER)); + __ cmp(ecx, FullCodeGenerator::TOS_REG); __ j(not_equal, ¬_tos_eax, Label::kNear); __ ret(2 * kPointerSize); // Remove state, eax. diff --git a/src/interpreter/bytecodes.cc b/src/interpreter/bytecodes.cc index 61d449796e..6604191c59 100644 --- a/src/interpreter/bytecodes.cc +++ b/src/interpreter/bytecodes.cc @@ -149,11 +149,6 @@ int Bytecodes::Size(Bytecode bytecode, OperandScale operand_scale) { } -// static -size_t Bytecodes::ReturnCount(Bytecode bytecode) { - return bytecode == Bytecode::kReturn ? 1 : 0; -} - // static int Bytecodes::NumberOfOperands(Bytecode bytecode) { DCHECK(bytecode <= Bytecode::kLast); diff --git a/src/interpreter/bytecodes.h b/src/interpreter/bytecodes.h index 2f91bf1b14..83c09dbd2e 100644 --- a/src/interpreter/bytecodes.h +++ b/src/interpreter/bytecodes.h @@ -239,7 +239,7 @@ namespace interpreter { /* Non-local flow control */ \ V(Throw, AccumulatorUse::kRead) \ V(ReThrow, AccumulatorUse::kRead) \ - V(Return, AccumulatorUse::kRead) \ + V(Return, AccumulatorUse::kNone) \ \ /* Generators */ \ V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ @@ -509,9 +509,6 @@ class Bytecodes { // Returns the size of |operand|. static OperandSize SizeOfOperand(OperandType operand, OperandScale scale); - // Returns the number of values which |bytecode| returns. - static size_t ReturnCount(Bytecode bytecode); - // Returns true if the bytecode is a conditional jump taking // an immediate byte operand (OperandType::kImm). static bool IsConditionalJumpImmediate(Bytecode bytecode); diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc index fa67a0c299..5f38ea444b 100644 --- a/src/interpreter/interpreter-assembler.cc +++ b/src/interpreter/interpreter-assembler.cc @@ -27,8 +27,7 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, OperandScale operand_scale) : CodeStubAssembler(isolate, zone, InterpreterDispatchDescriptor(isolate), Code::ComputeFlags(Code::BYTECODE_HANDLER), - Bytecodes::ToString(bytecode), - Bytecodes::ReturnCount(bytecode)), + Bytecodes::ToString(bytecode), 0), bytecode_(bytecode), operand_scale_(operand_scale), accumulator_(this, MachineRepresentation::kTagged), @@ -601,7 +600,7 @@ void InterpreterAssembler::DispatchWide(OperandScale operand_scale) { DispatchToBytecodeHandlerEntry(target_code_entry, next_bytecode_offset); } -void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { +compiler::Node* InterpreterAssembler::InterpreterReturn() { // TODO(rmcilroy): Investigate whether it is worth supporting self // optimization of primitive functions like FullCodegen. @@ -611,6 +610,10 @@ void InterpreterAssembler::UpdateInterruptBudgetOnReturn() { Int32Sub(Int32Constant(kHeapObjectTag + BytecodeArray::kHeaderSize), BytecodeOffset()); UpdateInterruptBudget(profiling_weight); + + Node* exit_trampoline_code_object = + HeapConstant(isolate()->builtins()->InterpreterExitTrampoline()); + return DispatchToBytecodeHandler(exit_trampoline_code_object); } Node* InterpreterAssembler::StackCheckTriggeredInterrupt() { diff --git a/src/interpreter/interpreter-assembler.h b/src/interpreter/interpreter-assembler.h index 79ad89efc0..3f44f12980 100644 --- a/src/interpreter/interpreter-assembler.h +++ b/src/interpreter/interpreter-assembler.h @@ -127,8 +127,8 @@ class InterpreterAssembler : public CodeStubAssembler { // Returns true if the stack guard check triggers an interrupt. compiler::Node* StackCheckTriggeredInterrupt(); - // Updates the profiler interrupt budget for a return. - void UpdateInterruptBudgetOnReturn(); + // Returns from the function. + compiler::Node* InterpreterReturn(); // Dispatch to the bytecode. compiler::Node* Dispatch(); diff --git a/src/interpreter/interpreter.cc b/src/interpreter/interpreter.cc index 92529ea9d6..323e9bec6b 100644 --- a/src/interpreter/interpreter.cc +++ b/src/interpreter/interpreter.cc @@ -1642,9 +1642,7 @@ void Interpreter::DoReThrow(InterpreterAssembler* assembler) { // // Return the value in the accumulator. void Interpreter::DoReturn(InterpreterAssembler* assembler) { - __ UpdateInterruptBudgetOnReturn(); - Node* accumulator = __ GetAccumulator(); - __ Return(accumulator); + __ InterpreterReturn(); } // Debugger diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc index 76d0640bc9..cc1baa23bf 100644 --- a/src/mips/builtins-mips.cc +++ b/src/mips/builtins-mips.cc @@ -1051,20 +1051,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Lsa(at, kInterpreterDispatchTableRegister, a0, kPointerSizeLog2); __ lw(at, MemOperand(at)); __ Call(at); - masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); - // The return value is in v0. - - // Get the arguments + reciever count. - __ lw(t0, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ lw(t0, FieldMemOperand(t0, BytecodeArray::kParameterSizeOffset)); - - // Leave the frame (also dropping the register file). - __ LeaveFrame(StackFrame::JAVA_SCRIPT); - - // Drop receiver + arguments and return. - __ Addu(sp, sp, t0); - __ Jump(ra); + // Even though the first bytecode handler was called, we will never return. + __ Abort(kUnexpectedReturnFromBytecodeHandler); // Load debug copy of the bytecode array. __ bind(&load_debug_bytecode_array); @@ -1085,6 +1074,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Jump(t0); } + +void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { + // The return value is in accumulator, which is already in v0. + + // Leave the frame (also dropping the register file). + __ LeaveFrame(StackFrame::JAVA_SCRIPT); + + // Drop receiver + arguments and return. + __ lw(at, FieldMemOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kParameterSizeOffset)); + __ Addu(sp, sp, at); + __ Jump(ra); +} + + // static void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode) { @@ -1117,6 +1121,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( RelocInfo::CODE_TARGET); } + // static void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { // ----------- S t a t e ------------- @@ -1147,16 +1152,8 @@ 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)); - __ li(t0, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline())); - __ Addu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() + - Code::kHeaderSize - kHeapObjectTag)); +static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { // Initialize the dispatch table register. __ li(kInterpreterDispatchTableRegister, Operand(ExternalReference::interpreter_dispatch_table_address( @@ -1190,6 +1187,55 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { __ Jump(a1); } + +static void Generate_InterpreterNotifyDeoptimizedHelper( + MacroAssembler* masm, Deoptimizer::BailoutType type) { + // Enter an internal frame. + { + FrameScope scope(masm, StackFrame::INTERNAL); + + // Pass the deoptimization type to the runtime system. + __ li(a1, Operand(Smi::FromInt(static_cast(type)))); + __ push(a1); + __ 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. + __ li(ra, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline())); + + Generate_EnterBytecodeDispatch(masm); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- a0 : argument count (preserved for callee) @@ -1487,17 +1533,15 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, __ SmiUntag(t2); // Switch on the state. Label with_tos_register, unknown_state; - __ Branch(&with_tos_register, ne, t2, - Operand(static_cast(Deoptimizer::BailoutState::NO_REGISTERS))); + __ Branch(&with_tos_register, + ne, t2, Operand(FullCodeGenerator::NO_REGISTERS)); __ Ret(USE_DELAY_SLOT); // Safe to fill delay slot Addu will emit one instruction. __ Addu(sp, sp, Operand(1 * kPointerSize)); // Remove state. __ bind(&with_tos_register); - DCHECK_EQ(kInterpreterAccumulatorRegister.code(), v0.code()); __ lw(v0, MemOperand(sp, 1 * kPointerSize)); - __ Branch(&unknown_state, ne, t2, - Operand(static_cast(Deoptimizer::BailoutState::TOS_REGISTER))); + __ Branch(&unknown_state, ne, t2, Operand(FullCodeGenerator::TOS_REG)); __ Ret(USE_DELAY_SLOT); // Safe to fill delay slot Addu will emit one instruction. diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc index 202c906144..cca7861e8e 100644 --- a/src/mips64/builtins-mips64.cc +++ b/src/mips64/builtins-mips64.cc @@ -940,6 +940,7 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { Generate_JSEntryTrampolineHelper(masm, true); } + // 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 @@ -1039,20 +1040,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Dlsa(at, kInterpreterDispatchTableRegister, a0, kPointerSizeLog2); __ ld(at, MemOperand(at)); __ Call(at); - masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); - // The return value is in v0. - - // Get the arguments + reciever count. - __ ld(t0, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ lw(t0, FieldMemOperand(t0, BytecodeArray::kParameterSizeOffset)); - - // Leave the frame (also dropping the register file). - __ LeaveFrame(StackFrame::JAVA_SCRIPT); - - // Drop receiver + arguments and return. - __ Daddu(sp, sp, t0); - __ Jump(ra); + // Even though the first bytecode handler was called, we will never return. + __ Abort(kUnexpectedReturnFromBytecodeHandler); // Load debug copy of the bytecode array. __ bind(&load_debug_bytecode_array); @@ -1073,6 +1063,21 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ Jump(a4); } + +void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { + // The return value is in accumulator, which is already in v0. + + // Leave the frame (also dropping the register file). + __ LeaveFrame(StackFrame::JAVA_SCRIPT); + + // Drop receiver + arguments and return. + __ lw(at, FieldMemOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kParameterSizeOffset)); + __ Daddu(sp, sp, at); + __ Jump(ra); +} + + // static void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode) { @@ -1105,6 +1110,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( RelocInfo::CODE_TARGET); } + // static void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { // ----------- S t a t e ------------- @@ -1135,16 +1141,8 @@ 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)); - __ li(t0, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline())); - __ Daddu(ra, t0, Operand(interpreter_entry_return_pc_offset->value() + - Code::kHeaderSize - kHeapObjectTag)); +static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { // Initialize the dispatch table register. __ li(kInterpreterDispatchTableRegister, Operand(ExternalReference::interpreter_dispatch_table_address( @@ -1178,6 +1176,55 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { __ Jump(a1); } + +static void Generate_InterpreterNotifyDeoptimizedHelper( + MacroAssembler* masm, Deoptimizer::BailoutType type) { + // Enter an internal frame. + { + FrameScope scope(masm, StackFrame::INTERNAL); + + // Pass the deoptimization type to the runtime system. + __ li(a1, Operand(Smi::FromInt(static_cast(type)))); + __ push(a1); + __ 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. + __ li(ra, Operand(masm->isolate()->builtins()->InterpreterEntryTrampoline())); + + Generate_EnterBytecodeDispatch(masm); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- a0 : argument count (preserved for callee) @@ -1474,17 +1521,15 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, __ SmiUntag(a6); // Switch on the state. Label with_tos_register, unknown_state; - __ Branch(&with_tos_register, ne, a6, - Operand(static_cast(Deoptimizer::BailoutState::NO_REGISTERS))); + __ Branch(&with_tos_register, + ne, a6, Operand(FullCodeGenerator::NO_REGISTERS)); __ Ret(USE_DELAY_SLOT); // Safe to fill delay slot Addu will emit one instruction. __ Daddu(sp, sp, Operand(1 * kPointerSize)); // Remove state. __ bind(&with_tos_register); - DCHECK_EQ(kInterpreterAccumulatorRegister.code(), v0.code()); __ ld(v0, MemOperand(sp, 1 * kPointerSize)); - __ Branch(&unknown_state, ne, t2, - Operand(static_cast(Deoptimizer::BailoutState::TOS_REGISTER))); + __ Branch(&unknown_state, ne, a6, Operand(FullCodeGenerator::TOS_REG)); __ Ret(USE_DELAY_SLOT); // Safe to fill delay slot Addu will emit one instruction. diff --git a/src/objects.cc b/src/objects.cc index 47285b117a..6f24eee0af 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -13738,9 +13738,8 @@ void DeoptimizationOutputData::DeoptimizationOutputDataPrint( int pc_and_state = this->PcAndState(i)->value(); os << std::setw(6) << this->AstId(i).ToInt() << " " << std::setw(8) << FullCodeGenerator::PcField::decode(pc_and_state) << " " - << Deoptimizer::BailoutStateToString( - FullCodeGenerator::BailoutStateField::decode(pc_and_state)) - << "\n"; + << FullCodeGenerator::State2String( + FullCodeGenerator::StateField::decode(pc_and_state)) << "\n"; } } diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc index 419ee0fa5c..3cbe8178c3 100644 --- a/src/x64/builtins-x64.cc +++ b/src/x64/builtins-x64.cc @@ -699,22 +699,9 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { __ movp(rbx, Operand(kInterpreterDispatchTableRegister, rbx, times_pointer_size, 0)); __ call(rbx); - masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset()); - // The return value is in rax. - - // Get the arguments + reciever count. - __ movp(rbx, Operand(rbp, InterpreterFrameConstants::kBytecodeArrayFromFp)); - __ movl(rbx, FieldOperand(rbx, BytecodeArray::kParameterSizeOffset)); - - // Leave the frame (also dropping the register file). - __ leave(); - - // Drop receiver + arguments and return. - __ PopReturnAddressTo(rcx); - __ addp(rsp, rbx); - __ PushReturnAddressFrom(rcx); - __ ret(0); + // Even though the first bytecode handler was called, we will never return. + __ Abort(kUnexpectedReturnFromBytecodeHandler); // Load debug copy of the bytecode array. __ bind(&load_debug_bytecode_array); @@ -737,6 +724,23 @@ 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). + __ leave(); + + // Drop receiver + arguments and return. + __ movl(rbx, FieldOperand(kInterpreterBytecodeArrayRegister, + BytecodeArray::kParameterSizeOffset)); + __ PopReturnAddressTo(rcx); + __ addp(rsp, rbx); + __ PushReturnAddressFrom(rcx); + __ ret(0); +} + + static void Generate_InterpreterPushArgs(MacroAssembler* masm, bool push_receiver) { // ----------- S t a t e ------------- @@ -767,6 +771,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm, __ j(greater, &loop_header, Label::kNear); } + // static void Builtins::Generate_InterpreterPushArgsAndCallImpl( MacroAssembler* masm, TailCallMode tail_call_mode) { @@ -790,6 +795,7 @@ void Builtins::Generate_InterpreterPushArgsAndCallImpl( RelocInfo::CODE_TARGET); } + // static void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { // ----------- S t a t e ------------- @@ -817,17 +823,8 @@ 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(rbx, masm->isolate()->builtins()->InterpreterEntryTrampoline()); - __ addp(rbx, Immediate(interpreter_entry_return_pc_offset->value() + - Code::kHeaderSize - kHeapObjectTag)); - __ Push(rbx); +static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { // Initialize dispatch table register. __ Move( kInterpreterDispatchTableRegister, @@ -859,6 +856,58 @@ void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { __ jmp(rbx); } + +static void Generate_InterpreterNotifyDeoptimizedHelper( + MacroAssembler* masm, Deoptimizer::BailoutType type) { + // Enter an internal frame. + { + FrameScope scope(masm, StackFrame::INTERNAL); + + // Pass the deoptimization type to the runtime system. + __ Push(Smi::FromInt(static_cast(type))); + __ 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 and push PC at top + // of stack (to simulate initial call to bytecode handler in interpreter entry + // trampoline). + __ Pop(rbx); + __ Drop(1); + __ Pop(kInterpreterAccumulatorRegister); + __ Push(rbx); + + // 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. + __ Push(masm->isolate()->builtins()->InterpreterEntryTrampoline()); + + Generate_EnterBytecodeDispatch(masm); +} + + void Builtins::Generate_CompileLazy(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- rax : argument count (preserved for callee) @@ -1132,16 +1181,13 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, // Switch on the state. Label not_no_registers, not_tos_rax; - __ cmpp(kScratchRegister, - Immediate(static_cast(Deoptimizer::BailoutState::NO_REGISTERS))); + __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::NO_REGISTERS)); __ j(not_equal, ¬_no_registers, Label::kNear); __ ret(1 * kPointerSize); // Remove state. __ bind(¬_no_registers); - DCHECK_EQ(kInterpreterAccumulatorRegister.code(), rax.code()); __ movp(rax, Operand(rsp, kPCOnStackSize + kPointerSize)); - __ cmpp(kScratchRegister, - Immediate(static_cast(Deoptimizer::BailoutState::TOS_REGISTER))); + __ cmpp(kScratchRegister, Immediate(FullCodeGenerator::TOS_REG)); __ j(not_equal, ¬_tos_rax, Label::kNear); __ ret(2 * kPointerSize); // Remove state, rax. diff --git a/test/unittests/interpreter/interpreter-assembler-unittest.cc b/test/unittests/interpreter/interpreter-assembler-unittest.cc index 25b306e359..ebdb16c4b5 100644 --- a/test/unittests/interpreter/interpreter-assembler-unittest.cc +++ b/test/unittests/interpreter/interpreter-assembler-unittest.cc @@ -382,6 +382,32 @@ TARGET_TEST_F(InterpreterAssemblerTest, Jump) { } } +TARGET_TEST_F(InterpreterAssemblerTest, InterpreterReturn) { + // If debug code is enabled we emit extra code in InterpreterReturn. + if (FLAG_debug_code) return; + + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* tail_call_node = m.InterpreterReturn(); + + Handle exit_trampoline = + isolate()->builtins()->InterpreterExitTrampoline(); + Matcher exit_trampoline_entry_matcher = + IsIntPtrAdd(IsHeapConstant(exit_trampoline), + IsIntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); + EXPECT_THAT( + tail_call_node, + IsTailCall( + _, exit_trampoline_entry_matcher, + IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), + IsParameter( + InterpreterDispatchDescriptor::kBytecodeOffsetParameter), + _, + IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), + _, _)); + } +} + TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { static const OperandScale kOperandScales[] = { OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple};