Commit 7a51f8c8 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: [runtime] Unify and simplify how frames are marked.

  port 9dcd0857 (r34571)

  original commit message:
  Before this CL, various code stubs used different techniques
  for marking their frames to enable stack-crawling and other
  access to data in the frame. All of them were based on a abuse
  of the "standard" frame representation, e.g. storing the a
  context pointer immediately below the frame's fp, and a
  function pointer after that. Although functional, this approach
  tends to make stubs and builtins do an awkward, unnecessary
  dance to appear like standard frames, even if they have
  nothing to do with JavaScript execution.

  This CL attempts to improve this by:

  * Ensuring that there are only two fundamentally different
    types of frames, a "standard" frame and a "typed" frame.
    Standard frames, as before, contain both a context and
    function pointer. Typed frames contain only a minimum
    of a smi marker in the position immediately below the fp
    where the context is in standard frames.
  * Only interpreted, full codegen, and optimized Crankshaft and
    TurboFan JavaScript frames use the "standard" format. All
    other frames use the type frame format with an explicit
    marker.
  * Typed frames can contain one or more values below the
    type marker. There is new magic macro machinery in
    frames.h that simplifies defining the offsets of these fields
    in typed frames.
  * A new flag in the CallDescriptor enables specifying whether
    a frame is a standard frame or a typed frame. Secondary
    register location spilling is now only enabled for standard
    frames.
  * A zillion places in the code have been updated to deal with
    the fact that most code stubs and internal frames use the
    typed frame format. This includes changes in the
    deoptimizer, debugger, and liveedit.
  * StandardFrameConstants::kMarkerOffset is deprecated,
    (CommonFrameConstants::kContextOrFrameTypeOffset
    and StandardFrameConstants::kFrameOffset are now used
    in its stead).

BUG=

Review URL: https://codereview.chromium.org/1774353002

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