Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index 900cb58b715b3ea1d0f3afcfeb2cb87e67335385..326e757f6180de273d55b3efd74faec556700cef 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -100,6 +100,34 @@ void MacroAssembler::StoreRoot(Register source, |
sw(source, MemOperand(s6, index << kPointerSizeLog2)); |
} |
+void MacroAssembler::PushCommonFrame(Register marker_reg) { |
+ if (marker_reg.is_valid()) { |
+ Push(ra, fp, marker_reg); |
+ Addu(fp, sp, Operand(kPointerSize)); |
+ } else { |
+ Push(ra, fp); |
+ mov(fp, sp); |
+ } |
+} |
+ |
+void MacroAssembler::PopCommonFrame(Register marker_reg) { |
+ if (marker_reg.is_valid()) { |
+ Pop(ra, fp, marker_reg); |
+ } else { |
+ Pop(ra, fp); |
+ } |
+} |
+ |
+void MacroAssembler::PushStandardFrame(Register function_reg) { |
+ int offset = -StandardFrameConstants::kContextOffset; |
+ if (function_reg.is_valid()) { |
+ Push(ra, fp, cp, function_reg); |
+ offset += kPointerSize; |
+ } else { |
+ Push(ra, fp, cp); |
+ } |
+ Addu(fp, sp, Operand(offset)); |
+} |
// Push and pop all registers that can hold pointers. |
void MacroAssembler::PushSafepointRegisters() { |
@@ -486,8 +514,18 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
DCHECK(!holder_reg.is(at)); |
DCHECK(!scratch.is(at)); |
- // Load current lexical context from the stack frame. |
- lw(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
+ // Load current lexical context from the active StandardFrame, which |
+ // may require crawling past STUB frames. |
+ Label load_context; |
+ Label has_context; |
+ mov(at, fp); |
+ bind(&load_context); |
+ lw(scratch, MemOperand(at, CommonFrameConstants::kContextOrFrameTypeOffset)); |
+ JumpIfNotSmi(scratch, &has_context); |
+ lw(at, MemOperand(at, CommonFrameConstants::kCallerFPOffset)); |
+ b(&load_context); |
+ bind(&has_context); |
+ |
// In debug mode, make sure the lexical context is set. |
#ifdef DEBUG |
Check(ne, kWeShouldNotHaveAnEmptyLexicalContext, |
@@ -4938,12 +4976,9 @@ void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
} |
} |
- |
-void MacroAssembler::StubPrologue() { |
- Push(ra, fp, cp); |
- Push(Smi::FromInt(StackFrame::STUB)); |
- // Adjust FP to point to saved FP. |
- Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
+void MacroAssembler::StubPrologue(StackFrame::Type type) { |
+ li(at, Operand(Smi::FromInt(type))); |
+ PushCommonFrame(at); |
} |
@@ -4966,10 +5001,8 @@ void MacroAssembler::Prologue(bool code_pre_aging) { |
nop(); // Branch delay slot nop. |
nop(); // Pad the empty space. |
} else { |
- Push(ra, fp, cp, a1); |
+ PushStandardFrame(a1); |
nop(Assembler::CODE_AGE_SEQUENCE_NOP); |
- // Adjust fp to point to caller's fp. |
- Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
} |
} |
@@ -4990,30 +5023,41 @@ void MacroAssembler::EnterFrame(StackFrame::Type type, |
void MacroAssembler::EnterFrame(StackFrame::Type type) { |
- addiu(sp, sp, -5 * kPointerSize); |
- li(t8, Operand(Smi::FromInt(type))); |
- li(t9, Operand(CodeObject()), CONSTANT_SIZE); |
- sw(ra, MemOperand(sp, 4 * kPointerSize)); |
- sw(fp, MemOperand(sp, 3 * kPointerSize)); |
- sw(cp, MemOperand(sp, 2 * kPointerSize)); |
- sw(t8, MemOperand(sp, 1 * kPointerSize)); |
- sw(t9, MemOperand(sp, 0 * kPointerSize)); |
+ int stack_offset, fp_offset; |
+ if (type == StackFrame::INTERNAL) { |
+ stack_offset = -4 * kPointerSize; |
+ fp_offset = 2 * kPointerSize; |
+ } else { |
+ stack_offset = -3 * kPointerSize; |
+ fp_offset = 1 * kPointerSize; |
+ } |
+ addiu(sp, sp, stack_offset); |
+ stack_offset = -stack_offset - kPointerSize; |
+ sw(ra, MemOperand(sp, stack_offset)); |
+ stack_offset -= kPointerSize; |
+ sw(fp, MemOperand(sp, stack_offset)); |
+ stack_offset -= kPointerSize; |
+ li(t9, Operand(Smi::FromInt(type))); |
+ sw(t9, MemOperand(sp, stack_offset)); |
+ if (type == StackFrame::INTERNAL) { |
+ DCHECK_EQ(stack_offset, kPointerSize); |
+ li(t9, Operand(CodeObject())); |
+ sw(t9, MemOperand(sp, 0)); |
+ } else { |
+ DCHECK_EQ(stack_offset, 0); |
+ } |
// Adjust FP to point to saved FP. |
- Addu(fp, sp, |
- Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); |
+ Addu(fp, sp, Operand(fp_offset)); |
} |
void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
- mov(sp, fp); |
- lw(fp, MemOperand(sp, 0 * kPointerSize)); |
- lw(ra, MemOperand(sp, 1 * kPointerSize)); |
- addiu(sp, sp, 2 * kPointerSize); |
+ addiu(sp, fp, 2 * kPointerSize); |
+ lw(ra, MemOperand(fp, 1 * kPointerSize)); |
+ lw(fp, MemOperand(fp, 0 * kPointerSize)); |
} |
- |
-void MacroAssembler::EnterExitFrame(bool save_doubles, |
- int stack_space) { |
+void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { |
// Set up the frame structure on the stack. |
STATIC_ASSERT(2 * kPointerSize == ExitFrameConstants::kCallerSPDisplacement); |
STATIC_ASSERT(1 * kPointerSize == ExitFrameConstants::kCallerPCOffset); |
@@ -5023,16 +5067,20 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, |
// fp + 2 (==kCallerSPDisplacement) - old stack's end |
// [fp + 1 (==kCallerPCOffset)] - saved old ra |
// [fp + 0 (==kCallerFPOffset)] - saved old fp |
- // [fp - 1 (==kSPOffset)] - sp of the called function |
- // [fp - 2 (==kCodeOffset)] - CodeObject |
+ // [fp - 1 StackFrame::EXIT Smi |
+ // [fp - 2 (==kSPOffset)] - sp of the called function |
+ // [fp - 3 (==kCodeOffset)] - CodeObject |
// fp - (2 + stack_space + alignment) == sp == [fp - kSPOffset] - top of the |
// new stack (will contain saved ra) |
- // Save registers. |
- addiu(sp, sp, -4 * kPointerSize); |
- sw(ra, MemOperand(sp, 3 * kPointerSize)); |
- sw(fp, MemOperand(sp, 2 * kPointerSize)); |
- addiu(fp, sp, 2 * kPointerSize); // Set up new frame pointer. |
+ // Save registers and reserve room for saved entry sp and code object. |
+ addiu(sp, sp, -2 * kPointerSize - ExitFrameConstants::kFixedFrameSizeFromFp); |
+ sw(ra, MemOperand(sp, 4 * kPointerSize)); |
+ sw(fp, MemOperand(sp, 3 * kPointerSize)); |
+ li(at, Operand(Smi::FromInt(StackFrame::EXIT))); |
+ sw(at, MemOperand(sp, 2 * kPointerSize)); |
+ // Set up new frame pointer. |
+ addiu(fp, sp, ExitFrameConstants::kFixedFrameSizeFromFp); |
if (emit_debug_code()) { |
sw(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset)); |