OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1075 reinterpret_cast<intptr_t>(continuation->entry())); | 1075 reinterpret_cast<intptr_t>(continuation->entry())); |
1076 } | 1076 } |
1077 } | 1077 } |
1078 | 1078 |
1079 void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, | 1079 void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, |
1080 int frame_index, | 1080 int frame_index, |
1081 bool goto_catch_handler) { | 1081 bool goto_catch_handler) { |
1082 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); | 1082 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); |
1083 | 1083 |
1084 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1084 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1085 bool is_bottommost = (0 == frame_index); | |
1086 bool is_topmost = (output_count_ - 1 == frame_index); | |
1085 int input_index = 0; | 1087 int input_index = 0; |
1086 | 1088 |
1087 int bytecode_offset = translated_frame->node_id().ToInt(); | 1089 int bytecode_offset = translated_frame->node_id().ToInt(); |
1088 unsigned height = translated_frame->height(); | 1090 unsigned height = translated_frame->height(); |
1089 unsigned height_in_bytes = height * kPointerSize; | 1091 unsigned height_in_bytes = height * kPointerSize; |
1090 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1092 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1091 value_iterator++; | 1093 value_iterator++; |
1092 input_index++; | 1094 input_index++; |
1093 if (trace_scope_ != NULL) { | 1095 if (trace_scope_ != NULL) { |
1094 PrintF(trace_scope_->file(), " translating interpreted frame "); | 1096 PrintF(trace_scope_->file(), " translating interpreted frame "); |
1095 std::unique_ptr<char[]> name = shared->DebugName()->ToCString(); | 1097 std::unique_ptr<char[]> name = shared->DebugName()->ToCString(); |
1096 PrintF(trace_scope_->file(), "%s", name.get()); | 1098 PrintF(trace_scope_->file(), "%s", name.get()); |
1097 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n", | 1099 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n", |
1098 bytecode_offset, height_in_bytes, | 1100 bytecode_offset, height_in_bytes, |
1099 goto_catch_handler ? " (throw)" : ""); | 1101 goto_catch_handler ? " (throw)" : ""); |
1100 } | 1102 } |
1101 if (goto_catch_handler) { | 1103 if (goto_catch_handler) { |
1102 bytecode_offset = catch_handler_pc_offset_; | 1104 bytecode_offset = catch_handler_pc_offset_; |
1103 } | 1105 } |
1104 | 1106 |
1107 // All tranlations for interpreted frames contain the accumulator and hence | |
1108 // are assumed to be in bailout state {BailoutState::TOS_REGISTER}. However | |
1109 // such a state is only supported for the topmost frame. We need to skip | |
1110 // pushing the accumulator for any non-topmost frame. | |
1111 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.
| |
1112 | |
1105 // The 'fixed' part of the frame consists of the incoming parameters and | 1113 // The 'fixed' part of the frame consists of the incoming parameters and |
1106 // the part described by InterpreterFrameConstants. | 1114 // the part described by InterpreterFrameConstants. |
1107 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); | 1115 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); |
1108 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1116 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1109 | 1117 |
1110 // Allocate and store the output frame description. | 1118 // Allocate and store the output frame description. |
1111 int parameter_count = shared->internal_formal_parameter_count() + 1; | 1119 int parameter_count = shared->internal_formal_parameter_count() + 1; |
1112 FrameDescription* output_frame = new (output_frame_size) | 1120 FrameDescription* output_frame = new (output_frame_size) |
1113 FrameDescription(output_frame_size, parameter_count); | 1121 FrameDescription(output_frame_size, parameter_count); |
1114 output_frame->SetFrameType(StackFrame::INTERPRETED); | 1122 output_frame->SetFrameType(StackFrame::INTERPRETED); |
1115 | 1123 |
1116 bool is_bottommost = (0 == frame_index); | |
1117 bool is_topmost = (output_count_ - 1 == frame_index); | |
1118 CHECK(frame_index >= 0 && frame_index < output_count_); | 1124 CHECK(frame_index >= 0 && frame_index < output_count_); |
1119 CHECK_NULL(output_[frame_index]); | 1125 CHECK_NULL(output_[frame_index]); |
1120 output_[frame_index] = output_frame; | 1126 output_[frame_index] = output_frame; |
1121 | 1127 |
1122 // The top address of the frame is computed from the previous frame's top and | 1128 // The top address of the frame is computed from the previous frame's top and |
1123 // this frame's size. | 1129 // this frame's size. |
1124 intptr_t top_address; | 1130 intptr_t top_address; |
1125 if (is_bottommost) { | 1131 if (is_bottommost) { |
1126 top_address = caller_frame_top_ - output_frame_size; | 1132 top_address = caller_frame_top_ - output_frame_size; |
1127 } else { | 1133 } else { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1248 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, | 1254 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, |
1249 "bytecode offset "); | 1255 "bytecode offset "); |
1250 | 1256 |
1251 // Translate the rest of the interpreter registers in the frame. | 1257 // Translate the rest of the interpreter registers in the frame. |
1252 for (unsigned i = 0; i < height - 1; ++i) { | 1258 for (unsigned i = 0; i < height - 1; ++i) { |
1253 output_offset -= kPointerSize; | 1259 output_offset -= kPointerSize; |
1254 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1260 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1255 output_offset); | 1261 output_offset); |
1256 } | 1262 } |
1257 | 1263 |
1258 // Put the accumulator on the stack. It will be popped by the | 1264 // Put the accumulator on the stack. The bailout state for interpreted frames |
1259 // InterpreterNotifyDeopt builtin (possibly after materialization). | 1265 // is always set to {BailoutState::TOS_REGISTER} and the {NotifyDeoptimized} |
1260 output_offset -= kPointerSize; | 1266 // builtin will pop it off the topmost frame (possibly after materialization). |
1261 if (goto_catch_handler) { | 1267 if (is_topmost) { |
1262 // If we are lazy deopting to a catch handler, we set the accumulator to | 1268 output_offset -= kPointerSize; |
1263 // the exception (which lives in the result register). | 1269 if (goto_catch_handler) { |
1264 intptr_t accumulator_value = | 1270 // If we are lazy deopting to a catch handler, we set the accumulator to |
1265 input_->GetRegister(FullCodeGenerator::result_register().code()); | 1271 // the exception (which lives in the result register). |
1266 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, | 1272 intptr_t accumulator_value = |
1267 frame_index, output_offset, "accumulator "); | 1273 input_->GetRegister(FullCodeGenerator::result_register().code()); |
1274 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, | |
1275 frame_index, output_offset, "accumulator "); | |
1276 value_iterator++; | |
1277 } else { | |
1278 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | |
1279 output_offset); | |
1280 } | |
1281 } else { | |
1268 value_iterator++; | 1282 value_iterator++; |
1269 } else { | 1283 input_index++; |
1270 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | |
1271 output_offset); | |
1272 } | 1284 } |
1273 CHECK_EQ(0u, output_offset); | 1285 CHECK_EQ(0u, output_offset); |
1274 | 1286 |
1275 Builtins* builtins = isolate_->builtins(); | 1287 Builtins* builtins = isolate_->builtins(); |
1276 Code* dispatch_builtin = | 1288 Code* dispatch_builtin = |
1277 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); | 1289 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); |
1278 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); | 1290 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); |
1279 // Restore accumulator (TOS) register. | 1291 // Restore accumulator (TOS) register. |
1280 output_frame->SetState( | 1292 output_frame->SetState( |
1281 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER))); | 1293 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER))); |
(...skipping 2726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4008 CHECK(value_info->IsMaterializedObject()); | 4020 CHECK(value_info->IsMaterializedObject()); |
4009 | 4021 |
4010 value_info->value_ = | 4022 value_info->value_ = |
4011 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4023 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4012 } | 4024 } |
4013 } | 4025 } |
4014 } | 4026 } |
4015 | 4027 |
4016 } // namespace internal | 4028 } // namespace internal |
4017 } // namespace v8 | 4029 } // namespace v8 |
OLD | NEW |