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/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/disasm.h" | 9 #include "src/disasm.h" |
10 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 stack_fp_ = reinterpret_cast<Address>( | 753 stack_fp_ = reinterpret_cast<Address>( |
754 input_->GetRegister(fp_reg.code()) + | 754 input_->GetRegister(fp_reg.code()) + |
755 has_alignment_padding_ * kPointerSize); | 755 has_alignment_padding_ * kPointerSize); |
756 | 756 |
757 // Translate each output frame. | 757 // Translate each output frame. |
758 for (size_t i = 0; i < count; ++i) { | 758 for (size_t i = 0; i < count; ++i) { |
759 // Read the ast node id, function, and frame height for this output frame. | 759 // Read the ast node id, function, and frame height for this output frame. |
760 int frame_index = static_cast<int>(i); | 760 int frame_index = static_cast<int>(i); |
761 switch (translated_state_.frames()[i].kind()) { | 761 switch (translated_state_.frames()[i].kind()) { |
762 case TranslatedFrame::kFunction: | 762 case TranslatedFrame::kFunction: |
763 DoComputeJSFrame(nullptr, frame_index); | 763 DoComputeJSFrame(frame_index); |
764 jsframe_count_++; | 764 jsframe_count_++; |
765 break; | 765 break; |
766 case TranslatedFrame::kArgumentsAdaptor: | 766 case TranslatedFrame::kArgumentsAdaptor: |
767 DoComputeArgumentsAdaptorFrame(nullptr, frame_index); | 767 DoComputeArgumentsAdaptorFrame(frame_index); |
768 break; | 768 break; |
769 case TranslatedFrame::kConstructStub: | 769 case TranslatedFrame::kConstructStub: |
770 DoComputeConstructStubFrame(nullptr, frame_index); | 770 DoComputeConstructStubFrame(frame_index); |
771 break; | 771 break; |
772 case TranslatedFrame::kGetter: | 772 case TranslatedFrame::kGetter: |
773 DoComputeAccessorStubFrame(nullptr, frame_index, false); | 773 DoComputeAccessorStubFrame(frame_index, false); |
774 break; | 774 break; |
775 case TranslatedFrame::kSetter: | 775 case TranslatedFrame::kSetter: |
776 DoComputeAccessorStubFrame(nullptr, frame_index, true); | 776 DoComputeAccessorStubFrame(frame_index, true); |
777 break; | 777 break; |
778 case TranslatedFrame::kCompiledStub: | 778 case TranslatedFrame::kCompiledStub: |
779 DoComputeCompiledStubFrame(nullptr, frame_index); | 779 DoComputeCompiledStubFrame(frame_index); |
780 break; | 780 break; |
781 case TranslatedFrame::kInvalid: | 781 case TranslatedFrame::kInvalid: |
782 FATAL("invalid frame"); | 782 FATAL("invalid frame"); |
783 break; | 783 break; |
784 } | 784 } |
785 } | 785 } |
786 | 786 |
787 // Print some helpful diagnostic information. | 787 // Print some helpful diagnostic information. |
788 if (trace_scope_ != NULL) { | 788 if (trace_scope_ != NULL) { |
789 double ms = timer.Elapsed().InMillisecondsF(); | 789 double ms = timer.Elapsed().InMillisecondsF(); |
790 int index = output_count_ - 1; // Index of the topmost frame. | 790 int index = output_count_ - 1; // Index of the topmost frame. |
791 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", | 791 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", |
792 MessageFor(bailout_type_)); | 792 MessageFor(bailout_type_)); |
793 PrintFunctionName(); | 793 PrintFunctionName(); |
794 PrintF(trace_scope_->file(), | 794 PrintF(trace_scope_->file(), |
795 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," | 795 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," |
796 " took %0.3f ms]\n", | 796 " took %0.3f ms]\n", |
797 bailout_id_, | 797 bailout_id_, |
798 node_id.ToInt(), | 798 node_id.ToInt(), |
799 output_[index]->GetPc(), | 799 output_[index]->GetPc(), |
800 FullCodeGenerator::State2String( | 800 FullCodeGenerator::State2String( |
801 static_cast<FullCodeGenerator::State>( | 801 static_cast<FullCodeGenerator::State>( |
802 output_[index]->GetState()->value())), | 802 output_[index]->GetState()->value())), |
803 has_alignment_padding_ ? "with padding" : "no padding", | 803 has_alignment_padding_ ? "with padding" : "no padding", |
804 ms); | 804 ms); |
805 } | 805 } |
806 } | 806 } |
807 | 807 |
808 | 808 |
809 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, | 809 void Deoptimizer::DoComputeJSFrame(int frame_index) { |
810 int frame_index) { | |
811 TranslatedFrame* translated_frame = | 810 TranslatedFrame* translated_frame = |
812 &(translated_state_.frames()[frame_index]); | 811 &(translated_state_.frames()[frame_index]); |
813 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 812 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
814 int input_index = 0; | 813 int input_index = 0; |
815 | 814 |
816 BailoutId node_id = translated_frame->node_id(); | 815 BailoutId node_id = translated_frame->node_id(); |
817 unsigned height = | 816 unsigned height = |
818 translated_frame->height() - 1; // Do not count the context. | 817 translated_frame->height() - 1; // Do not count the context. |
819 unsigned height_in_bytes = height * kPointerSize; | 818 unsigned height_in_bytes = height * kPointerSize; |
820 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 819 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); | 1015 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); |
1017 } else { | 1016 } else { |
1018 CHECK_EQ(bailout_type_, EAGER); | 1017 CHECK_EQ(bailout_type_, EAGER); |
1019 } | 1018 } |
1020 output_frame->SetContinuation( | 1019 output_frame->SetContinuation( |
1021 reinterpret_cast<intptr_t>(continuation->entry())); | 1020 reinterpret_cast<intptr_t>(continuation->entry())); |
1022 } | 1021 } |
1023 } | 1022 } |
1024 | 1023 |
1025 | 1024 |
1026 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, | 1025 void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) { |
1027 int frame_index) { | |
1028 TranslatedFrame* translated_frame = | 1026 TranslatedFrame* translated_frame = |
1029 &(translated_state_.frames()[frame_index]); | 1027 &(translated_state_.frames()[frame_index]); |
1030 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1028 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1031 int input_index = 0; | 1029 int input_index = 0; |
1032 | 1030 |
1033 unsigned height = translated_frame->height(); | 1031 unsigned height = translated_frame->height(); |
1034 unsigned height_in_bytes = height * kPointerSize; | 1032 unsigned height_in_bytes = height * kPointerSize; |
1035 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1033 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1036 value_iterator++; | 1034 value_iterator++; |
1037 input_index++; | 1035 input_index++; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); | 1121 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); |
1124 output_frame->SetPc(pc_value); | 1122 output_frame->SetPc(pc_value); |
1125 if (FLAG_enable_embedded_constant_pool) { | 1123 if (FLAG_enable_embedded_constant_pool) { |
1126 intptr_t constant_pool_value = | 1124 intptr_t constant_pool_value = |
1127 reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool()); | 1125 reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool()); |
1128 output_frame->SetConstantPool(constant_pool_value); | 1126 output_frame->SetConstantPool(constant_pool_value); |
1129 } | 1127 } |
1130 } | 1128 } |
1131 | 1129 |
1132 | 1130 |
1133 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, | 1131 void Deoptimizer::DoComputeConstructStubFrame(int frame_index) { |
1134 int frame_index) { | |
1135 TranslatedFrame* translated_frame = | 1132 TranslatedFrame* translated_frame = |
1136 &(translated_state_.frames()[frame_index]); | 1133 &(translated_state_.frames()[frame_index]); |
1137 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1134 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1138 int input_index = 0; | 1135 int input_index = 0; |
1139 | 1136 |
1140 Builtins* builtins = isolate_->builtins(); | 1137 Builtins* builtins = isolate_->builtins(); |
1141 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 1138 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); |
1142 unsigned height = translated_frame->height(); | 1139 unsigned height = translated_frame->height(); |
1143 unsigned height_in_bytes = height * kPointerSize; | 1140 unsigned height_in_bytes = height * kPointerSize; |
1144 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1141 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 1256 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); |
1260 output_frame->SetPc(pc); | 1257 output_frame->SetPc(pc); |
1261 if (FLAG_enable_embedded_constant_pool) { | 1258 if (FLAG_enable_embedded_constant_pool) { |
1262 intptr_t constant_pool_value = | 1259 intptr_t constant_pool_value = |
1263 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); | 1260 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); |
1264 output_frame->SetConstantPool(constant_pool_value); | 1261 output_frame->SetConstantPool(constant_pool_value); |
1265 } | 1262 } |
1266 } | 1263 } |
1267 | 1264 |
1268 | 1265 |
1269 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, | 1266 void Deoptimizer::DoComputeAccessorStubFrame(int frame_index, |
1270 int frame_index, | |
1271 bool is_setter_stub_frame) { | 1267 bool is_setter_stub_frame) { |
1272 TranslatedFrame* translated_frame = | 1268 TranslatedFrame* translated_frame = |
1273 &(translated_state_.frames()[frame_index]); | 1269 &(translated_state_.frames()[frame_index]); |
1274 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1270 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1275 int input_index = 0; | 1271 int input_index = 0; |
1276 | 1272 |
1277 JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue()); | 1273 JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue()); |
1278 value_iterator++; | 1274 value_iterator++; |
1279 input_index++; | 1275 input_index++; |
1280 // The receiver (and the implicit return value, if any) are expected in | 1276 // The receiver (and the implicit return value, if any) are expected in |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 accessor_stub->instruction_start() + offset->value()); | 1381 accessor_stub->instruction_start() + offset->value()); |
1386 output_frame->SetPc(pc); | 1382 output_frame->SetPc(pc); |
1387 if (FLAG_enable_embedded_constant_pool) { | 1383 if (FLAG_enable_embedded_constant_pool) { |
1388 intptr_t constant_pool_value = | 1384 intptr_t constant_pool_value = |
1389 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); | 1385 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); |
1390 output_frame->SetConstantPool(constant_pool_value); | 1386 output_frame->SetConstantPool(constant_pool_value); |
1391 } | 1387 } |
1392 } | 1388 } |
1393 | 1389 |
1394 | 1390 |
1395 void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, | 1391 void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) { |
1396 int frame_index) { | |
1397 // | 1392 // |
1398 // FROM TO | 1393 // FROM TO |
1399 // | .... | | .... | | 1394 // | .... | | .... | |
1400 // +-------------------------+ +-------------------------+ | 1395 // +-------------------------+ +-------------------------+ |
1401 // | JSFunction continuation | | JSFunction continuation | | 1396 // | JSFunction continuation | | JSFunction continuation | |
1402 // +-------------------------+ +-------------------------+ | 1397 // +-------------------------+ +-------------------------+ |
1403 // | | saved frame (FP) | | saved frame (FP) | | 1398 // | | saved frame (FP) | | saved frame (FP) | |
1404 // | +=========================+<-fpreg +=========================+<-fpreg | 1399 // | +=========================+<-fpreg +=========================+<-fpreg |
1405 // | |constant pool (if ool_cp)| |constant pool (if ool_cp)| | 1400 // | |constant pool (if ool_cp)| |constant pool (if ool_cp)| |
1406 // | +-------------------------+ +-------------------------| | 1401 // | +-------------------------+ +-------------------------| |
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2699 BailoutId node_id = BailoutId(iterator->Next()); | 2694 BailoutId node_id = BailoutId(iterator->Next()); |
2700 SharedFunctionInfo* shared_info = | 2695 SharedFunctionInfo* shared_info = |
2701 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 2696 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2702 int height = iterator->Next(); | 2697 int height = iterator->Next(); |
2703 if (trace_file != nullptr) { | 2698 if (trace_file != nullptr) { |
2704 base::SmartArrayPointer<char> name = | 2699 base::SmartArrayPointer<char> name = |
2705 shared_info->DebugName()->ToCString(); | 2700 shared_info->DebugName()->ToCString(); |
2706 PrintF(trace_file, " reading input frame %s", name.get()); | 2701 PrintF(trace_file, " reading input frame %s", name.get()); |
2707 int arg_count = shared_info->internal_formal_parameter_count() + 1; | 2702 int arg_count = shared_info->internal_formal_parameter_count() + 1; |
2708 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", | 2703 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", |
2709 arg_count, node_id.ToInt(), height); | 2704 node_id.ToInt(), arg_count, height); |
2710 } | 2705 } |
2711 return TranslatedFrame::JSFrame(node_id, shared_info, height); | 2706 return TranslatedFrame::JSFrame(node_id, shared_info, height); |
2712 } | 2707 } |
2713 | 2708 |
2714 case Translation::ARGUMENTS_ADAPTOR_FRAME: { | 2709 case Translation::ARGUMENTS_ADAPTOR_FRAME: { |
2715 SharedFunctionInfo* shared_info = | 2710 SharedFunctionInfo* shared_info = |
2716 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 2711 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2717 int height = iterator->Next(); | 2712 int height = iterator->Next(); |
2718 if (trace_file != nullptr) { | 2713 if (trace_file != nullptr) { |
2719 base::SmartArrayPointer<char> name = | 2714 base::SmartArrayPointer<char> name = |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3402 DCHECK(value_info->IsMaterializedObject()); | 3397 DCHECK(value_info->IsMaterializedObject()); |
3403 | 3398 |
3404 value_info->value_ = | 3399 value_info->value_ = |
3405 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3400 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3406 } | 3401 } |
3407 } | 3402 } |
3408 } | 3403 } |
3409 | 3404 |
3410 } // namespace internal | 3405 } // namespace internal |
3411 } // namespace v8 | 3406 } // namespace v8 |
OLD | NEW |