| Index: src/ia32/deoptimizer-ia32.cc
|
| diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
|
| index 73961e1416deb7654e17845bddde94531d821c01..14c2582f806f0e8663573eee1979231ae275b5cb 100644
|
| --- a/src/ia32/deoptimizer-ia32.cc
|
| +++ b/src/ia32/deoptimizer-ia32.cc
|
| @@ -415,6 +415,25 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
|
| output_offset -= kPointerSize;
|
| }
|
|
|
| + // All OSR stack frames are dynamically aligned to an 8-byte boundary.
|
| + 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_state = (has_alignment_padding_ == 1) ?
|
| + kAlignmentPaddingPushed :
|
| + kNoAlignmentPadding;
|
| + if (FLAG_trace_osr) {
|
| + PrintF(" [esp + %d] <- 0x%08x ; (alignment state)\n",
|
| + output_offset,
|
| + alignment_state);
|
| + }
|
| + output_[0]->SetFrameSlot(output_offset, alignment_state);
|
| + output_offset -= kPointerSize;
|
| +
|
| // Translate the rest of the frame.
|
| while (ok && input_offset >= 0) {
|
| ok = DoOsrTranslateCommand(&iterator, &input_offset);
|
| @@ -427,7 +446,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 +707,36 @@ 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_state_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) {
|
| + int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset);
|
| + has_alignment_padding_ =
|
| + (alignment_state == kAlignmentPaddingPushed) ? 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 +778,9 @@ 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 +981,28 @@ 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);
|
| + if (FLAG_debug_code) {
|
| + __ cmp(ecx, Immediate(kAlignmentZapValue));
|
| + __ Assert(equal, "alignment marker expected");
|
| + }
|
| + __ bind(&no_padding);
|
| + } else {
|
| + // If frame needs dynamic alignment push padding.
|
| + Label no_padding;
|
| + __ cmp(Operand(eax, Deoptimizer::has_alignment_padding_offset()),
|
| + Immediate(0));
|
| + __ j(equal, &no_padding);
|
| + __ push(Immediate(kAlignmentZapValue));
|
| + __ 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
|
|
|