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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
704 // We rely on this function not causing a GC. It is called from generated code | 704 // We rely on this function not causing a GC. It is called from generated code |
705 // without having a real stack frame in place. | 705 // without having a real stack frame in place. |
706 void Deoptimizer::DoComputeOutputFrames() { | 706 void Deoptimizer::DoComputeOutputFrames() { |
707 base::ElapsedTimer timer; | 707 base::ElapsedTimer timer; |
708 | 708 |
709 // Determine basic deoptimization information. The optimized frame is | 709 // Determine basic deoptimization information. The optimized frame is |
710 // described by the input data. | 710 // described by the input data. |
711 DeoptimizationInputData* input_data = | 711 DeoptimizationInputData* input_data = |
712 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); | 712 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); |
713 | 713 |
| 714 { |
| 715 // Read caller's PC, caller's FP and caller's constant pool values |
| 716 // from input frame. Compute caller's frame top address. |
| 717 |
| 718 Register fp_reg = JavaScriptFrame::fp_register(); |
| 719 stack_fp_ = input_->GetRegister(fp_reg.code()); |
| 720 |
| 721 caller_frame_top_ = stack_fp_ + ComputeInputFrameAboveFpFixedSize(); |
| 722 |
| 723 Address fp_address = input_->GetFramePointerAddress(); |
| 724 caller_fp_ = Memory::intptr_at(fp_address); |
| 725 caller_pc_ = |
| 726 Memory::intptr_at(fp_address + CommonFrameConstants::kCallerPCOffset); |
| 727 input_frame_context_ = Memory::intptr_at( |
| 728 fp_address + CommonFrameConstants::kContextOrFrameTypeOffset); |
| 729 |
| 730 if (FLAG_enable_embedded_constant_pool) { |
| 731 caller_constant_pool_ = Memory::intptr_at( |
| 732 fp_address + CommonFrameConstants::kConstantPoolOffset); |
| 733 } |
| 734 } |
| 735 |
714 if (trace_scope_ != NULL) { | 736 if (trace_scope_ != NULL) { |
715 timer.Start(); | 737 timer.Start(); |
716 PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ", | 738 PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ", |
717 MessageFor(bailout_type_)); | 739 MessageFor(bailout_type_)); |
718 PrintFunctionName(); | 740 PrintFunctionName(); |
719 PrintF(trace_scope_->file(), | 741 PrintF(trace_scope_->file(), |
720 " (opt #%d) @%d, FP to SP delta: %d]\n", | 742 " (opt #%d) @%d, FP to SP delta: %d, caller sp: 0x%08" V8PRIxPTR |
721 input_data->OptimizationId()->value(), | 743 "]\n", |
722 bailout_id_, | 744 input_data->OptimizationId()->value(), bailout_id_, fp_to_sp_delta_, |
723 fp_to_sp_delta_); | 745 caller_frame_top_); |
724 if (bailout_type_ == EAGER || bailout_type_ == SOFT || | 746 if (bailout_type_ == EAGER || bailout_type_ == SOFT || |
725 (compiled_code_->is_hydrogen_stub())) { | 747 (compiled_code_->is_hydrogen_stub())) { |
726 compiled_code_->PrintDeoptLocation(trace_scope_->file(), from_); | 748 compiled_code_->PrintDeoptLocation(trace_scope_->file(), from_); |
727 } | 749 } |
728 } | 750 } |
729 | 751 |
730 BailoutId node_id = input_data->AstId(bailout_id_); | 752 BailoutId node_id = input_data->AstId(bailout_id_); |
731 ByteArray* translations = input_data->TranslationByteArray(); | 753 ByteArray* translations = input_data->TranslationByteArray(); |
732 unsigned translation_index = | 754 unsigned translation_index = |
733 input_data->TranslationIndex(bailout_id_)->value(); | 755 input_data->TranslationIndex(bailout_id_)->value(); |
(...skipping 22 matching lines...) Expand all Loading... |
756 count = catch_handler_frame_index + 1; | 778 count = catch_handler_frame_index + 1; |
757 } | 779 } |
758 | 780 |
759 DCHECK(output_ == NULL); | 781 DCHECK(output_ == NULL); |
760 output_ = new FrameDescription*[count]; | 782 output_ = new FrameDescription*[count]; |
761 for (size_t i = 0; i < count; ++i) { | 783 for (size_t i = 0; i < count; ++i) { |
762 output_[i] = NULL; | 784 output_[i] = NULL; |
763 } | 785 } |
764 output_count_ = static_cast<int>(count); | 786 output_count_ = static_cast<int>(count); |
765 | 787 |
766 { | |
767 // Read caller's PC, caller's FP and caller's constant pool values | |
768 // from input frame. Compute caller's frame top address. | |
769 | |
770 Register fp_reg = JavaScriptFrame::fp_register(); | |
771 stack_fp_ = input_->GetRegister(fp_reg.code()); | |
772 | |
773 caller_frame_top_ = stack_fp_ + ComputeInputFrameAboveFpFixedSize(); | |
774 | |
775 Address fp_address = input_->GetFramePointerAddress(); | |
776 caller_fp_ = Memory::intptr_at(fp_address); | |
777 caller_pc_ = | |
778 Memory::intptr_at(fp_address + StandardFrameConstants::kCallerPCOffset); | |
779 input_frame_context_ = | |
780 Memory::intptr_at(fp_address + StandardFrameConstants::kContextOffset); | |
781 | |
782 if (FLAG_enable_embedded_constant_pool) { | |
783 caller_constant_pool_ = Memory::intptr_at( | |
784 fp_address + StandardFrameConstants::kConstantPoolOffset); | |
785 } | |
786 } | |
787 | |
788 // Translate each output frame. | 788 // Translate each output frame. |
789 for (size_t i = 0; i < count; ++i) { | 789 int frame_index = 0; // output_frame_index |
| 790 for (size_t i = 0; i < count; ++i, ++frame_index) { |
790 // Read the ast node id, function, and frame height for this output frame. | 791 // Read the ast node id, function, and frame height for this output frame. |
791 int frame_index = static_cast<int>(i); | 792 TranslatedFrame* translated_frame = &(translated_state_.frames()[i]); |
792 switch (translated_state_.frames()[i].kind()) { | 793 switch (translated_frame->kind()) { |
793 case TranslatedFrame::kFunction: | 794 case TranslatedFrame::kFunction: |
794 DoComputeJSFrame(frame_index, deoptimizing_throw_ && i == count - 1); | 795 DoComputeJSFrame(translated_frame, frame_index, |
| 796 deoptimizing_throw_ && i == count - 1); |
795 jsframe_count_++; | 797 jsframe_count_++; |
796 break; | 798 break; |
797 case TranslatedFrame::kInterpretedFunction: | 799 case TranslatedFrame::kInterpretedFunction: |
798 DoComputeInterpretedFrame(frame_index, | 800 DoComputeInterpretedFrame(translated_frame, frame_index, |
799 deoptimizing_throw_ && i == count - 1); | 801 deoptimizing_throw_ && i == count - 1); |
800 jsframe_count_++; | 802 jsframe_count_++; |
801 break; | 803 break; |
802 case TranslatedFrame::kArgumentsAdaptor: | 804 case TranslatedFrame::kArgumentsAdaptor: |
803 DoComputeArgumentsAdaptorFrame(frame_index); | 805 DoComputeArgumentsAdaptorFrame(translated_frame, frame_index); |
| 806 break; |
| 807 case TranslatedFrame::kTailCallerFunction: |
| 808 DoComputeTailCallerFrame(translated_frame, frame_index); |
| 809 // Tail caller frame translations do not produce output frames. |
| 810 frame_index--; |
| 811 output_count_--; |
804 break; | 812 break; |
805 case TranslatedFrame::kConstructStub: | 813 case TranslatedFrame::kConstructStub: |
806 DoComputeConstructStubFrame(frame_index); | 814 DoComputeConstructStubFrame(translated_frame, frame_index); |
807 break; | 815 break; |
808 case TranslatedFrame::kGetter: | 816 case TranslatedFrame::kGetter: |
809 DoComputeAccessorStubFrame(frame_index, false); | 817 DoComputeAccessorStubFrame(translated_frame, frame_index, false); |
810 break; | 818 break; |
811 case TranslatedFrame::kSetter: | 819 case TranslatedFrame::kSetter: |
812 DoComputeAccessorStubFrame(frame_index, true); | 820 DoComputeAccessorStubFrame(translated_frame, frame_index, true); |
813 break; | 821 break; |
814 case TranslatedFrame::kCompiledStub: | 822 case TranslatedFrame::kCompiledStub: |
815 DoComputeCompiledStubFrame(frame_index); | 823 DoComputeCompiledStubFrame(translated_frame, frame_index); |
816 break; | 824 break; |
817 case TranslatedFrame::kInvalid: | 825 case TranslatedFrame::kInvalid: |
818 FATAL("invalid frame"); | 826 FATAL("invalid frame"); |
819 break; | 827 break; |
820 } | 828 } |
821 } | 829 } |
822 | 830 |
823 // Print some helpful diagnostic information. | 831 // Print some helpful diagnostic information. |
824 if (trace_scope_ != NULL) { | 832 if (trace_scope_ != NULL) { |
825 double ms = timer.Elapsed().InMillisecondsF(); | 833 double ms = timer.Elapsed().InMillisecondsF(); |
826 int index = output_count_ - 1; // Index of the topmost frame. | 834 int index = output_count_ - 1; // Index of the topmost frame. |
827 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", | 835 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", |
828 MessageFor(bailout_type_)); | 836 MessageFor(bailout_type_)); |
829 PrintFunctionName(); | 837 PrintFunctionName(); |
830 PrintF( | 838 PrintF(trace_scope_->file(), |
831 trace_scope_->file(), | 839 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", caller sp=0x%08" V8PRIxPTR |
832 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n", | 840 ", state=%s, took %0.3f ms]\n", |
833 bailout_id_, node_id.ToInt(), output_[index]->GetPc(), | 841 bailout_id_, node_id.ToInt(), output_[index]->GetPc(), |
834 FullCodeGenerator::State2String(static_cast<FullCodeGenerator::State>( | 842 caller_frame_top_, FullCodeGenerator::State2String( |
835 output_[index]->GetState()->value())), | 843 static_cast<FullCodeGenerator::State>( |
836 ms); | 844 output_[index]->GetState()->value())), |
| 845 ms); |
837 } | 846 } |
838 } | 847 } |
839 | 848 |
840 void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) { | 849 void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame, |
841 TranslatedFrame* translated_frame = | 850 int frame_index, bool goto_catch_handler) { |
842 &(translated_state_.frames()[frame_index]); | |
843 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); | 851 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); |
844 | 852 |
845 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 853 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
846 bool is_bottommost = (0 == frame_index); | 854 bool is_bottommost = (0 == frame_index); |
847 bool is_topmost = (output_count_ - 1 == frame_index); | 855 bool is_topmost = (output_count_ - 1 == frame_index); |
848 int input_index = 0; | 856 int input_index = 0; |
849 | 857 |
850 BailoutId node_id = translated_frame->node_id(); | 858 BailoutId node_id = translated_frame->node_id(); |
851 unsigned height = | 859 unsigned height = |
852 translated_frame->height() - 1; // Do not count the context. | 860 translated_frame->height() - 1; // Do not count the context. |
853 unsigned height_in_bytes = height * kPointerSize; | 861 unsigned height_in_bytes = height * kPointerSize; |
854 if (goto_catch_handler) { | 862 if (goto_catch_handler) { |
855 // Take the stack height from the handler table. | 863 // Take the stack height from the handler table. |
856 height = catch_handler_data_; | 864 height = catch_handler_data_; |
857 // We also make space for the exception itself. | 865 // We also make space for the exception itself. |
858 height_in_bytes = (height + 1) * kPointerSize; | 866 height_in_bytes = (height + 1) * kPointerSize; |
859 CHECK(is_topmost); | 867 CHECK(is_topmost); |
860 } | 868 } |
861 | 869 |
862 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 870 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
863 value_iterator++; | 871 value_iterator++; |
864 input_index++; | 872 input_index++; |
865 if (trace_scope_ != NULL) { | 873 if (trace_scope_ != NULL) { |
866 PrintF(trace_scope_->file(), " translating frame "); | 874 PrintF(trace_scope_->file(), " translating frame "); |
867 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString(); | 875 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString(); |
868 PrintF(trace_scope_->file(), "%s", name.get()); | 876 PrintF(trace_scope_->file(), "%s", name.get()); |
869 PrintF(trace_scope_->file(), | |
870 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | |
871 PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(), | 877 PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(), |
872 height_in_bytes, goto_catch_handler ? " (throw)" : ""); | 878 height_in_bytes, goto_catch_handler ? " (throw)" : ""); |
873 } | 879 } |
874 | 880 |
875 // The 'fixed' part of the frame consists of the incoming parameters and | 881 // The 'fixed' part of the frame consists of the incoming parameters and |
876 // the part described by JavaScriptFrameConstants. | 882 // the part described by JavaScriptFrameConstants. |
877 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared); | 883 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared); |
878 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 884 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
879 | 885 |
880 // Allocate and store the output frame description. | 886 // Allocate and store the output frame description. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + | 1000 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + |
995 output_offset; | 1001 output_offset; |
996 values_to_materialize_.push_back({output_address, context_pos}); | 1002 values_to_materialize_.push_back({output_address, context_pos}); |
997 } | 1003 } |
998 value_iterator++; | 1004 value_iterator++; |
999 input_index++; | 1005 input_index++; |
1000 | 1006 |
1001 // The function was mentioned explicitly in the BEGIN_FRAME. | 1007 // The function was mentioned explicitly in the BEGIN_FRAME. |
1002 output_offset -= kPointerSize; | 1008 output_offset -= kPointerSize; |
1003 value = reinterpret_cast<intptr_t>(function); | 1009 value = reinterpret_cast<intptr_t>(function); |
1004 // The function for the bottommost output frame should also agree with the | |
1005 // input frame. | |
1006 DCHECK(!is_bottommost || reinterpret_cast<intptr_t>(function_) == value); | |
1007 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); | 1010 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); |
1008 | 1011 |
1009 // Translate the rest of the frame. | 1012 // Translate the rest of the frame. |
1010 for (unsigned i = 0; i < height; ++i) { | 1013 for (unsigned i = 0; i < height; ++i) { |
1011 output_offset -= kPointerSize; | 1014 output_offset -= kPointerSize; |
1012 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1015 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1013 output_offset); | 1016 output_offset); |
1014 } | 1017 } |
1015 if (goto_catch_handler) { | 1018 if (goto_catch_handler) { |
1016 // Write out the exception for the catch handler. | 1019 // Write out the exception for the catch handler. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 } else if (bailout_type_ == SOFT) { | 1066 } else if (bailout_type_ == SOFT) { |
1064 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); | 1067 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); |
1065 } else { | 1068 } else { |
1066 CHECK_EQ(bailout_type_, EAGER); | 1069 CHECK_EQ(bailout_type_, EAGER); |
1067 } | 1070 } |
1068 output_frame->SetContinuation( | 1071 output_frame->SetContinuation( |
1069 reinterpret_cast<intptr_t>(continuation->entry())); | 1072 reinterpret_cast<intptr_t>(continuation->entry())); |
1070 } | 1073 } |
1071 } | 1074 } |
1072 | 1075 |
1073 void Deoptimizer::DoComputeInterpretedFrame(int frame_index, | 1076 void Deoptimizer::DoComputeInterpretedFrame(TranslatedFrame* translated_frame, |
| 1077 int frame_index, |
1074 bool goto_catch_handler) { | 1078 bool goto_catch_handler) { |
1075 TranslatedFrame* translated_frame = | |
1076 &(translated_state_.frames()[frame_index]); | |
1077 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); | 1079 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); |
1078 | 1080 |
1079 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1081 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1080 int input_index = 0; | 1082 int input_index = 0; |
1081 | 1083 |
1082 int bytecode_offset = translated_frame->node_id().ToInt(); | 1084 int bytecode_offset = translated_frame->node_id().ToInt(); |
1083 unsigned height = translated_frame->height(); | 1085 unsigned height = translated_frame->height(); |
1084 unsigned height_in_bytes = height * kPointerSize; | 1086 unsigned height_in_bytes = height * kPointerSize; |
1085 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1087 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1086 value_iterator++; | 1088 value_iterator++; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 output_frame->SetContext(value); | 1214 output_frame->SetContext(value); |
1213 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); | 1215 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); |
1214 WriteValueToOutput(context, context_input_index, frame_index, output_offset, | 1216 WriteValueToOutput(context, context_input_index, frame_index, output_offset, |
1215 "context "); | 1217 "context "); |
1216 value_iterator++; | 1218 value_iterator++; |
1217 input_index++; | 1219 input_index++; |
1218 | 1220 |
1219 // The function was mentioned explicitly in the BEGIN_FRAME. | 1221 // The function was mentioned explicitly in the BEGIN_FRAME. |
1220 output_offset -= kPointerSize; | 1222 output_offset -= kPointerSize; |
1221 value = reinterpret_cast<intptr_t>(function); | 1223 value = reinterpret_cast<intptr_t>(function); |
1222 // The function for the bottommost output frame should also agree with the | |
1223 // input frame. | |
1224 DCHECK(!is_bottommost || reinterpret_cast<intptr_t>(function_) == value); | |
1225 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); | 1224 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); |
1226 | 1225 |
1227 // The new.target slot is only used during function activiation which is | 1226 // The new.target slot is only used during function activiation which is |
1228 // before the first deopt point, so should never be needed. Just set it to | 1227 // before the first deopt point, so should never be needed. Just set it to |
1229 // undefined. | 1228 // undefined. |
1230 output_offset -= kPointerSize; | 1229 output_offset -= kPointerSize; |
1231 Object* new_target = isolate_->heap()->undefined_value(); | 1230 Object* new_target = isolate_->heap()->undefined_value(); |
1232 WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target "); | 1231 WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target "); |
1233 | 1232 |
1234 // Set the bytecode array pointer. | 1233 // Set the bytecode array pointer. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 continuation = | 1297 continuation = |
1299 builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized); | 1298 builtins->builtin(Builtins::kInterpreterNotifySoftDeoptimized); |
1300 } else { | 1299 } else { |
1301 CHECK_EQ(bailout_type_, EAGER); | 1300 CHECK_EQ(bailout_type_, EAGER); |
1302 } | 1301 } |
1303 output_frame->SetContinuation( | 1302 output_frame->SetContinuation( |
1304 reinterpret_cast<intptr_t>(continuation->entry())); | 1303 reinterpret_cast<intptr_t>(continuation->entry())); |
1305 } | 1304 } |
1306 } | 1305 } |
1307 | 1306 |
1308 | 1307 void Deoptimizer::DoComputeArgumentsAdaptorFrame( |
1309 void Deoptimizer::DoComputeArgumentsAdaptorFrame(int frame_index) { | 1308 TranslatedFrame* translated_frame, int frame_index) { |
1310 TranslatedFrame* translated_frame = | |
1311 &(translated_state_.frames()[frame_index]); | |
1312 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1309 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
| 1310 bool is_bottommost = (0 == frame_index); |
1313 int input_index = 0; | 1311 int input_index = 0; |
1314 | 1312 |
1315 unsigned height = translated_frame->height(); | 1313 unsigned height = translated_frame->height(); |
1316 unsigned height_in_bytes = height * kPointerSize; | 1314 unsigned height_in_bytes = height * kPointerSize; |
1317 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1315 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
1318 value_iterator++; | 1316 value_iterator++; |
1319 input_index++; | 1317 input_index++; |
1320 if (trace_scope_ != NULL) { | 1318 if (trace_scope_ != NULL) { |
1321 PrintF(trace_scope_->file(), | 1319 PrintF(trace_scope_->file(), |
1322 " translating arguments adaptor => height=%d\n", height_in_bytes); | 1320 " translating arguments adaptor => height=%d\n", height_in_bytes); |
1323 } | 1321 } |
1324 | 1322 |
1325 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFixedFrameSize; | 1323 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFixedFrameSize; |
1326 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1324 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1327 | 1325 |
1328 // Allocate and store the output frame description. | 1326 // Allocate and store the output frame description. |
1329 int parameter_count = height; | 1327 int parameter_count = height; |
1330 FrameDescription* output_frame = new (output_frame_size) | 1328 FrameDescription* output_frame = new (output_frame_size) |
1331 FrameDescription(output_frame_size, parameter_count); | 1329 FrameDescription(output_frame_size, parameter_count); |
1332 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); | 1330 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); |
1333 | 1331 |
1334 // Arguments adaptor can not be topmost or bottommost. | 1332 // Arguments adaptor can not be topmost. |
1335 CHECK(frame_index > 0 && frame_index < output_count_ - 1); | 1333 CHECK(frame_index < output_count_ - 1); |
1336 CHECK(output_[frame_index] == NULL); | 1334 CHECK(output_[frame_index] == NULL); |
1337 output_[frame_index] = output_frame; | 1335 output_[frame_index] = output_frame; |
1338 | 1336 |
1339 // The top address of the frame is computed from the previous | 1337 // The top address of the frame is computed from the previous |
1340 // frame's top and this frame's size. | 1338 // frame's top and this frame's size. |
1341 intptr_t top_address; | 1339 intptr_t top_address; |
1342 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1340 if (is_bottommost) { |
| 1341 top_address = caller_frame_top_ - output_frame_size; |
| 1342 } else { |
| 1343 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 1344 } |
1343 output_frame->SetTop(top_address); | 1345 output_frame->SetTop(top_address); |
1344 | 1346 |
1345 // Compute the incoming parameter translation. | 1347 // Compute the incoming parameter translation. |
1346 unsigned output_offset = output_frame_size; | 1348 unsigned output_offset = output_frame_size; |
1347 for (int i = 0; i < parameter_count; ++i) { | 1349 for (int i = 0; i < parameter_count; ++i) { |
1348 output_offset -= kPointerSize; | 1350 output_offset -= kPointerSize; |
1349 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1351 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1350 output_offset); | 1352 output_offset); |
1351 } | 1353 } |
1352 | 1354 |
1353 // Read caller's PC from the previous frame. | 1355 // Read caller's PC from the previous frame. |
1354 output_offset -= kPCOnStackSize; | 1356 output_offset -= kPCOnStackSize; |
1355 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 1357 intptr_t value; |
1356 output_frame->SetCallerPc(output_offset, callers_pc); | 1358 if (is_bottommost) { |
1357 DebugPrintOutputSlot(callers_pc, frame_index, output_offset, "caller's pc\n"); | 1359 value = caller_pc_; |
| 1360 } else { |
| 1361 value = output_[frame_index - 1]->GetPc(); |
| 1362 } |
| 1363 output_frame->SetCallerPc(output_offset, value); |
| 1364 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); |
1358 | 1365 |
1359 // Read caller's FP from the previous frame, and set this frame's FP. | 1366 // Read caller's FP from the previous frame, and set this frame's FP. |
1360 output_offset -= kFPOnStackSize; | 1367 output_offset -= kFPOnStackSize; |
1361 intptr_t value = output_[frame_index - 1]->GetFp(); | 1368 if (is_bottommost) { |
| 1369 value = caller_fp_; |
| 1370 } else { |
| 1371 value = output_[frame_index - 1]->GetFp(); |
| 1372 } |
1362 output_frame->SetCallerFp(output_offset, value); | 1373 output_frame->SetCallerFp(output_offset, value); |
1363 intptr_t fp_value = top_address + output_offset; | 1374 intptr_t fp_value = top_address + output_offset; |
1364 output_frame->SetFp(fp_value); | 1375 output_frame->SetFp(fp_value); |
1365 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 1376 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
1366 | 1377 |
1367 if (FLAG_enable_embedded_constant_pool) { | 1378 if (FLAG_enable_embedded_constant_pool) { |
1368 // Read the caller's constant pool from the previous frame. | 1379 // Read the caller's constant pool from the previous frame. |
1369 output_offset -= kPointerSize; | 1380 output_offset -= kPointerSize; |
1370 value = output_[frame_index - 1]->GetConstantPool(); | 1381 value = output_[frame_index - 1]->GetConstantPool(); |
1371 output_frame->SetCallerConstantPool(output_offset, value); | 1382 output_frame->SetCallerConstantPool(output_offset, value); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1404 adaptor_trampoline->instruction_start() + | 1415 adaptor_trampoline->instruction_start() + |
1405 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); | 1416 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); |
1406 output_frame->SetPc(pc_value); | 1417 output_frame->SetPc(pc_value); |
1407 if (FLAG_enable_embedded_constant_pool) { | 1418 if (FLAG_enable_embedded_constant_pool) { |
1408 intptr_t constant_pool_value = | 1419 intptr_t constant_pool_value = |
1409 reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool()); | 1420 reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool()); |
1410 output_frame->SetConstantPool(constant_pool_value); | 1421 output_frame->SetConstantPool(constant_pool_value); |
1411 } | 1422 } |
1412 } | 1423 } |
1413 | 1424 |
| 1425 void Deoptimizer::DoComputeTailCallerFrame(TranslatedFrame* translated_frame, |
| 1426 int frame_index) { |
| 1427 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); |
1414 | 1428 |
1415 void Deoptimizer::DoComputeConstructStubFrame(int frame_index) { | 1429 bool is_bottommost = (0 == frame_index); |
1416 TranslatedFrame* translated_frame = | 1430 // Tail caller frame can't be topmost. |
1417 &(translated_state_.frames()[frame_index]); | 1431 DCHECK_NE(output_count_ - 1, frame_index); |
| 1432 |
| 1433 if (trace_scope_ != NULL) { |
| 1434 PrintF(trace_scope_->file(), " translating tail caller frame "); |
| 1435 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString(); |
| 1436 PrintF(trace_scope_->file(), "%s\n", name.get()); |
| 1437 } |
| 1438 |
| 1439 if (!is_bottommost) return; |
| 1440 |
| 1441 // Drop arguments adaptor frame below current frame if it exsits. |
| 1442 Address fp_address = input_->GetFramePointerAddress(); |
| 1443 Address adaptor_fp_address = |
| 1444 Memory::Address_at(fp_address + CommonFrameConstants::kCallerFPOffset); |
| 1445 |
| 1446 if (Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR) != |
| 1447 Memory::Object_at(adaptor_fp_address + |
| 1448 CommonFrameConstants::kContextOrFrameTypeOffset)) { |
| 1449 return; |
| 1450 } |
| 1451 |
| 1452 int caller_params_count = |
| 1453 Smi::cast( |
| 1454 Memory::Object_at(adaptor_fp_address + |
| 1455 ArgumentsAdaptorFrameConstants::kLengthOffset)) |
| 1456 ->value(); |
| 1457 |
| 1458 int callee_params_count = |
| 1459 function_->shared()->internal_formal_parameter_count(); |
| 1460 |
| 1461 // Both caller and callee parameters count do not include receiver. |
| 1462 int offset = (caller_params_count - callee_params_count) * kPointerSize; |
| 1463 intptr_t new_stack_fp = |
| 1464 reinterpret_cast<intptr_t>(adaptor_fp_address) + offset; |
| 1465 |
| 1466 intptr_t new_caller_frame_top = new_stack_fp + |
| 1467 (callee_params_count + 1) * kPointerSize + |
| 1468 CommonFrameConstants::kFixedFrameSizeAboveFp; |
| 1469 |
| 1470 intptr_t adaptor_caller_pc = Memory::intptr_at( |
| 1471 adaptor_fp_address + CommonFrameConstants::kCallerPCOffset); |
| 1472 intptr_t adaptor_caller_fp = Memory::intptr_at( |
| 1473 adaptor_fp_address + CommonFrameConstants::kCallerFPOffset); |
| 1474 |
| 1475 if (trace_scope_ != NULL) { |
| 1476 PrintF(trace_scope_->file(), |
| 1477 " dropping caller arguments adaptor frame: offset=%d, " |
| 1478 "fp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR |
| 1479 ", " |
| 1480 "caller sp: 0x%08" V8PRIxPTR " -> 0x%08" V8PRIxPTR "\n", |
| 1481 offset, stack_fp_, new_stack_fp, caller_frame_top_, |
| 1482 new_caller_frame_top); |
| 1483 } |
| 1484 stack_fp_ = new_stack_fp; |
| 1485 caller_frame_top_ = new_caller_frame_top; |
| 1486 caller_fp_ = adaptor_caller_fp; |
| 1487 caller_pc_ = adaptor_caller_pc; |
| 1488 } |
| 1489 |
| 1490 void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame, |
| 1491 int frame_index) { |
1418 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1492 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1419 int input_index = 0; | 1493 int input_index = 0; |
1420 | 1494 |
1421 Builtins* builtins = isolate_->builtins(); | 1495 Builtins* builtins = isolate_->builtins(); |
1422 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 1496 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); |
1423 unsigned height = translated_frame->height(); | 1497 unsigned height = translated_frame->height(); |
1424 unsigned height_in_bytes = height * kPointerSize; | 1498 unsigned height_in_bytes = height * kPointerSize; |
1425 // Skip function. | 1499 // Skip function. |
1426 value_iterator++; | 1500 value_iterator++; |
1427 input_index++; | 1501 input_index++; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1527 construct_stub->instruction_start() + | 1601 construct_stub->instruction_start() + |
1528 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 1602 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); |
1529 output_frame->SetPc(pc); | 1603 output_frame->SetPc(pc); |
1530 if (FLAG_enable_embedded_constant_pool) { | 1604 if (FLAG_enable_embedded_constant_pool) { |
1531 intptr_t constant_pool_value = | 1605 intptr_t constant_pool_value = |
1532 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); | 1606 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); |
1533 output_frame->SetConstantPool(constant_pool_value); | 1607 output_frame->SetConstantPool(constant_pool_value); |
1534 } | 1608 } |
1535 } | 1609 } |
1536 | 1610 |
1537 | 1611 void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame, |
1538 void Deoptimizer::DoComputeAccessorStubFrame(int frame_index, | 1612 int frame_index, |
1539 bool is_setter_stub_frame) { | 1613 bool is_setter_stub_frame) { |
1540 TranslatedFrame* translated_frame = | |
1541 &(translated_state_.frames()[frame_index]); | |
1542 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1614 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1543 int input_index = 0; | 1615 int input_index = 0; |
1544 | 1616 |
1545 // Skip accessor. | 1617 // Skip accessor. |
1546 value_iterator++; | 1618 value_iterator++; |
1547 input_index++; | 1619 input_index++; |
1548 // The receiver (and the implicit return value, if any) are expected in | 1620 // The receiver (and the implicit return value, if any) are expected in |
1549 // registers by the LoadIC/StoreIC, so they don't belong to the output stack | 1621 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
1550 // frame. This means that we have to use a height of 0. | 1622 // frame. This means that we have to use a height of 0. |
1551 unsigned height = 0; | 1623 unsigned height = 0; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 intptr_t pc = reinterpret_cast<intptr_t>( | 1724 intptr_t pc = reinterpret_cast<intptr_t>( |
1653 accessor_stub->instruction_start() + offset->value()); | 1725 accessor_stub->instruction_start() + offset->value()); |
1654 output_frame->SetPc(pc); | 1726 output_frame->SetPc(pc); |
1655 if (FLAG_enable_embedded_constant_pool) { | 1727 if (FLAG_enable_embedded_constant_pool) { |
1656 intptr_t constant_pool_value = | 1728 intptr_t constant_pool_value = |
1657 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); | 1729 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); |
1658 output_frame->SetConstantPool(constant_pool_value); | 1730 output_frame->SetConstantPool(constant_pool_value); |
1659 } | 1731 } |
1660 } | 1732 } |
1661 | 1733 |
1662 | 1734 void Deoptimizer::DoComputeCompiledStubFrame(TranslatedFrame* translated_frame, |
1663 void Deoptimizer::DoComputeCompiledStubFrame(int frame_index) { | 1735 int frame_index) { |
1664 // | 1736 // |
1665 // FROM TO | 1737 // FROM TO |
1666 // | .... | | .... | | 1738 // | .... | | .... | |
1667 // +-------------------------+ +-------------------------+ | 1739 // +-------------------------+ +-------------------------+ |
1668 // | JSFunction continuation | | JSFunction continuation | | 1740 // | JSFunction continuation | | JSFunction continuation | |
1669 // +-------------------------+ +-------------------------+ | 1741 // +-------------------------+ +-------------------------+ |
1670 // | | saved frame (FP) | | saved frame (FP) | | 1742 // | | saved frame (FP) | | saved frame (FP) | |
1671 // | +=========================+<-fpreg +=========================+<-fpreg | 1743 // | +=========================+<-fpreg +=========================+<-fpreg |
1672 // | |constant pool (if ool_cp)| |constant pool (if ool_cp)| | 1744 // | |constant pool (if ool_cp)| |constant pool (if ool_cp)| |
1673 // | +-------------------------+ +-------------------------| | 1745 // | +-------------------------+ +-------------------------| |
(...skipping 15 matching lines...) Expand all Loading... |
1689 // +-------------------------+<-spreg | 1761 // +-------------------------+<-spreg |
1690 // reg = number of parameters | 1762 // reg = number of parameters |
1691 // reg = failure handler address | 1763 // reg = failure handler address |
1692 // reg = saved frame | 1764 // reg = saved frame |
1693 // reg = JSFunction context | 1765 // reg = JSFunction context |
1694 // | 1766 // |
1695 // Caller stack params contain the register parameters to the stub first, | 1767 // Caller stack params contain the register parameters to the stub first, |
1696 // and then, if the descriptor specifies a constant number of stack | 1768 // and then, if the descriptor specifies a constant number of stack |
1697 // parameters, the stack parameters as well. | 1769 // parameters, the stack parameters as well. |
1698 | 1770 |
1699 TranslatedFrame* translated_frame = | |
1700 &(translated_state_.frames()[frame_index]); | |
1701 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1771 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1702 int input_index = 0; | 1772 int input_index = 0; |
1703 | 1773 |
1704 CHECK(compiled_code_->is_hydrogen_stub()); | 1774 CHECK(compiled_code_->is_hydrogen_stub()); |
1705 int major_key = CodeStub::GetMajorKey(compiled_code_); | 1775 int major_key = CodeStub::GetMajorKey(compiled_code_); |
1706 CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key()); | 1776 CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key()); |
1707 | 1777 |
1708 // The output frame must have room for all pushed register parameters | 1778 // The output frame must have room for all pushed register parameters |
1709 // and the standard stack frame slots. Include space for an argument | 1779 // and the standard stack frame slots. Include space for an argument |
1710 // object to the callee and optionally the space to pass the argument | 1780 // object to the callee and optionally the space to pass the argument |
(...skipping 20 matching lines...) Expand all Loading... |
1731 new (output_frame_size) FrameDescription(output_frame_size); | 1801 new (output_frame_size) FrameDescription(output_frame_size); |
1732 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); | 1802 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); |
1733 CHECK_EQ(frame_index, 0); | 1803 CHECK_EQ(frame_index, 0); |
1734 output_[frame_index] = output_frame; | 1804 output_[frame_index] = output_frame; |
1735 | 1805 |
1736 // The top address for the output frame can be computed from the input | 1806 // The top address for the output frame can be computed from the input |
1737 // frame pointer and the output frame's height. Subtract space for the | 1807 // frame pointer and the output frame's height. Subtract space for the |
1738 // context and function slots. | 1808 // context and function slots. |
1739 Register fp_reg = StubFailureTrampolineFrame::fp_register(); | 1809 Register fp_reg = StubFailureTrampolineFrame::fp_register(); |
1740 intptr_t top_address = | 1810 intptr_t top_address = |
1741 stack_fp_ - // input_->GetRegister(fp_reg.code()) - | 1811 stack_fp_ - StubFailureTrampolineFrameConstants::kFixedFrameSizeFromFp - |
1742 StubFailureTrampolineFrameConstants::kFixedFrameSizeFromFp - | |
1743 height_in_bytes; | 1812 height_in_bytes; |
1744 output_frame->SetTop(top_address); | 1813 output_frame->SetTop(top_address); |
1745 | 1814 |
1746 // Set caller's PC (JSFunction continuation). | 1815 // Set caller's PC (JSFunction continuation). |
1747 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; | 1816 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; |
1748 intptr_t value = caller_pc_; | 1817 intptr_t value = caller_pc_; |
1749 output_frame->SetCallerPc(output_frame_offset, value); | 1818 output_frame->SetCallerPc(output_frame_offset, value); |
1750 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1819 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
1751 "caller's pc\n"); | 1820 "caller's pc\n"); |
1752 | 1821 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 unsigned fixed_size = CommonFrameConstants::kFixedFrameSizeAboveFp; | 2052 unsigned fixed_size = CommonFrameConstants::kFixedFrameSizeAboveFp; |
1984 if (!function_->IsSmi()) { | 2053 if (!function_->IsSmi()) { |
1985 fixed_size += ComputeIncomingArgumentSize(function_->shared()); | 2054 fixed_size += ComputeIncomingArgumentSize(function_->shared()); |
1986 } | 2055 } |
1987 return fixed_size; | 2056 return fixed_size; |
1988 } | 2057 } |
1989 | 2058 |
1990 unsigned Deoptimizer::ComputeInputFrameSize() const { | 2059 unsigned Deoptimizer::ComputeInputFrameSize() const { |
1991 // The fp-to-sp delta already takes the context, constant pool pointer and the | 2060 // The fp-to-sp delta already takes the context, constant pool pointer and the |
1992 // function into account so we have to avoid double counting them. | 2061 // function into account so we have to avoid double counting them. |
1993 unsigned fixed_size_from_fp = ComputeInputFrameAboveFpFixedSize(); | 2062 unsigned fixed_size_above_fp = ComputeInputFrameAboveFpFixedSize(); |
1994 unsigned result = fixed_size_from_fp + fp_to_sp_delta_; | 2063 unsigned result = fixed_size_above_fp + fp_to_sp_delta_; |
1995 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 2064 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
1996 unsigned stack_slots = compiled_code_->stack_slots(); | 2065 unsigned stack_slots = compiled_code_->stack_slots(); |
1997 unsigned outgoing_size = | 2066 unsigned outgoing_size = |
1998 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); | 2067 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); |
1999 CHECK(result == | 2068 CHECK_EQ(fixed_size_above_fp + (stack_slots * kPointerSize) - |
2000 fixed_size_from_fp + (stack_slots * kPointerSize) - | 2069 CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size, |
2001 CommonFrameConstants::kFixedFrameSizeAboveFp + outgoing_size); | 2070 result); |
2002 } | 2071 } |
2003 return result; | 2072 return result; |
2004 } | 2073 } |
2005 | 2074 |
2006 // static | 2075 // static |
2007 unsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) { | 2076 unsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) { |
2008 // The fixed part of the frame consists of the return address, frame | 2077 // The fixed part of the frame consists of the return address, frame |
2009 // pointer, function, context, and all the incoming arguments. | 2078 // pointer, function, context, and all the incoming arguments. |
2010 return ComputeIncomingArgumentSize(shared) + | 2079 return ComputeIncomingArgumentSize(shared) + |
2011 StandardFrameConstants::kFixedFrameSize; | 2080 StandardFrameConstants::kFixedFrameSize; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2189 buffer_->Add(literal_id, zone()); | 2258 buffer_->Add(literal_id, zone()); |
2190 } | 2259 } |
2191 | 2260 |
2192 | 2261 |
2193 void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { | 2262 void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { |
2194 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone()); | 2263 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone()); |
2195 buffer_->Add(literal_id, zone()); | 2264 buffer_->Add(literal_id, zone()); |
2196 buffer_->Add(height, zone()); | 2265 buffer_->Add(height, zone()); |
2197 } | 2266 } |
2198 | 2267 |
| 2268 void Translation::BeginTailCallerFrame(int literal_id) { |
| 2269 buffer_->Add(TAIL_CALLER_FRAME, zone()); |
| 2270 buffer_->Add(literal_id, zone()); |
| 2271 } |
2199 | 2272 |
2200 void Translation::BeginJSFrame(BailoutId node_id, | 2273 void Translation::BeginJSFrame(BailoutId node_id, |
2201 int literal_id, | 2274 int literal_id, |
2202 unsigned height) { | 2275 unsigned height) { |
2203 buffer_->Add(JS_FRAME, zone()); | 2276 buffer_->Add(JS_FRAME, zone()); |
2204 buffer_->Add(node_id.ToInt(), zone()); | 2277 buffer_->Add(node_id.ToInt(), zone()); |
2205 buffer_->Add(literal_id, zone()); | 2278 buffer_->Add(literal_id, zone()); |
2206 buffer_->Add(height, zone()); | 2279 buffer_->Add(height, zone()); |
2207 } | 2280 } |
2208 | 2281 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2334 case UINT32_REGISTER: | 2407 case UINT32_REGISTER: |
2335 case BOOL_REGISTER: | 2408 case BOOL_REGISTER: |
2336 case DOUBLE_REGISTER: | 2409 case DOUBLE_REGISTER: |
2337 case STACK_SLOT: | 2410 case STACK_SLOT: |
2338 case INT32_STACK_SLOT: | 2411 case INT32_STACK_SLOT: |
2339 case UINT32_STACK_SLOT: | 2412 case UINT32_STACK_SLOT: |
2340 case BOOL_STACK_SLOT: | 2413 case BOOL_STACK_SLOT: |
2341 case DOUBLE_STACK_SLOT: | 2414 case DOUBLE_STACK_SLOT: |
2342 case LITERAL: | 2415 case LITERAL: |
2343 case COMPILED_STUB_FRAME: | 2416 case COMPILED_STUB_FRAME: |
| 2417 case TAIL_CALLER_FRAME: |
2344 return 1; | 2418 return 1; |
2345 case BEGIN: | 2419 case BEGIN: |
2346 case ARGUMENTS_ADAPTOR_FRAME: | 2420 case ARGUMENTS_ADAPTOR_FRAME: |
2347 case CONSTRUCT_STUB_FRAME: | 2421 case CONSTRUCT_STUB_FRAME: |
2348 return 2; | 2422 return 2; |
2349 case JS_FRAME: | 2423 case JS_FRAME: |
2350 case INTERPRETED_FRAME: | 2424 case INTERPRETED_FRAME: |
2351 return 3; | 2425 return 3; |
2352 } | 2426 } |
2353 FATAL("Unexpected translation type"); | 2427 FATAL("Unexpected translation type"); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2893 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); | 2967 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); |
2894 } | 2968 } |
2895 | 2969 |
2896 | 2970 |
2897 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( | 2971 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( |
2898 SharedFunctionInfo* shared_info, int height) { | 2972 SharedFunctionInfo* shared_info, int height) { |
2899 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), | 2973 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), |
2900 shared_info, height); | 2974 shared_info, height); |
2901 } | 2975 } |
2902 | 2976 |
| 2977 TranslatedFrame TranslatedFrame::TailCallerFrame( |
| 2978 SharedFunctionInfo* shared_info) { |
| 2979 return TranslatedFrame(kTailCallerFunction, shared_info->GetIsolate(), |
| 2980 shared_info, 0); |
| 2981 } |
2903 | 2982 |
2904 TranslatedFrame TranslatedFrame::ConstructStubFrame( | 2983 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
2905 SharedFunctionInfo* shared_info, int height) { | 2984 SharedFunctionInfo* shared_info, int height) { |
2906 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, | 2985 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, |
2907 height); | 2986 height); |
2908 } | 2987 } |
2909 | 2988 |
2910 | 2989 |
2911 int TranslatedFrame::GetValueCount() { | 2990 int TranslatedFrame::GetValueCount() { |
2912 switch (kind()) { | 2991 switch (kind()) { |
(...skipping 14 matching lines...) Expand all Loading... |
2927 case kGetter: | 3006 case kGetter: |
2928 return 2; // Function and receiver. | 3007 return 2; // Function and receiver. |
2929 | 3008 |
2930 case kSetter: | 3009 case kSetter: |
2931 return 3; // Function, receiver and the value to set. | 3010 return 3; // Function, receiver and the value to set. |
2932 | 3011 |
2933 case kArgumentsAdaptor: | 3012 case kArgumentsAdaptor: |
2934 case kConstructStub: | 3013 case kConstructStub: |
2935 return 1 + height_; | 3014 return 1 + height_; |
2936 | 3015 |
| 3016 case kTailCallerFunction: |
| 3017 return 1; // Function. |
| 3018 |
2937 case kCompiledStub: | 3019 case kCompiledStub: |
2938 return height_; | 3020 return height_; |
2939 | 3021 |
2940 case kInvalid: | 3022 case kInvalid: |
2941 UNREACHABLE(); | 3023 UNREACHABLE(); |
2942 break; | 3024 break; |
2943 } | 3025 } |
2944 UNREACHABLE(); | 3026 UNREACHABLE(); |
2945 return -1; | 3027 return -1; |
2946 } | 3028 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3003 int height = iterator->Next(); | 3085 int height = iterator->Next(); |
3004 if (trace_file != nullptr) { | 3086 if (trace_file != nullptr) { |
3005 base::SmartArrayPointer<char> name = | 3087 base::SmartArrayPointer<char> name = |
3006 shared_info->DebugName()->ToCString(); | 3088 shared_info->DebugName()->ToCString(); |
3007 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); | 3089 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); |
3008 PrintF(trace_file, " => height=%d; inputs:\n", height); | 3090 PrintF(trace_file, " => height=%d; inputs:\n", height); |
3009 } | 3091 } |
3010 return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height); | 3092 return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height); |
3011 } | 3093 } |
3012 | 3094 |
| 3095 case Translation::TAIL_CALLER_FRAME: { |
| 3096 SharedFunctionInfo* shared_info = |
| 3097 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
| 3098 if (trace_file != nullptr) { |
| 3099 base::SmartArrayPointer<char> name = |
| 3100 shared_info->DebugName()->ToCString(); |
| 3101 PrintF(trace_file, " reading tail caller frame marker %s\n", |
| 3102 name.get()); |
| 3103 } |
| 3104 return TranslatedFrame::TailCallerFrame(shared_info); |
| 3105 } |
| 3106 |
3013 case Translation::CONSTRUCT_STUB_FRAME: { | 3107 case Translation::CONSTRUCT_STUB_FRAME: { |
3014 SharedFunctionInfo* shared_info = | 3108 SharedFunctionInfo* shared_info = |
3015 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); | 3109 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
3016 int height = iterator->Next(); | 3110 int height = iterator->Next(); |
3017 if (trace_file != nullptr) { | 3111 if (trace_file != nullptr) { |
3018 base::SmartArrayPointer<char> name = | 3112 base::SmartArrayPointer<char> name = |
3019 shared_info->DebugName()->ToCString(); | 3113 shared_info->DebugName()->ToCString(); |
3020 PrintF(trace_file, " reading construct stub frame %s", name.get()); | 3114 PrintF(trace_file, " reading construct stub frame %s", name.get()); |
3021 PrintF(trace_file, " => height=%d; inputs:\n", height); | 3115 PrintF(trace_file, " => height=%d; inputs:\n", height); |
3022 } | 3116 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3103 FILE* trace_file) { | 3197 FILE* trace_file) { |
3104 disasm::NameConverter converter; | 3198 disasm::NameConverter converter; |
3105 | 3199 |
3106 Translation::Opcode opcode = | 3200 Translation::Opcode opcode = |
3107 static_cast<Translation::Opcode>(iterator->Next()); | 3201 static_cast<Translation::Opcode>(iterator->Next()); |
3108 switch (opcode) { | 3202 switch (opcode) { |
3109 case Translation::BEGIN: | 3203 case Translation::BEGIN: |
3110 case Translation::JS_FRAME: | 3204 case Translation::JS_FRAME: |
3111 case Translation::INTERPRETED_FRAME: | 3205 case Translation::INTERPRETED_FRAME: |
3112 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 3206 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 3207 case Translation::TAIL_CALLER_FRAME: |
3113 case Translation::CONSTRUCT_STUB_FRAME: | 3208 case Translation::CONSTRUCT_STUB_FRAME: |
3114 case Translation::GETTER_STUB_FRAME: | 3209 case Translation::GETTER_STUB_FRAME: |
3115 case Translation::SETTER_STUB_FRAME: | 3210 case Translation::SETTER_STUB_FRAME: |
3116 case Translation::COMPILED_STUB_FRAME: | 3211 case Translation::COMPILED_STUB_FRAME: |
3117 // Peeled off before getting here. | 3212 // Peeled off before getting here. |
3118 break; | 3213 break; |
3119 | 3214 |
3120 case Translation::DUPLICATED_OBJECT: { | 3215 case Translation::DUPLICATED_OBJECT: { |
3121 int object_id = iterator->Next(); | 3216 int object_id = iterator->Next(); |
3122 if (trace_file != nullptr) { | 3217 if (trace_file != nullptr) { |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3714 CHECK(value_info->IsMaterializedObject()); | 3809 CHECK(value_info->IsMaterializedObject()); |
3715 | 3810 |
3716 value_info->value_ = | 3811 value_info->value_ = |
3717 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3812 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3718 } | 3813 } |
3719 } | 3814 } |
3720 } | 3815 } |
3721 | 3816 |
3722 } // namespace internal | 3817 } // namespace internal |
3723 } // namespace v8 | 3818 } // namespace v8 |
OLD | NEW |