| Index: src/deoptimizer.cc
|
| diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
|
| index d4756ff18389d833774a02720ff1f9eebab677c9..b99541bf6dd581bafe60ab1611c141c70afde4bc 100644
|
| --- a/src/deoptimizer.cc
|
| +++ b/src/deoptimizer.cc
|
| @@ -1082,11 +1082,20 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
|
| SharedFunctionInfo* shared = translated_frame->raw_shared_info();
|
|
|
| TranslatedFrame::iterator value_iterator = translated_frame->begin();
|
| + bool is_bottommost = (0 == frame_index);
|
| + bool is_topmost = (output_count_ - 1 == frame_index);
|
| int input_index = 0;
|
|
|
| int bytecode_offset = translated_frame->node_id().ToInt();
|
| unsigned height = translated_frame->height();
|
| unsigned height_in_bytes = height * kPointerSize;
|
| +
|
| + // All tranlations for interpreted frames contain the accumulator and hence
|
| + // are assumed to be in bailout state {BailoutState::TOS_REGISTER}. However
|
| + // such a state is only supported for the topmost frame. We need to skip
|
| + // pushing the accumulator for any non-topmost frame.
|
| + if (!is_topmost) height_in_bytes -= kPointerSize;
|
| +
|
| JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
|
| value_iterator++;
|
| input_index++;
|
| @@ -1113,8 +1122,6 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
|
| FrameDescription(output_frame_size, parameter_count);
|
| output_frame->SetFrameType(StackFrame::INTERPRETED);
|
|
|
| - bool is_bottommost = (0 == frame_index);
|
| - bool is_topmost = (output_count_ - 1 == frame_index);
|
| CHECK(frame_index >= 0 && frame_index < output_count_);
|
| CHECK_NULL(output_[frame_index]);
|
| output_[frame_index] = output_frame;
|
| @@ -1255,20 +1262,30 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
|
| output_offset);
|
| }
|
|
|
| - // Put the accumulator on the stack. It will be popped by the
|
| - // InterpreterNotifyDeopt builtin (possibly after materialization).
|
| - output_offset -= kPointerSize;
|
| - if (goto_catch_handler) {
|
| - // If we are lazy deopting to a catch handler, we set the accumulator to
|
| - // the exception (which lives in the result register).
|
| - intptr_t accumulator_value =
|
| - input_->GetRegister(FullCodeGenerator::result_register().code());
|
| - WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0,
|
| - frame_index, output_offset, "accumulator ");
|
| - value_iterator++;
|
| + // Translate the accumulator register (depending on frame position).
|
| + if (is_topmost) {
|
| + // For topmost frmae, p ut the accumulator on the stack. The bailout state
|
| + // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and
|
| + // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly
|
| + // after materialization).
|
| + output_offset -= kPointerSize;
|
| + if (goto_catch_handler) {
|
| + // If we are lazy deopting to a catch handler, we set the accumulator to
|
| + // the exception (which lives in the result register).
|
| + intptr_t accumulator_value =
|
| + input_->GetRegister(FullCodeGenerator::result_register().code());
|
| + WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0,
|
| + frame_index, output_offset, "accumulator ");
|
| + value_iterator++;
|
| + } else {
|
| + WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
|
| + output_offset, "accumulator ");
|
| + }
|
| } else {
|
| - WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index,
|
| - output_offset);
|
| + // For non-topmost frames, skip the accumulator translation. For those
|
| + // frames, the return value from the callee will become the accumulator.
|
| + value_iterator++;
|
| + input_index++;
|
| }
|
| CHECK_EQ(0u, output_offset);
|
|
|
|
|