Chromium Code Reviews| Index: src/ia32/deoptimizer-ia32.cc |
| diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc |
| index 73961e1416deb7654e17845bddde94531d821c01..13c13c94c60b35929b37c000b52854e27a9a0126 100644 |
| --- a/src/ia32/deoptimizer-ia32.cc |
| +++ b/src/ia32/deoptimizer-ia32.cc |
| @@ -415,6 +415,23 @@ void Deoptimizer::DoComputeOsrOutputFrame() { |
| output_offset -= kPointerSize; |
| } |
| + // All OSR stack frames are dynamically aligned to an 8-byte boundary. |
|
Massi
2012/06/11 10:03:32
Why don't we need to (eventually) move the incomin
Vyacheslav Egorov (Google)
2012/06/11 11:02:43
Incomming arguments are part of the frame translat
|
| + int frame_pointer = input_->GetRegister(ebp.code()); |
| + if ((frame_pointer & 0x4) == 0) { |
| + // Return address at FP + 4 should be aligned, so FP mod 8 should be 4. |
| + frame_pointer -= kPointerSize; |
| + has_alignment_padding_ = 1; |
| + } |
| + |
| + int32_t alignment_marker = has_alignment_padding_ ? 2 : 0; |
| + if (FLAG_trace_osr) { |
| + PrintF(" [esp + %d] <- 0x%08x ; (alignment marker)\n", |
| + output_offset, |
| + alignment_marker); |
| + } |
| + output_[0]->SetFrameSlot(output_offset, alignment_marker); |
| + output_offset -= kPointerSize; |
| + |
| // Translate the rest of the frame. |
| while (ok && input_offset >= 0) { |
| ok = DoOsrTranslateCommand(&iterator, &input_offset); |
| @@ -427,7 +444,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() { |
| output_[0]->SetPc(reinterpret_cast<uint32_t>(from_)); |
| } else { |
| // Set up the frame pointer and the context pointer. |
| - output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code())); |
| + output_[0]->SetRegister(ebp.code(), frame_pointer); |
| output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); |
| unsigned pc_offset = data->OsrPcOffset()->value(); |
| @@ -688,24 +705,35 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
| ASSERT(output_[frame_index] == NULL); |
| output_[frame_index] = output_frame; |
| + // Compute the incoming parameter translation. |
| + int parameter_count = function->shared()->formal_parameter_count() + 1; |
| + unsigned output_offset = output_frame_size; |
| + unsigned input_offset = input_frame_size; |
| + |
| + unsigned alignment_marker_offset = |
| + input_offset - parameter_count * kPointerSize - |
| + StandardFrameConstants::kFixedFrameSize - |
| + kPointerSize; |
| + |
| // The top address for the bottommost output frame can be computed from |
| // 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. |
| uint32_t top_address; |
| if (is_bottommost) { |
| + has_alignment_padding_ = |
| + (input_->GetFrameSlot(alignment_marker_offset) == 2) ? 1 : 0; |
| // 2 = context and function in the frame. |
| - top_address = |
| - input_->GetRegister(ebp.code()) - (2 * kPointerSize) - height_in_bytes; |
| + // If the optimized frame had alignment padding, adjust the frame pointer |
| + // to point to the new position of the old frame pointer after padding |
| + // is removed. Subtract 2 * kPointerSize for the context and function slots. |
| + top_address = input_->GetRegister(ebp.code()) - (2 * kPointerSize) - |
| + height_in_bytes + has_alignment_padding_ * kPointerSize; |
| } else { |
| top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| } |
| output_frame->SetTop(top_address); |
| - // Compute the incoming parameter translation. |
| - int parameter_count = function->shared()->formal_parameter_count() + 1; |
| - unsigned output_offset = output_frame_size; |
| - unsigned input_offset = input_frame_size; |
| for (int i = 0; i < parameter_count; ++i) { |
| output_offset -= kPointerSize; |
| DoTranslateCommand(iterator, frame_index, output_offset); |
| @@ -747,7 +775,8 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
| } |
| output_frame->SetFrameSlot(output_offset, value); |
| intptr_t fp_value = top_address + output_offset; |
| - ASSERT(!is_bottommost || input_->GetRegister(ebp.code()) == fp_value); |
| + ASSERT(!is_bottommost || |
| + (input_->GetRegister(ebp.code()) + has_alignment_padding_ * kPointerSize) == fp_value); |
| output_frame->SetFp(fp_value); |
| if (is_topmost) output_frame->SetRegister(ebp.code(), fp_value); |
| if (FLAG_trace_deopt) { |
| @@ -948,6 +977,23 @@ void Deoptimizer::EntryGenerator::Generate() { |
| } |
| __ pop(eax); |
| + if (type() != OSR) { |
| + // If frame was dynamically aligned, pop padding. |
| + Label no_padding; |
| + __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), Immediate(0)); |
| + __ j(equal, &no_padding); |
| + __ pop(ecx); |
| + __ cmp(ecx, Immediate(Smi::FromInt(0x12345))); |
| + __ Assert(equal, "alignment marker expected"); |
| + __ bind(&no_padding); |
| + } else { |
| + Label no_padding; |
| + __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()), Immediate(0)); |
| + __ j(equal, &no_padding); |
| + __ push(Immediate(Smi::FromInt(0x12345))); |
| + __ bind(&no_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 |