| 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 |