Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc |
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
| index 2d469da6ed55867d5a32e0cdd6c22253888fc1da..2f1935573224ba27dfc77d07df63e3d7cdff360b 100644 |
| --- a/src/ia32/lithium-codegen-ia32.cc |
| +++ b/src/ia32/lithium-codegen-ia32.cc |
| @@ -79,6 +79,9 @@ bool LCodeGen::GenerateCode() { |
| // the frame (that is done in GeneratePrologue). |
| FrameScope frame_scope(masm_, StackFrame::MANUAL); |
| + dynamic_frame_alignment_ = chunk()->num_double_slots() > 2 || |
| + info()->osr_ast_id() != AstNode::kNoNumber; |
| + |
| return GeneratePrologue() && |
| GenerateBody() && |
| GenerateDeferredCode() && |
| @@ -153,6 +156,31 @@ bool LCodeGen::GeneratePrologue() { |
| __ bind(&ok); |
| } |
| + // Move state of dynamic frame alignment into edx. |
| + __ mov(edx, Immediate(kNoAlignmentPadding)); |
| + |
| + if (dynamic_frame_alignment_) { |
| + Label do_not_pad, align_loop; |
| + STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); |
| + // Align esp to a multiple of 2 * kPointerSize. |
| + __ test(esp, Immediate(kPointerSize)); |
| + __ j(zero, &do_not_pad, Label::kNear); |
| + __ push(Immediate(0)); |
| + __ mov(ebx, esp); |
| + __ mov(edx, Immediate(kAlignmentPaddingPushed)); |
| + // Copy arguments, receiver, and return address. |
| + __ mov(ecx, Immediate(scope()->num_parameters() + 2)); |
| + |
| + __ bind(&align_loop); |
| + __ mov(eax, Operand(ebx, 1 * kPointerSize)); |
| + __ mov(Operand(ebx, 0), eax); |
| + __ add(Operand(ebx), Immediate(kPointerSize)); |
| + __ dec(ecx); |
| + __ j(not_zero, &align_loop, Label::kNear); |
| + __ mov(Operand(ebx, 0), Immediate(kAlignmentZapValue)); |
| + __ bind(&do_not_pad); |
| + } |
| + |
| __ push(ebp); // Caller's frame pointer. |
| __ mov(ebp, esp); |
| __ push(esi); // Callee's context. |
| @@ -160,30 +188,32 @@ bool LCodeGen::GeneratePrologue() { |
| // Reserve space for the stack slots needed by the code. |
| int slots = GetStackSlotCount(); |
| - if (slots > 0) { |
| - if (FLAG_debug_code) { |
| - __ mov(Operand(eax), Immediate(slots)); |
| - Label loop; |
| - __ bind(&loop); |
| - __ push(Immediate(kSlotsZapValue)); |
| - __ dec(eax); |
| - __ j(not_zero, &loop); |
| - } else { |
| - __ sub(Operand(esp), Immediate(slots * kPointerSize)); |
| + ASSERT_GE(slots, 1); |
| + if (FLAG_debug_code) { |
| + __ mov(Operand(eax), Immediate(slots)); |
| + Label loop; |
| + __ bind(&loop); |
| + __ push(Immediate(kSlotsZapValue)); |
| + __ dec(eax); |
| + __ j(not_zero, &loop); |
| + } else { |
| + __ sub(Operand(esp), Immediate(slots * kPointerSize)); |
| #ifdef _MSC_VER |
| - // On windows, you may not access the stack more than one page below |
| - // the most recently mapped page. To make the allocated area randomly |
| - // accessible, we write to each page in turn (the value is irrelevant). |
| - const int kPageSize = 4 * KB; |
| - for (int offset = slots * kPointerSize - kPageSize; |
| - offset > 0; |
| - offset -= kPageSize) { |
| - __ mov(Operand(esp, offset), eax); |
| - } |
| -#endif |
| + // On windows, you may not access the stack more than one page below |
| + // the most recently mapped page. To make the allocated area randomly |
| + // accessible, we write to each page in turn (the value is irrelevant). |
| + const int kPageSize = 4 * KB; |
| + for (int offset = slots * kPointerSize - kPageSize; |
| + offset > 0; |
| + offset -= kPageSize) { |
| + __ mov(Operand(esp, offset), eax); |
| } |
| +#endif |
| } |
| + // Store dynamic frame alignment state in the first local. |
| + __ mov(Operand(ebp, JavaScriptFrameConstants::kLocal0Offset), edx); |
|
danno
2012/06/11 10:53:14
To reduce the theoretical expense of the tag in th
|
| + |
| // Possibly allocate a local context. |
| int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
| if (heap_slots > 0) { |
| @@ -2098,8 +2128,24 @@ void LCodeGen::DoReturn(LReturn* instr) { |
| __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| __ CallRuntime(Runtime::kTraceExit, 1); |
| } |
| + if (dynamic_frame_alignment_) { |
| + // Fetch the state of the dynamic frame alignment. |
| + __ mov(edx, Operand(ebp, JavaScriptFrameConstants::kLocal0Offset)); |
|
danno
2012/06/11 10:53:14
Can you alias something like kFrameAlignmentCookie
|
| + } |
| __ mov(esp, ebp); |
| __ pop(ebp); |
| + if (dynamic_frame_alignment_) { |
| + Label no_padding; |
| + __ cmp(edx, Immediate(kNoAlignmentPadding)); |
| + __ j(equal, &no_padding); |
| + if (FLAG_debug_code) { |
| + __ cmp(Operand(esp, (GetParameterCount() + 2) * kPointerSize), |
| + Immediate(kAlignmentZapValue)); |
| + __ Assert(equal, "expected alignment marker"); |
| + } |
| + __ Ret((GetParameterCount() + 2) * kPointerSize, ecx); |
| + __ bind(&no_padding); |
| + } |
| __ Ret((GetParameterCount() + 1) * kPointerSize, ecx); |
| } |