diff --git a/src/compiler/x87/code-generator-x87.cc b/src/compiler/x87/code-generator-x87.cc index 82a2d14c51..272218b76b 100644 --- a/src/compiler/x87/code-generator-x87.cc +++ b/src/compiler/x87/code-generator-x87.cc @@ -2006,16 +2006,15 @@ void CodeGenerator::AssembleDeoptimizerCall( void CodeGenerator::AssemblePrologue() { CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); - if (descriptor->IsCFunctionCall()) { - // Assemble a prologue similar the to cdecl calling convention. - __ push(ebp); - __ mov(ebp, esp); - } else if (descriptor->IsJSFunctionCall()) { - // TODO(turbofan): this prologue is redundant with OSR, but needed for - // code aging. - __ Prologue(this->info()->GeneratePreagedPrologue()); - } else if (frame()->needs_frame()) { - __ StubPrologue(); + if (frame()->needs_frame()) { + if (descriptor->IsCFunctionCall()) { + __ push(ebp); + __ mov(ebp, esp); + } else if (descriptor->IsJSFunctionCall()) { + __ Prologue(this->info()->GeneratePreagedPrologue()); + } else { + __ StubPrologue(info()->GetOutputStackFrameType()); + } } else { frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize); } diff --git a/src/crankshaft/x87/lithium-codegen-x87.cc b/src/crankshaft/x87/lithium-codegen-x87.cc index f71b8ba866..612f8e57cb 100644 --- a/src/crankshaft/x87/lithium-codegen-x87.cc +++ b/src/crankshaft/x87/lithium-codegen-x87.cc @@ -98,7 +98,7 @@ bool LCodeGen::GeneratePrologue() { DCHECK(!frame_is_built_); frame_is_built_ = true; if (info()->IsStub()) { - __ StubPrologue(); + __ StubPrologue(StackFrame::STUB); } else { __ Prologue(info()->GeneratePreagedPrologue()); } @@ -273,32 +273,24 @@ bool LCodeGen::GenerateJumpTable() { } if (needs_frame.is_linked()) { __ bind(&needs_frame); - /* stack layout - 4: entry address - 3: return address <-- esp - 2: garbage + 3: entry address + 2: return address <-- esp 1: garbage 0: garbage */ - __ sub(esp, Immediate(kPointerSize)); // Reserve space for stub marker. - __ push(MemOperand(esp, kPointerSize)); // Copy return address. - __ push(MemOperand(esp, 3 * kPointerSize)); // Copy entry address. + __ push(MemOperand(esp, 0)); // Copy return address. + __ push(MemOperand(esp, 2 * kPointerSize)); // Copy entry address. /* stack layout 4: entry address 3: return address - 2: garbage 1: return address 0: entry address <-- esp */ - __ mov(MemOperand(esp, 4 * kPointerSize), ebp); // Save ebp. - - // Copy context. - __ mov(ebp, MemOperand(ebp, StandardFrameConstants::kContextOffset)); - __ mov(MemOperand(esp, 3 * kPointerSize), ebp); + __ mov(MemOperand(esp, 3 * kPointerSize), ebp); // Save ebp. // Fill ebp with the right stack frame address. - __ lea(ebp, MemOperand(esp, 4 * kPointerSize)); + __ lea(ebp, MemOperand(esp, 3 * kPointerSize)); // This variant of deopt can only be used with stubs. Since we don't // have a function pointer to install in the stack frame that we're @@ -308,8 +300,7 @@ bool LCodeGen::GenerateJumpTable() { Immediate(Smi::FromInt(StackFrame::STUB))); /* stack layout - 4: old ebp - 3: context pointer + 3: old ebp 2: stub marker 1: return address 0: entry address <-- esp @@ -346,9 +337,8 @@ bool LCodeGen::GenerateDeferredCode() { frame_is_built_ = true; // Build the frame in such a way that esi isn't trashed. __ push(ebp); // Caller's frame pointer. - __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); __ push(Immediate(Smi::FromInt(StackFrame::STUB))); - __ lea(ebp, Operand(esp, 2 * kPointerSize)); + __ lea(ebp, Operand(esp, TypedFrameConstants::kFixedFrameSizeFromFp)); Comment(";;; Deferred code"); } code->Generate(); @@ -3088,7 +3078,8 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { // Check for arguments adapter frame. Label done, adapted; __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); - __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); + __ mov(result, + Operand(result, CommonFrameConstants::kContextOrFrameTypeOffset)); __ cmp(Operand(result), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); __ j(equal, &adapted, Label::kNear); diff --git a/src/debug/x87/debug-x87.cc b/src/debug/x87/debug-x87.cc index 8ddb82f39d..28b635b326 100644 --- a/src/debug/x87/debug-x87.cc +++ b/src/debug/x87/debug-x87.cc @@ -110,9 +110,12 @@ void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { // We do not know our frame height, but set esp based on ebp. - __ lea(esp, Operand(ebp, -1 * kPointerSize)); - + __ lea(esp, Operand(ebp, FrameDropperFrameConstants::kFunctionOffset)); __ pop(edi); // Function. + __ add(esp, Immediate(-FrameDropperFrameConstants::kCodeOffset)); // INTERNAL + // frame + // marker + // and code __ pop(ebp); ParameterCount dummy(0); diff --git a/src/ic/x87/handler-compiler-x87.cc b/src/ic/x87/handler-compiler-x87.cc index e1eea1af7a..dc035b0b5d 100644 --- a/src/ic/x87/handler-compiler-x87.cc +++ b/src/ic/x87/handler-compiler-x87.cc @@ -23,6 +23,9 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( { FrameScope scope(masm, StackFrame::INTERNAL); + // Save context register + __ push(esi); + if (accessor_index >= 0) { DCHECK(!holder.is(scratch)); DCHECK(!receiver.is(scratch)); @@ -46,7 +49,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter( } // Restore context register. - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ pop(esi); } __ ret(0); } @@ -252,6 +255,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( { FrameScope scope(masm, StackFrame::INTERNAL); + // Save context register + __ push(esi); // Save value register, so we can restore it later. __ push(value()); @@ -280,9 +285,8 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter( // We have to return the passed value, not the return value of the setter. __ pop(eax); - // Restore context register. - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ pop(esi); } __ ret(0); } diff --git a/src/x87/builtins-x87.cc b/src/x87/builtins-x87.cc index 2139cff6a5..84f088fa18 100644 --- a/src/x87/builtins-x87.cc +++ b/src/x87/builtins-x87.cc @@ -123,6 +123,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, bool check_derived_construct) { // ----------- S t a t e ------------- // -- eax: number of arguments + // -- esi: context // -- edi: constructor function // -- ebx: allocation site or undefined // -- edx: new target @@ -134,6 +135,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, // Preserve the incoming parameters on the stack. __ AssertUndefinedOrAllocationSite(ebx); + __ push(esi); __ push(ebx); __ SmiTag(eax); __ push(eax); @@ -201,7 +203,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, } // Restore context from the frame. - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ mov(esi, Operand(ebp, ConstructFrameConstants::kContextOffset)); if (create_implicit_receiver) { // If the result is an object (in the ECMA sense), we should get rid @@ -325,9 +327,6 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, bool is_construct) { ProfileEntryHookStub::MaybeCallEntryHook(masm); - // Clear the context before we push it when entering the internal frame. - __ Move(esi, Immediate(0)); - { FrameScope scope(masm, StackFrame::INTERNAL); @@ -1899,7 +1898,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg, // Drop possible interpreter handler/stub frame. { Label no_interpreter_frame; - __ cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), + __ cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), Immediate(Smi::FromInt(StackFrame::STUB))); __ j(not_equal, &no_interpreter_frame, Label::kNear); __ mov(ebp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); @@ -1910,7 +1909,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg, Register caller_args_count_reg = scratch1; Label no_arguments_adaptor, formal_parameter_count_loaded; __ mov(scratch2, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); - __ cmp(Operand(scratch2, StandardFrameConstants::kContextOffset), + __ cmp(Operand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); __ j(not_equal, &no_arguments_adaptor, Label::kNear); @@ -2457,7 +2456,7 @@ void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { // Call the entry point. __ bind(&invoke); // Restore function pointer. - __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); + __ mov(edi, Operand(ebp, ArgumentsAdaptorFrameConstants::kFunctionOffset)); // eax : expected number of arguments // edx : new target (passed through to callee) // edi : function (passed through to callee) diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc index a62f1d2117..b7b6ad5526 100644 --- a/src/x87/code-stubs-x87.cc +++ b/src/x87/code-stubs-x87.cc @@ -1720,8 +1720,9 @@ void JSEntryStub::Generate(MacroAssembler* masm) { // Push marker in two places. int marker = type(); - __ push(Immediate(Smi::FromInt(marker))); // context slot - __ push(Immediate(Smi::FromInt(marker))); // function slot + __ push(Immediate(Smi::FromInt(marker))); // marker + ExternalReference context_address(Isolate::kContextAddress, isolate()); + __ push(Operand::StaticVariable(context_address)); // context // Save callee-saved registers (C calling conventions). __ push(edi); __ push(esi); @@ -3385,7 +3386,7 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) { CEntryStub ces(isolate(), 1, kSaveFPRegs); __ call(ces.GetCode(), RelocInfo::CODE_TARGET); int parameter_count_offset = - StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset; + StubFailureTrampolineFrameConstants::kArgumentsLengthOffset; __ mov(ebx, MemOperand(ebp, parameter_count_offset)); masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); __ pop(ecx); @@ -4531,7 +4532,7 @@ void FastNewRestParameterStub::Generate(MacroAssembler* masm) { __ bind(&loop); __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); __ bind(&loop_entry); - __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset)); + __ cmp(edi, Operand(edx, StandardFrameConstants::kFunctionOffset)); __ j(not_equal, &loop); } @@ -4539,7 +4540,7 @@ void FastNewRestParameterStub::Generate(MacroAssembler* masm) { // arguments adaptor frame below the function frame). Label no_rest_parameters; __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); - __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), + __ cmp(Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); __ j(not_equal, &no_rest_parameters, Label::kNear); @@ -4681,7 +4682,7 @@ void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) { // Check if the calling frame is an arguments adaptor frame. Label adaptor_frame, try_allocate, runtime; __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); - __ mov(eax, Operand(ebx, StandardFrameConstants::kContextOffset)); + __ mov(eax, Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset)); __ cmp(eax, Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); __ j(equal, &adaptor_frame, Label::kNear); @@ -4917,14 +4918,14 @@ void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) { __ bind(&loop); __ mov(edx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); __ bind(&loop_entry); - __ cmp(edi, Operand(edx, StandardFrameConstants::kMarkerOffset)); + __ cmp(edi, Operand(edx, StandardFrameConstants::kFunctionOffset)); __ j(not_equal, &loop); } // Check if we have an arguments adaptor frame below the function frame. Label arguments_adaptor, arguments_done; __ mov(ebx, Operand(edx, StandardFrameConstants::kCallerFPOffset)); - __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), + __ cmp(Operand(ebx, CommonFrameConstants::kContextOrFrameTypeOffset), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); __ j(equal, &arguments_adaptor, Label::kNear); { diff --git a/src/x87/deoptimizer-x87.cc b/src/x87/deoptimizer-x87.cc index f31f915efd..99c31f26e2 100644 --- a/src/x87/deoptimizer-x87.cc +++ b/src/x87/deoptimizer-x87.cc @@ -246,7 +246,12 @@ void Deoptimizer::TableEntryGenerator::Generate() { __ push(edi); // Allocate a new deoptimizer object. __ PrepareCallCFunction(6, eax); + __ mov(eax, Immediate(0)); + Label context_check; + __ mov(edi, Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset)); + __ JumpIfSmi(edi, &context_check); __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); + __ bind(&context_check); __ mov(Operand(esp, 0 * kPointerSize), eax); // Function. __ mov(Operand(esp, 1 * kPointerSize), Immediate(type())); // Bailout type. __ mov(Operand(esp, 2 * kPointerSize), ebx); // Bailout id. diff --git a/src/x87/frames-x87.h b/src/x87/frames-x87.h index 275713705b..1a378ed3ec 100644 --- a/src/x87/frames-x87.h +++ b/src/x87/frames-x87.h @@ -42,13 +42,11 @@ class EntryFrameConstants : public AllStatic { static const int kArgvOffset = +6 * kPointerSize; }; - -class ExitFrameConstants : public AllStatic { +class ExitFrameConstants : public TypedFrameConstants { public: - static const int kFrameSize = 2 * kPointerSize; - - static const int kCodeOffset = -2 * kPointerSize; - static const int kSPOffset = -1 * kPointerSize; + static const int kSPOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0); + static const int kCodeOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1); + DEFINE_TYPED_FRAME_SIZES(2); static const int kCallerFPOffset = 0 * kPointerSize; static const int kCallerPCOffset = +1 * kPointerSize; @@ -66,7 +64,7 @@ class JavaScriptFrameConstants : public AllStatic { // FP-relative. static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset; static const int kLastParameterOffset = +2 * kPointerSize; - static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset; + static const int kFunctionOffset = StandardFrameConstants::kFunctionOffset; // Caller SP-relative. static const int kParam0Offset = -2 * kPointerSize; diff --git a/src/x87/macro-assembler-x87.cc b/src/x87/macro-assembler-x87.cc index d350343b93..0434119c4e 100644 --- a/src/x87/macro-assembler-x87.cc +++ b/src/x87/macro-assembler-x87.cc @@ -954,12 +954,10 @@ void MacroAssembler::AssertNotSmi(Register object) { } } - -void MacroAssembler::StubPrologue() { +void MacroAssembler::StubPrologue(StackFrame::Type type) { push(ebp); // Caller's frame pointer. mov(ebp, esp); - push(esi); // Callee's context. - push(Immediate(Smi::FromInt(StackFrame::STUB))); + push(Immediate(Smi::FromInt(type))); } @@ -997,9 +995,10 @@ void MacroAssembler::EnterFrame(StackFrame::Type type, void MacroAssembler::EnterFrame(StackFrame::Type type) { push(ebp); mov(ebp, esp); - push(esi); push(Immediate(Smi::FromInt(type))); - push(Immediate(CodeObject())); + if (type == StackFrame::INTERNAL) { + push(Immediate(CodeObject())); + } if (emit_debug_code()) { cmp(Operand(esp, 0), Immediate(isolate()->factory()->undefined_value())); Check(not_equal, kCodeObjectNotProperlyPatched); @@ -1009,7 +1008,7 @@ void MacroAssembler::EnterFrame(StackFrame::Type type) { void MacroAssembler::LeaveFrame(StackFrame::Type type) { if (emit_debug_code()) { - cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), + cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), Immediate(Smi::FromInt(type))); Check(equal, kStackFrameTypesMustMatch); } @@ -1019,15 +1018,17 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) { void MacroAssembler::EnterExitFramePrologue() { // Set up the frame structure on the stack. - DCHECK(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); - DCHECK(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); - DCHECK(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); + DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); + DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); + DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); push(ebp); mov(ebp, esp); // Reserve room for entry stack pointer and push the code object. - DCHECK(ExitFrameConstants::kSPOffset == -1 * kPointerSize); + push(Immediate(Smi::FromInt(StackFrame::EXIT))); + DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); push(Immediate(0)); // Saved entry sp, patched before call. + DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. // Save the frame pointer and the context in top. @@ -1046,7 +1047,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { // Store FPU state to m108byte. int space = 108 + argc * kPointerSize; sub(esp, Immediate(space)); - const int offset = -2 * kPointerSize; // entry fp + code object. + const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; fnsave(MemOperand(ebp, offset - 108)); } else { sub(esp, Immediate(argc * kPointerSize)); @@ -1086,7 +1087,7 @@ void MacroAssembler::EnterApiExitFrame(int argc) { void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { // Optionally restore FPU state. if (save_doubles) { - const int offset = -2 * kPointerSize; + const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; frstor(MemOperand(ebp, offset - 108)); } @@ -1166,8 +1167,18 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, DCHECK(!holder_reg.is(scratch2)); DCHECK(!scratch1.is(scratch2)); - // Load current lexical context from the stack frame. - mov(scratch1, Operand(ebp, StandardFrameConstants::kContextOffset)); + // Load current lexical context from the active StandardFrame, which + // may require crawling past STUB frames. + Label load_context; + Label has_context; + mov(scratch2, ebp); + bind(&load_context); + mov(scratch1, + MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset)); + JumpIfNotSmi(scratch1, &has_context); + mov(scratch2, MemOperand(scratch2, CommonFrameConstants::kCallerFPOffset)); + jmp(&load_context); + bind(&has_context); // When generating debug code, make sure the lexical context is set. if (emit_debug_code()) { diff --git a/src/x87/macro-assembler-x87.h b/src/x87/macro-assembler-x87.h index 4feb62dd8f..e345314452 100644 --- a/src/x87/macro-assembler-x87.h +++ b/src/x87/macro-assembler-x87.h @@ -236,7 +236,7 @@ class MacroAssembler: public Assembler { void DebugBreak(); // Generates function and stub prologue code. - void StubPrologue(); + void StubPrologue(StackFrame::Type type); void Prologue(bool code_pre_aging); // Enter specific kind of exit frame. Expects the number of