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; |
| 1092 |
| 1093 // All tranlations for interpreted frames contain the accumulator and hence |
| 1094 // are assumed to be in bailout state {BailoutState::TOS_REGISTER}. However |
| 1095 // such a state is only supported for the topmost frame. We need to skip |
| 1096 // pushing the accumulator for any non-topmost frame. |
| 1097 if (!is_topmost) height_in_bytes -= kPointerSize; |
| 1098 |
1090 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1099 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1091 value_iterator++; | 1100 value_iterator++; |
1092 input_index++; | 1101 input_index++; |
1093 if (trace_scope_ != NULL) { | 1102 if (trace_scope_ != NULL) { |
1094 PrintF(trace_scope_->file(), " translating interpreted frame "); | 1103 PrintF(trace_scope_->file(), " translating interpreted frame "); |
1095 std::unique_ptr<char[]> name = shared->DebugName()->ToCString(); | 1104 std::unique_ptr<char[]> name = shared->DebugName()->ToCString(); |
1096 PrintF(trace_scope_->file(), "%s", name.get()); | 1105 PrintF(trace_scope_->file(), "%s", name.get()); |
1097 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n", | 1106 PrintF(trace_scope_->file(), " => bytecode_offset=%d, height=%d%s\n", |
1098 bytecode_offset, height_in_bytes, | 1107 bytecode_offset, height_in_bytes, |
1099 goto_catch_handler ? " (throw)" : ""); | 1108 goto_catch_handler ? " (throw)" : ""); |
1100 } | 1109 } |
1101 if (goto_catch_handler) { | 1110 if (goto_catch_handler) { |
1102 bytecode_offset = catch_handler_pc_offset_; | 1111 bytecode_offset = catch_handler_pc_offset_; |
1103 } | 1112 } |
1104 | 1113 |
1105 // The 'fixed' part of the frame consists of the incoming parameters and | 1114 // The 'fixed' part of the frame consists of the incoming parameters and |
1106 // the part described by InterpreterFrameConstants. | 1115 // the part described by InterpreterFrameConstants. |
1107 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); | 1116 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); |
1108 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1117 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1109 | 1118 |
1110 // Allocate and store the output frame description. | 1119 // Allocate and store the output frame description. |
1111 int parameter_count = shared->internal_formal_parameter_count() + 1; | 1120 int parameter_count = shared->internal_formal_parameter_count() + 1; |
1112 FrameDescription* output_frame = new (output_frame_size) | 1121 FrameDescription* output_frame = new (output_frame_size) |
1113 FrameDescription(output_frame_size, parameter_count); | 1122 FrameDescription(output_frame_size, parameter_count); |
1114 output_frame->SetFrameType(StackFrame::INTERPRETED); | 1123 output_frame->SetFrameType(StackFrame::INTERPRETED); |
1115 | 1124 |
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_); | 1125 CHECK(frame_index >= 0 && frame_index < output_count_); |
1119 CHECK_NULL(output_[frame_index]); | 1126 CHECK_NULL(output_[frame_index]); |
1120 output_[frame_index] = output_frame; | 1127 output_[frame_index] = output_frame; |
1121 | 1128 |
1122 // The top address of the frame is computed from the previous frame's top and | 1129 // The top address of the frame is computed from the previous frame's top and |
1123 // this frame's size. | 1130 // this frame's size. |
1124 intptr_t top_address; | 1131 intptr_t top_address; |
1125 if (is_bottommost) { | 1132 if (is_bottommost) { |
1126 top_address = caller_frame_top_ - output_frame_size; | 1133 top_address = caller_frame_top_ - output_frame_size; |
1127 } else { | 1134 } else { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, | 1255 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, |
1249 "bytecode offset "); | 1256 "bytecode offset "); |
1250 | 1257 |
1251 // Translate the rest of the interpreter registers in the frame. | 1258 // Translate the rest of the interpreter registers in the frame. |
1252 for (unsigned i = 0; i < height - 1; ++i) { | 1259 for (unsigned i = 0; i < height - 1; ++i) { |
1253 output_offset -= kPointerSize; | 1260 output_offset -= kPointerSize; |
1254 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1261 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1255 output_offset); | 1262 output_offset); |
1256 } | 1263 } |
1257 | 1264 |
1258 // Put the accumulator on the stack. It will be popped by the | 1265 // Translate the accumulator register (depending on frame position). |
1259 // InterpreterNotifyDeopt builtin (possibly after materialization). | 1266 if (is_topmost) { |
1260 output_offset -= kPointerSize; | 1267 // For topmost frmae, p ut the accumulator on the stack. The bailout state |
1261 if (goto_catch_handler) { | 1268 // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and |
1262 // If we are lazy deopting to a catch handler, we set the accumulator to | 1269 // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly |
1263 // the exception (which lives in the result register). | 1270 // after materialization). |
1264 intptr_t accumulator_value = | 1271 output_offset -= kPointerSize; |
1265 input_->GetRegister(FullCodeGenerator::result_register().code()); | 1272 if (goto_catch_handler) { |
1266 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, | 1273 // If we are lazy deopting to a catch handler, we set the accumulator to |
1267 frame_index, output_offset, "accumulator "); | 1274 // the exception (which lives in the result register). |
| 1275 intptr_t accumulator_value = |
| 1276 input_->GetRegister(FullCodeGenerator::result_register().code()); |
| 1277 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, |
| 1278 frame_index, output_offset, "accumulator "); |
| 1279 value_iterator++; |
| 1280 } else { |
| 1281 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 1282 output_offset, "accumulator "); |
| 1283 } |
| 1284 } else { |
| 1285 // For non-topmost frames, skip the accumulator translation. For those |
| 1286 // frames, the return value from the callee will become the accumulator. |
1268 value_iterator++; | 1287 value_iterator++; |
1269 } else { | 1288 input_index++; |
1270 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | |
1271 output_offset); | |
1272 } | 1289 } |
1273 CHECK_EQ(0u, output_offset); | 1290 CHECK_EQ(0u, output_offset); |
1274 | 1291 |
1275 Builtins* builtins = isolate_->builtins(); | 1292 Builtins* builtins = isolate_->builtins(); |
1276 Code* dispatch_builtin = | 1293 Code* dispatch_builtin = |
1277 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); | 1294 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); |
1278 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); | 1295 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); |
1279 // Restore accumulator (TOS) register. | 1296 // Restore accumulator (TOS) register. |
1280 output_frame->SetState( | 1297 output_frame->SetState( |
1281 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER))); | 1298 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()); | 4025 CHECK(value_info->IsMaterializedObject()); |
4009 | 4026 |
4010 value_info->value_ = | 4027 value_info->value_ = |
4011 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4028 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4012 } | 4029 } |
4013 } | 4030 } |
4014 } | 4031 } |
4015 | 4032 |
4016 } // namespace internal | 4033 } // namespace internal |
4017 } // namespace v8 | 4034 } // namespace v8 |
OLD | NEW |