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 "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/ast/prettyprinter.h" | 8 #include "src/ast/prettyprinter.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/disasm.h" | 10 #include "src/disasm.h" |
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1264 // The bytecode offset was mentioned explicitly in the BEGIN_FRAME. | 1264 // The bytecode offset was mentioned explicitly in the BEGIN_FRAME. |
1265 output_offset -= kPointerSize; | 1265 output_offset -= kPointerSize; |
1266 input_offset -= kPointerSize; | 1266 input_offset -= kPointerSize; |
1267 int raw_bytecode_offset = | 1267 int raw_bytecode_offset = |
1268 BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset; | 1268 BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset; |
1269 Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset); | 1269 Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset); |
1270 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, | 1270 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, |
1271 "bytecode offset "); | 1271 "bytecode offset "); |
1272 | 1272 |
1273 // Translate the rest of the interpreter registers in the frame. | 1273 // Translate the rest of the interpreter registers in the frame. |
1274 for (unsigned i = 0; i < height; ++i) { | 1274 for (unsigned i = 0; i < height - 1; ++i) { |
1275 output_offset -= kPointerSize; | 1275 output_offset -= kPointerSize; |
1276 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1276 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1277 output_offset); | 1277 output_offset); |
1278 } | 1278 } |
| 1279 |
| 1280 // Put the accumulator on the stack. It will be popped by the |
| 1281 // InterpreterNotifyDeopt builtin (possibly after materialization). |
| 1282 output_offset -= kPointerSize; |
| 1283 if (goto_catch_handler) { |
| 1284 // If we are lazy deopting to a catch handler, we set the accumulator to |
| 1285 // the exception (which lives in the result register). |
| 1286 intptr_t accumulator_value = |
| 1287 input_->GetRegister(FullCodeGenerator::result_register().code()); |
| 1288 WriteValueToOutput(reinterpret_cast<Object*>(accumulator_value), 0, |
| 1289 frame_index, output_offset, "accumulator "); |
| 1290 value_iterator++; |
| 1291 } else { |
| 1292 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
| 1293 output_offset); |
| 1294 } |
1279 CHECK_EQ(0u, output_offset); | 1295 CHECK_EQ(0u, output_offset); |
1280 | 1296 |
1281 // Set the accumulator register. If we are lazy deopting to a catch handler, | |
1282 // we set the accumulator to the exception (which lives in the result | |
1283 // register). | |
1284 intptr_t accumulator_value = | |
1285 goto_catch_handler | |
1286 ? input_->GetRegister(FullCodeGenerator::result_register().code()) | |
1287 : reinterpret_cast<intptr_t>(value_iterator->GetRawValue()); | |
1288 output_frame->SetRegister(kInterpreterAccumulatorRegister.code(), | |
1289 accumulator_value); | |
1290 value_iterator++; | |
1291 | |
1292 Builtins* builtins = isolate_->builtins(); | 1297 Builtins* builtins = isolate_->builtins(); |
1293 Code* dispatch_builtin = | 1298 Code* dispatch_builtin = |
1294 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); | 1299 builtins->builtin(Builtins::kInterpreterEnterBytecodeDispatch); |
1295 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); | 1300 output_frame->SetPc(reinterpret_cast<intptr_t>(dispatch_builtin->entry())); |
1296 output_frame->SetState(0); | 1301 output_frame->SetState(0); |
1297 | 1302 |
1298 // Update constant pool. | 1303 // Update constant pool. |
1299 if (FLAG_enable_embedded_constant_pool) { | 1304 if (FLAG_enable_embedded_constant_pool) { |
1300 intptr_t constant_pool_value = | 1305 intptr_t constant_pool_value = |
1301 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); | 1306 reinterpret_cast<intptr_t>(dispatch_builtin->constant_pool()); |
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2562 for (int i = 0; i < skip_count; i++) { | 2567 for (int i = 0; i < skip_count; i++) { |
2563 stack_it++; | 2568 stack_it++; |
2564 } | 2569 } |
2565 | 2570 |
2566 // Get the context. | 2571 // Get the context. |
2567 context_ = GetValueForDebugger(stack_it, isolate); | 2572 context_ = GetValueForDebugger(stack_it, isolate); |
2568 stack_it++; | 2573 stack_it++; |
2569 | 2574 |
2570 // Get the expression stack. | 2575 // Get the expression stack. |
2571 int stack_height = frame_it->height(); | 2576 int stack_height = frame_it->height(); |
2572 if (frame_it->kind() == TranslatedFrame::kFunction) { | 2577 if (frame_it->kind() == TranslatedFrame::kFunction || |
| 2578 frame_it->kind() == TranslatedFrame::kInterpretedFunction) { |
2573 // For full-code frames, we should not count the context. | 2579 // For full-code frames, we should not count the context. |
| 2580 // For interpreter frames, we should not count the accumulator. |
2574 // TODO(jarin): Clean up the indexing in translated frames. | 2581 // TODO(jarin): Clean up the indexing in translated frames. |
2575 stack_height--; | 2582 stack_height--; |
2576 } | 2583 } |
2577 expression_stack_.resize(static_cast<size_t>(stack_height)); | 2584 expression_stack_.resize(static_cast<size_t>(stack_height)); |
2578 for (int i = 0; i < stack_height; i++) { | 2585 for (int i = 0; i < stack_height; i++) { |
2579 Handle<Object> expression = GetValueForDebugger(stack_it, isolate); | 2586 Handle<Object> expression = GetValueForDebugger(stack_it, isolate); |
2580 SetExpression(i, expression); | 2587 SetExpression(i, expression); |
2581 stack_it++; | 2588 stack_it++; |
2582 } | 2589 } |
2583 | 2590 |
2584 // For interpreter frame, skip the accumulator. | 2591 // For interpreter frame, skip the accumulator. |
2585 if (parameter_frame->kind() == TranslatedFrame::kInterpretedFunction) { | 2592 if (frame_it->kind() == TranslatedFrame::kInterpretedFunction) { |
2586 stack_it++; | 2593 stack_it++; |
2587 } | 2594 } |
2588 CHECK(stack_it == frame_it->end()); | 2595 CHECK(stack_it == frame_it->end()); |
2589 } | 2596 } |
2590 | 2597 |
2591 | 2598 |
2592 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { | 2599 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { |
2593 DCHECK(deopt_reason < kLastDeoptReason); | 2600 DCHECK(deopt_reason < kLastDeoptReason); |
2594 #define DEOPT_MESSAGES_TEXTS(C, T) T, | 2601 #define DEOPT_MESSAGES_TEXTS(C, T) T, |
2595 static const char* deopt_messages_[] = { | 2602 static const char* deopt_messages_[] = { |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2942 case kFunction: { | 2949 case kFunction: { |
2943 int parameter_count = | 2950 int parameter_count = |
2944 raw_shared_info_->internal_formal_parameter_count() + 1; | 2951 raw_shared_info_->internal_formal_parameter_count() + 1; |
2945 // + 1 for function. | 2952 // + 1 for function. |
2946 return height_ + parameter_count + 1; | 2953 return height_ + parameter_count + 1; |
2947 } | 2954 } |
2948 | 2955 |
2949 case kInterpretedFunction: { | 2956 case kInterpretedFunction: { |
2950 int parameter_count = | 2957 int parameter_count = |
2951 raw_shared_info_->internal_formal_parameter_count() + 1; | 2958 raw_shared_info_->internal_formal_parameter_count() + 1; |
2952 // + 3 for function, context and accumulator. | 2959 // + 2 for function and context. |
2953 return height_ + parameter_count + 3; | 2960 return height_ + parameter_count + 2; |
2954 } | 2961 } |
2955 | 2962 |
2956 case kGetter: | 2963 case kGetter: |
2957 return 2; // Function and receiver. | 2964 return 2; // Function and receiver. |
2958 | 2965 |
2959 case kSetter: | 2966 case kSetter: |
2960 return 3; // Function, receiver and the value to set. | 2967 return 3; // Function, receiver and the value to set. |
2961 | 2968 |
2962 case kArgumentsAdaptor: | 2969 case kArgumentsAdaptor: |
2963 case kConstructStub: | 2970 case kConstructStub: |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3743 CHECK(value_info->IsMaterializedObject()); | 3750 CHECK(value_info->IsMaterializedObject()); |
3744 | 3751 |
3745 value_info->value_ = | 3752 value_info->value_ = |
3746 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3753 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3747 } | 3754 } |
3748 } | 3755 } |
3749 } | 3756 } |
3750 | 3757 |
3751 } // namespace internal | 3758 } // namespace internal |
3752 } // namespace v8 | 3759 } // namespace v8 |
OLD | NEW |