Commit 9c8f4775 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[deoptimizer] Fix for non-topmost interpreted frame.

The accumulator is always part of the translation for every interpreted
frame. The assumption is that all frames are in {TOS_REGISTER} state.
This however is not supported for non-topmost frames and we need to
avoid pushing the accumulator onto the machine stack.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2271153003
Cr-Commit-Position: refs/heads/master@{#38945}
parent 36833446
...@@ -1058,11 +1058,20 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, ...@@ -1058,11 +1058,20 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
SharedFunctionInfo* shared = translated_frame->raw_shared_info(); SharedFunctionInfo* shared = translated_frame->raw_shared_info();
TranslatedFrame::iterator value_iterator = translated_frame->begin(); 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 input_index = 0;
int bytecode_offset = translated_frame->node_id().ToInt(); int bytecode_offset = translated_frame->node_id().ToInt();
unsigned height = translated_frame->height(); unsigned height = translated_frame->height();
unsigned height_in_bytes = height * kPointerSize; 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()); JSFunction* function = JSFunction::cast(value_iterator->GetRawValue());
value_iterator++; value_iterator++;
input_index++; input_index++;
...@@ -1089,8 +1098,6 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, ...@@ -1089,8 +1098,6 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
FrameDescription(output_frame_size, parameter_count); FrameDescription(output_frame_size, parameter_count);
output_frame->SetFrameType(StackFrame::INTERPRETED); 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(frame_index >= 0 && frame_index < output_count_);
CHECK_NULL(output_[frame_index]); CHECK_NULL(output_[frame_index]);
output_[frame_index] = output_frame; output_[frame_index] = output_frame;
...@@ -1231,20 +1238,30 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, ...@@ -1231,20 +1238,30 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame,
output_offset); output_offset);
} }
// Put the accumulator on the stack. It will be popped by the // Translate the accumulator register (depending on frame position).
// InterpreterNotifyDeopt builtin (possibly after materialization). if (is_topmost) {
output_offset -= kPointerSize; // For topmost frmae, p ut the accumulator on the stack. The bailout state
if (goto_catch_handler) { // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and
// If we are lazy deopting to a catch handler, we set the accumulator to // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly
// the exception (which lives in the result register). // after materialization).
intptr_t accumulator_value = output_offset -= kPointerSize;
input_->GetRegister(FullCodeGenerator::result_register().code()); if (goto_catch_handler) {
WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, // If we are lazy deopting to a catch handler, we set the accumulator to
frame_index, output_offset, "accumulator "); // the exception (which lives in the result register).
value_iterator++; 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 { } else {
WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, // For non-topmost frames, skip the accumulator translation. For those
output_offset); // frames, the return value from the callee will become the accumulator.
value_iterator++;
input_index++;
} }
CHECK_EQ(0u, output_offset); CHECK_EQ(0u, output_offset);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment