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 2623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2634 Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it, | 2634 Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it, |
2635 Isolate* isolate) { | 2635 Isolate* isolate) { |
2636 if (it->GetRawValue() == isolate->heap()->arguments_marker()) { | 2636 if (it->GetRawValue() == isolate->heap()->arguments_marker()) { |
2637 if (!it->IsMaterializableByDebugger()) { | 2637 if (!it->IsMaterializableByDebugger()) { |
2638 return isolate->factory()->undefined_value(); | 2638 return isolate->factory()->undefined_value(); |
2639 } | 2639 } |
2640 } | 2640 } |
2641 return it->GetValue(); | 2641 return it->GetValue(); |
2642 } | 2642 } |
2643 | 2643 |
2644 int ComputeSourcePosition(Handle<SharedFunctionInfo> shared, | |
2645 BailoutId node_id) { | |
2646 if (shared->HasBytecodeArray()) { | |
2647 BytecodeArray* bytecodes = shared->bytecode_array(); | |
2648 // BailoutId points to the next bytecode in the bytecode aray. Subtract | |
2649 // 1 to get the end of current bytecode. | |
2650 return bytecodes->SourcePosition(node_id.ToInt() - 1); | |
2651 } else { | |
2652 Code* non_optimized_code = shared->code(); | |
2653 FixedArray* raw_data = non_optimized_code->deoptimization_data(); | |
2654 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); | |
2655 unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, *shared); | |
2656 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); | |
2657 return non_optimized_code->SourcePosition(pc_offset); | |
2658 } | |
2659 } | |
2660 | |
2661 } // namespace | 2644 } // namespace |
2662 | 2645 |
2663 DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state, | 2646 DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state, |
2664 TranslatedState::iterator frame_it, | 2647 TranslatedState::iterator frame_it, |
2665 Isolate* isolate) { | 2648 Isolate* isolate) { |
2666 // If the previous frame is an adaptor frame, we will take the parameters | 2649 // If the previous frame is an adaptor frame, we will take the parameters |
2667 // from there. | 2650 // from there. |
2668 TranslatedState::iterator parameter_frame = frame_it; | 2651 TranslatedState::iterator parameter_frame = frame_it; |
2669 if (parameter_frame != state->begin()) { | 2652 if (parameter_frame != state->begin()) { |
2670 parameter_frame--; | 2653 parameter_frame--; |
2671 } | 2654 } |
2672 int parameter_count; | 2655 int parameter_count; |
2673 if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) { | 2656 if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) { |
2674 parameter_count = parameter_frame->height() - 1; // Ignore the receiver. | 2657 parameter_count = parameter_frame->height() - 1; // Ignore the receiver. |
2675 } else { | 2658 } else { |
2676 parameter_frame = frame_it; | 2659 parameter_frame = frame_it; |
2677 parameter_count = | 2660 parameter_count = |
2678 frame_it->shared_info()->internal_formal_parameter_count(); | 2661 frame_it->shared_info()->internal_formal_parameter_count(); |
2679 } | 2662 } |
2680 TranslatedFrame::iterator parameter_it = parameter_frame->begin(); | 2663 TranslatedFrame::iterator parameter_it = parameter_frame->begin(); |
2681 parameter_it++; // Skip the function. | 2664 parameter_it++; // Skip the function. |
2682 parameter_it++; // Skip the receiver. | 2665 parameter_it++; // Skip the receiver. |
2683 | 2666 |
2684 // Figure out whether there is a construct stub frame on top of | 2667 // Figure out whether there is a construct stub frame on top of |
2685 // the parameter frame. | 2668 // the parameter frame. |
2686 has_construct_stub_ = | 2669 has_construct_stub_ = |
2687 parameter_frame != state->begin() && | 2670 parameter_frame != state->begin() && |
2688 (parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub; | 2671 (parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub; |
2689 | 2672 |
2690 source_position_ = | 2673 source_position_ = Deoptimizer::ComputeSourcePosition( |
2691 ComputeSourcePosition(frame_it->shared_info(), frame_it->node_id()); | 2674 *frame_it->shared_info(), frame_it->node_id()); |
2692 | 2675 |
2693 TranslatedFrame::iterator value_it = frame_it->begin(); | 2676 TranslatedFrame::iterator value_it = frame_it->begin(); |
2694 // Get the function. Note that this might materialize the function. | 2677 // Get the function. Note that this might materialize the function. |
2695 // In case the debugger mutates this value, we should deoptimize | 2678 // In case the debugger mutates this value, we should deoptimize |
2696 // the function and remember the value in the materialized value store. | 2679 // the function and remember the value in the materialized value store. |
2697 function_ = Handle<JSFunction>::cast(value_it->GetValue()); | 2680 function_ = Handle<JSFunction>::cast(value_it->GetValue()); |
2698 | 2681 |
2699 parameters_.resize(static_cast<size_t>(parameter_count)); | 2682 parameters_.resize(static_cast<size_t>(parameter_count)); |
2700 for (int i = 0; i < parameter_count; i++) { | 2683 for (int i = 0; i < parameter_count; i++) { |
2701 Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate); | 2684 Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2745 static const char* deopt_messages_[] = { | 2728 static const char* deopt_messages_[] = { |
2746 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; | 2729 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; |
2747 #undef DEOPT_MESSAGES_TEXTS | 2730 #undef DEOPT_MESSAGES_TEXTS |
2748 return deopt_messages_[deopt_reason]; | 2731 return deopt_messages_[deopt_reason]; |
2749 } | 2732 } |
2750 | 2733 |
2751 | 2734 |
2752 Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) { | 2735 Deoptimizer::DeoptInfo Deoptimizer::GetDeoptInfo(Code* code, Address pc) { |
2753 SourcePosition last_position = SourcePosition::Unknown(); | 2736 SourcePosition last_position = SourcePosition::Unknown(); |
2754 Deoptimizer::DeoptReason last_reason = Deoptimizer::kNoReason; | 2737 Deoptimizer::DeoptReason last_reason = Deoptimizer::kNoReason; |
2755 int last_inlining_id = InlinedFunctionInfo::kNoParentId; | 2738 int last_deopt_id = Deoptimizer::DeoptInfo::kNoDeoptId; |
2756 int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) | | 2739 int mask = RelocInfo::ModeMask(RelocInfo::DEOPT_REASON) | |
2757 RelocInfo::ModeMask(RelocInfo::DEOPT_ID) | | 2740 RelocInfo::ModeMask(RelocInfo::DEOPT_ID) | |
2758 RelocInfo::ModeMask(RelocInfo::POSITION); | 2741 RelocInfo::ModeMask(RelocInfo::POSITION); |
2759 for (RelocIterator it(code, mask); !it.done(); it.next()) { | 2742 for (RelocIterator it(code, mask); !it.done(); it.next()) { |
2760 RelocInfo* info = it.rinfo(); | 2743 RelocInfo* info = it.rinfo(); |
2761 if (info->pc() >= pc) { | 2744 if (info->pc() >= pc) { |
2762 return DeoptInfo(last_position, last_reason, last_inlining_id); | 2745 return DeoptInfo(last_position, last_reason, last_deopt_id); |
2763 } | 2746 } |
2764 if (info->rmode() == RelocInfo::POSITION) { | 2747 if (info->rmode() == RelocInfo::POSITION) { |
2765 int raw_position = static_cast<int>(info->data()); | 2748 int raw_position = static_cast<int>(info->data()); |
2766 last_position = raw_position ? SourcePosition::FromRaw(raw_position) | 2749 last_position = raw_position ? SourcePosition::FromRaw(raw_position) |
2767 : SourcePosition::Unknown(); | 2750 : SourcePosition::Unknown(); |
2768 } else if (info->rmode() == RelocInfo::DEOPT_ID) { | 2751 } else if (info->rmode() == RelocInfo::DEOPT_ID) { |
2769 last_inlining_id = static_cast<int>(info->data()); | 2752 last_deopt_id = static_cast<int>(info->data()); |
2770 } else if (info->rmode() == RelocInfo::DEOPT_REASON) { | 2753 } else if (info->rmode() == RelocInfo::DEOPT_REASON) { |
2771 last_reason = static_cast<Deoptimizer::DeoptReason>(info->data()); | 2754 last_reason = static_cast<Deoptimizer::DeoptReason>(info->data()); |
2772 } | 2755 } |
2773 } | 2756 } |
2774 return DeoptInfo(SourcePosition::Unknown(), Deoptimizer::kNoReason, -1); | 2757 return DeoptInfo(SourcePosition::Unknown(), Deoptimizer::kNoReason, -1); |
2775 } | 2758 } |
2776 | 2759 |
2777 | 2760 |
2778 // static | 2761 // static |
| 2762 int Deoptimizer::ComputeSourcePosition(SharedFunctionInfo* shared, |
| 2763 BailoutId node_id) { |
| 2764 if (shared->HasBytecodeArray()) { |
| 2765 BytecodeArray* bytecodes = shared->bytecode_array(); |
| 2766 // BailoutId points to the next bytecode in the bytecode aray. Subtract |
| 2767 // 1 to get the end of current bytecode. |
| 2768 return bytecodes->SourcePosition(node_id.ToInt() - 1); |
| 2769 } else { |
| 2770 Code* non_optimized_code = shared->code(); |
| 2771 FixedArray* raw_data = non_optimized_code->deoptimization_data(); |
| 2772 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); |
| 2773 unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, shared); |
| 2774 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); |
| 2775 return non_optimized_code->SourcePosition(pc_offset); |
| 2776 } |
| 2777 } |
| 2778 |
| 2779 // static |
2779 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, | 2780 TranslatedValue TranslatedValue::NewArgumentsObject(TranslatedState* container, |
2780 int length, | 2781 int length, |
2781 int object_index) { | 2782 int object_index) { |
2782 TranslatedValue slot(container, kArgumentsObject); | 2783 TranslatedValue slot(container, kArgumentsObject); |
2783 slot.materialization_info_ = {object_index, length}; | 2784 slot.materialization_info_ = {object_index, length}; |
2784 return slot; | 2785 return slot; |
2785 } | 2786 } |
2786 | 2787 |
2787 | 2788 |
2788 // static | 2789 // static |
(...skipping 1133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3922 CHECK(value_info->IsMaterializedObject()); | 3923 CHECK(value_info->IsMaterializedObject()); |
3923 | 3924 |
3924 value_info->value_ = | 3925 value_info->value_ = |
3925 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3926 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3926 } | 3927 } |
3927 } | 3928 } |
3928 } | 3929 } |
3929 | 3930 |
3930 } // namespace internal | 3931 } // namespace internal |
3931 } // namespace v8 | 3932 } // namespace v8 |
OLD | NEW |