Index: src/ia32/deoptimizer-ia32.cc |
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc |
index 313b65f6e2168fe4fd0371083d103a90f493b83b..7779be389beb870f2886c4a131a13e568fc5baf3 100644 |
--- a/src/ia32/deoptimizer-ia32.cc |
+++ b/src/ia32/deoptimizer-ia32.cc |
@@ -440,6 +440,14 @@ void Deoptimizer::DoComputeOsrOutputFrame() { |
output_[0]->SetContinuation( |
reinterpret_cast<uint32_t>(continuation->entry())); |
+ // All OSR stack frames are dynamically aligned to an 8-byte boundary. |
+ int frame_pointer = output_[0]->GetRegister(ebp.code()); |
Kevin Millikin (Chromium)
2011/09/23 09:38:49
Don't put this here (i.e., don't set ebp register
|
+ if ((frame_pointer & 0x4) == 0) { |
+ // Return address at FP + 4 should be aligned, so FP mod 8 should be 4. |
+ output_[0]->SetRegister(ebp.code(), frame_pointer - kPointerSize); |
+ has_alignment_padding_ = 1; |
+ } |
+ |
if (FLAG_trace_osr) { |
PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", |
ok ? "finished" : "aborted", |
@@ -490,6 +498,15 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator, |
// the input frame pointer and the output frame's height. For all |
// subsequent output frames, it can be computed from the previous one's |
// top address and the current frame's size. |
+ |
+ // If the optimized frame had alignment padding, adjust the frame pointer |
Kevin Millikin (Chromium)
2011/09/23 09:38:49
I also don't like this here. First, it breaks up
William Hesse
2011/09/23 12:50:11
Done.
|
+ // to point to the new position of the old frame pointer after padding |
+ // is removed. |
+ if (has_alignment_padding_ == 1) { |
+ input_->SetRegister(ebp.code(), |
+ input_->GetRegister(ebp.code()) + kPointerSize); |
+ } |
+ |
uint32_t top_address; |
if (is_bottommost) { |
// 2 = context and function in the frame. |
@@ -734,6 +751,17 @@ void Deoptimizer::EntryGenerator::Generate() { |
__ cmp(ecx, Operand(esp)); |
__ j(not_equal, &pop_loop); |
+ // If frame was dynamically aligned, pop padding. |
+ Label sentinel, sentinel_done; |
+ __ pop(Operand(ecx)); |
+ __ cmp(ecx, Operand(eax, Deoptimizer::frame_alignment_marker_offset())); |
+ __ j(equal, &sentinel); |
+ __ push(Operand(ecx)); |
+ __ jmp(&sentinel_done); |
+ __ bind(&sentinel); |
+ __ mov(Operand(eax, Deoptimizer::has_alignment_padding_offset()), |
+ Immediate(1)); |
+ __ bind(&sentinel_done); |
// Compute the output frame in the deoptimizer. |
__ push(eax); |
__ PrepareCallCFunction(1, ebx); |
@@ -745,6 +773,17 @@ void Deoptimizer::EntryGenerator::Generate() { |
} |
__ pop(eax); |
+ if (type() == OSR) { |
+ // If alignment padding is added, push the sentinel. |
+ Label no_osr_padding; |
+ __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), |
+ Immediate(0)); |
+ __ j(equal, &no_osr_padding, Label::kNear); |
+ __ push(Operand(eax, Deoptimizer::frame_alignment_marker_offset())); |
+ __ bind(&no_osr_padding); |
+ } |
+ |
+ |
// Replace the current frame with the output frames. |
Label outer_push_loop, inner_push_loop; |
// Outer loop state: eax = current FrameDescription**, edx = one past the |