Index: src/deoptimizer.cc |
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc |
index d4756ff18389d833774a02720ff1f9eebab677c9..c40d328203de3f410a3bf998b1c1650e543048eb 100644 |
--- a/src/deoptimizer.cc |
+++ b/src/deoptimizer.cc |
@@ -1082,6 +1082,8 @@ 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(); |
@@ -1102,6 +1104,12 @@ void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, |
bytecode_offset = catch_handler_pc_offset_; |
} |
+ // 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; |
rmcilroy
2016/08/24 11:18:30
Should we do this before printing height for the t
Michael Starzinger
2016/08/24 11:38:42
Done. No strong opinion either way.
|
+ |
// The 'fixed' part of the frame consists of the incoming parameters and |
// the part described by InterpreterFrameConstants. |
unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); |
@@ -1113,8 +1121,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 +1261,26 @@ 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++; |
+ // Put the accumulator on the stack. The bailout state for interpreted frames |
+ // is always set to {BailoutState::TOS_REGISTER} and the {NotifyDeoptimized} |
+ // builtin will pop it off the topmost frame (possibly after materialization). |
+ if (is_topmost) { |
+ 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); |
+ } |
} else { |
- WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
- output_offset); |
+ value_iterator++; |
+ input_index++; |
} |
CHECK_EQ(0u, output_offset); |