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 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 intptr_t constant_pool_value = | 994 intptr_t constant_pool_value = |
995 reinterpret_cast<intptr_t>(non_optimized_code->constant_pool()); | 995 reinterpret_cast<intptr_t>(non_optimized_code->constant_pool()); |
996 output_frame->SetConstantPool(constant_pool_value); | 996 output_frame->SetConstantPool(constant_pool_value); |
997 if (is_topmost) { | 997 if (is_topmost) { |
998 Register constant_pool_reg = | 998 Register constant_pool_reg = |
999 JavaScriptFrame::constant_pool_pointer_register(); | 999 JavaScriptFrame::constant_pool_pointer_register(); |
1000 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); | 1000 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); |
1001 } | 1001 } |
1002 } | 1002 } |
1003 | 1003 |
1004 // Compute this frame's PC, state, and continuation. | 1004 // Compute this frame's PC and state. |
1005 FixedArray* raw_data = non_optimized_code->deoptimization_data(); | 1005 FixedArray* raw_data = non_optimized_code->deoptimization_data(); |
1006 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); | 1006 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); |
1007 Address start = non_optimized_code->instruction_start(); | 1007 Address start = non_optimized_code->instruction_start(); |
1008 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); | 1008 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); |
1009 unsigned pc_offset = goto_catch_handler | 1009 unsigned pc_offset = goto_catch_handler |
1010 ? catch_handler_pc_offset_ | 1010 ? catch_handler_pc_offset_ |
1011 : FullCodeGenerator::PcField::decode(pc_and_state); | 1011 : FullCodeGenerator::PcField::decode(pc_and_state); |
1012 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); | 1012 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); |
1013 output_frame->SetPc(pc_value); | 1013 output_frame->SetPc(pc_value); |
1014 | 1014 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 | 1236 |
1237 // Translate the rest of the interpreter registers in the frame. | 1237 // Translate the rest of the interpreter registers in the frame. |
1238 for (unsigned i = 0; i < height - 1; ++i) { | 1238 for (unsigned i = 0; i < height - 1; ++i) { |
1239 output_offset -= kPointerSize; | 1239 output_offset -= kPointerSize; |
1240 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1240 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1241 output_offset); | 1241 output_offset); |
1242 } | 1242 } |
1243 | 1243 |
1244 // Translate the accumulator register (depending on frame position). | 1244 // Translate the accumulator register (depending on frame position). |
1245 if (is_topmost) { | 1245 if (is_topmost) { |
1246 // For topmost frmae, p ut the accumulator on the stack. The bailout state | 1246 // For topmost frame, put the accumulator on the stack. The bailout state |
1247 // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and | 1247 // for interpreted frames is always set to {BailoutState::TOS_REGISTER} and |
1248 // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly | 1248 // the {NotifyDeoptimized} builtin pops it off the topmost frame (possibly |
1249 // after materialization). | 1249 // after materialization). |
1250 output_offset -= kPointerSize; | 1250 output_offset -= kPointerSize; |
1251 if (goto_catch_handler) { | 1251 if (goto_catch_handler) { |
1252 // If we are lazy deopting to a catch handler, we set the accumulator to | 1252 // If we are lazy deopting to a catch handler, we set the accumulator to |
1253 // the exception (which lives in the result register). | 1253 // the exception (which lives in the result register). |
1254 intptr_t accumulator_value = | 1254 intptr_t accumulator_value = |
1255 input_->GetRegister(FullCodeGenerator::result_register().code()); | 1255 input_->GetRegister(FullCodeGenerator::result_register().code()); |
1256 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, | 1256 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, |
1257 frame_index, output_offset, "accumulator "); | 1257 frame_index, output_offset, "accumulator "); |
1258 value_iterator++; | 1258 value_iterator++; |
1259 } else { | 1259 } else { |
1260 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1260 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1261 output_offset, "accumulator "); | 1261 output_offset, "accumulator "); |
1262 } | 1262 } |
1263 } else { | 1263 } else { |
1264 // For non-topmost frames, skip the accumulator translation. For those | 1264 // For non-topmost frames, skip the accumulator translation. For those |
1265 // frames, the return value from the callee will become the accumulator. | 1265 // frames, the return value from the callee will become the accumulator. |
1266 value_iterator++; | 1266 value_iterator++; |
1267 input_index++; | 1267 input_index++; |
1268 } | 1268 } |
1269 CHECK_EQ(0u, output_offset); | 1269 CHECK_EQ(0u, output_offset); |
1270 | 1270 |
| 1271 // Compute this frame's PC and state. The PC will be a special builtin that |
| 1272 // continues the bytecode dispatch. Note that non-topmost and lazy-style |
| 1273 // bailout handlers also advance the bytecode offset before dispatch, hence |
| 1274 // simulating what normal handlers do upon completion of the operation. |
1271 Builtins* builtins = isolate_->builtins(); | 1275 Builtins* builtins = isolate_->builtins(); |
1272 Code* dispatch_builtin = | 1276 Code* dispatch_builtin = |
1273 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); | 1277 (!is_topmost || (bailout_type_ == LAZY)) && !goto_catch_handler |
| 1278 ? builtins->builtin(Builtins::kInterpreterEnterBytecodeAdvance) |
| 1279 : builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); |
1274 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); | 1280 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); |
1275 // Restore accumulator (TOS) register. | 1281 // Restore accumulator (TOS) register. |
1276 output_frame->SetState( | 1282 output_frame->SetState( |
1277 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER))); | 1283 Smi::FromInt(static_cast<int>(BailoutState::TOS_REGISTER))); |
1278 | 1284 |
1279 // Update constant pool. | 1285 // Update constant pool. |
1280 if (FLAG_enable_embedded_constant_pool) { | 1286 if (FLAG_enable_embedded_constant_pool) { |
1281 intptr_t constant_pool_value = | 1287 intptr_t constant_pool_value = |
1282 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); | 1288 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); |
1283 output_frame->SetConstantPool(constant_pool_value); | 1289 output_frame->SetConstantPool(constant_pool_value); |
(...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2751 unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, shared); | 2757 unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, shared); |
2752 int code_offset = | 2758 int code_offset = |
2753 static_cast<int>(FullCodeGenerator::PcField::decode(pc_and_state)); | 2759 static_cast<int>(FullCodeGenerator::PcField::decode(pc_and_state)); |
2754 return AbstractCode::cast(code)->SourcePosition(code_offset); | 2760 return AbstractCode::cast(code)->SourcePosition(code_offset); |
2755 } | 2761 } |
2756 | 2762 |
2757 // static | 2763 // static |
2758 int Deoptimizer::ComputeSourcePositionFromBytecodeArray( | 2764 int Deoptimizer::ComputeSourcePositionFromBytecodeArray( |
2759 SharedFunctionInfo* shared, BailoutId node_id) { | 2765 SharedFunctionInfo* shared, BailoutId node_id) { |
2760 DCHECK(shared->HasBytecodeArray()); | 2766 DCHECK(shared->HasBytecodeArray()); |
2761 // BailoutId points to the next bytecode in the bytecode aray. Subtract | |
2762 // 1 to get the end of current bytecode. | |
2763 int code_offset = node_id.ToInt() - 1; | |
2764 return AbstractCode::cast(shared->bytecode_array()) | 2767 return AbstractCode::cast(shared->bytecode_array()) |
2765 ->SourcePosition(code_offset); | 2768 ->SourcePosition(node_id.ToInt()); |
2766 } | 2769 } |
2767 | 2770 |
2768 // static | 2771 // static |
2769 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, | 2772 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, |
2770 int length, | 2773 int length, |
2771 int object_index) { | 2774 int object_index) { |
2772 TranslatedValue slot(container, kArgumentsObject); | 2775 TranslatedValue slot(container, kArgumentsObject); |
2773 slot.materialization_info_ = {object_index, length}; | 2776 slot.materialization_info_ = {object_index, length}; |
2774 return slot; | 2777 return slot; |
2775 } | 2778 } |
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4011 CHECK(value_info->IsMaterializedObject()); | 4014 CHECK(value_info->IsMaterializedObject()); |
4012 | 4015 |
4013 value_info->value_ = | 4016 value_info->value_ = |
4014 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4017 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4015 } | 4018 } |
4016 } | 4019 } |
4017 } | 4020 } |
4018 | 4021 |
4019 } // namespace internal | 4022 } // namespace internal |
4020 } // namespace v8 | 4023 } // namespace v8 |
OLD | NEW |