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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 bailout_type_(type), | 474 bailout_type_(type), |
475 from_(from), | 475 from_(from), |
476 fp_to_sp_delta_(fp_to_sp_delta), | 476 fp_to_sp_delta_(fp_to_sp_delta), |
477 deoptimizing_throw_(false), | 477 deoptimizing_throw_(false), |
478 catch_handler_data_(-1), | 478 catch_handler_data_(-1), |
479 catch_handler_pc_offset_(-1), | 479 catch_handler_pc_offset_(-1), |
480 input_(nullptr), | 480 input_(nullptr), |
481 output_count_(0), | 481 output_count_(0), |
482 jsframe_count_(0), | 482 jsframe_count_(0), |
483 output_(nullptr), | 483 output_(nullptr), |
| 484 caller_frame_top_(0), |
| 485 caller_fp_(0), |
| 486 caller_pc_(0), |
| 487 caller_constant_pool_(0), |
| 488 input_frame_context_(0), |
| 489 stack_fp_(0), |
484 trace_scope_(nullptr) { | 490 trace_scope_(nullptr) { |
485 if (isolate->deoptimizer_lazy_throw()) { | 491 if (isolate->deoptimizer_lazy_throw()) { |
486 isolate->set_deoptimizer_lazy_throw(false); | 492 isolate->set_deoptimizer_lazy_throw(false); |
487 deoptimizing_throw_ = true; | 493 deoptimizing_throw_ = true; |
488 } | 494 } |
489 | 495 |
490 // For COMPILED_STUBs called from builtins, the function pointer is a SMI | 496 // For COMPILED_STUBs called from builtins, the function pointer is a SMI |
491 // indicating an internal frame. | 497 // indicating an internal frame. |
492 if (function->IsSmi()) { | 498 if (function->IsSmi()) { |
493 function = nullptr; | 499 function = nullptr; |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 count = catch_handler_frame_index + 1; | 761 count = catch_handler_frame_index + 1; |
756 } | 762 } |
757 | 763 |
758 DCHECK(output_ == NULL); | 764 DCHECK(output_ == NULL); |
759 output_ = new FrameDescription*[count]; | 765 output_ = new FrameDescription*[count]; |
760 for (size_t i = 0; i < count; ++i) { | 766 for (size_t i = 0; i < count; ++i) { |
761 output_[i] = NULL; | 767 output_[i] = NULL; |
762 } | 768 } |
763 output_count_ = static_cast<int>(count); | 769 output_count_ = static_cast<int>(count); |
764 | 770 |
765 Register fp_reg = JavaScriptFrame::fp_register(); | 771 { |
766 stack_fp_ = reinterpret_cast<Address>(input_->GetRegister(fp_reg.code())); | 772 // Read caller's PC, caller's FP and caller's constant pool values |
| 773 // from input frame. Compute caller's frame top address. |
| 774 |
| 775 Register fp_reg = JavaScriptFrame::fp_register(); |
| 776 stack_fp_ = input_->GetRegister(fp_reg.code()); |
| 777 |
| 778 caller_frame_top_ = stack_fp_ + ComputeInputFrameAboveFpFixedSize(); |
| 779 |
| 780 Address fp_address = input_->GetFramePointerAddress(); |
| 781 caller_fp_ = Memory::intptr_at(fp_address); |
| 782 caller_pc_ = |
| 783 Memory::intptr_at(fp_address + StandardFrameConstants::kCallerPCOffset); |
| 784 input_frame_context_ = |
| 785 Memory::intptr_at(fp_address + StandardFrameConstants::kContextOffset); |
| 786 |
| 787 if (FLAG_enable_embedded_constant_pool) { |
| 788 caller_constant_pool_ = Memory::intptr_at( |
| 789 fp_address + StandardFrameConstants::kConstantPoolOffset); |
| 790 } |
| 791 } |
767 | 792 |
768 // Translate each output frame. | 793 // Translate each output frame. |
769 for (size_t i = 0; i < count; ++i) { | 794 for (size_t i = 0; i < count; ++i) { |
770 // Read the ast node id, function, and frame height for this output frame. | 795 // Read the ast node id, function, and frame height for this output frame. |
771 int frame_index = static_cast<int>(i); | 796 int frame_index = static_cast<int>(i); |
772 switch (translated_state_.frames()[i].kind()) { | 797 switch (translated_state_.frames()[i].kind()) { |
773 case TranslatedFrame::kFunction: | 798 case TranslatedFrame::kFunction: |
774 DoComputeJSFrame(frame_index, deoptimizing_throw_ && i == count - 1); | 799 DoComputeJSFrame(frame_index, deoptimizing_throw_ && i == count - 1); |
775 jsframe_count_++; | 800 jsframe_count_++; |
776 break; | 801 break; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 PrintF(trace_scope_->file(), "%s", name.get()); | 873 PrintF(trace_scope_->file(), "%s", name.get()); |
849 PrintF(trace_scope_->file(), | 874 PrintF(trace_scope_->file(), |
850 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | 875 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); |
851 PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(), | 876 PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(), |
852 height_in_bytes, goto_catch_handler ? " (throw)" : ""); | 877 height_in_bytes, goto_catch_handler ? " (throw)" : ""); |
853 } | 878 } |
854 | 879 |
855 // The 'fixed' part of the frame consists of the incoming parameters and | 880 // The 'fixed' part of the frame consists of the incoming parameters and |
856 // the part described by JavaScriptFrameConstants. | 881 // the part described by JavaScriptFrameConstants. |
857 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared); | 882 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared); |
858 unsigned input_frame_size = input_->GetFrameSize(); | |
859 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 883 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
860 | 884 |
861 // Allocate and store the output frame description. | 885 // Allocate and store the output frame description. |
862 int parameter_count = shared->internal_formal_parameter_count() + 1; | 886 int parameter_count = shared->internal_formal_parameter_count() + 1; |
863 FrameDescription* output_frame = new (output_frame_size) | 887 FrameDescription* output_frame = new (output_frame_size) |
864 FrameDescription(output_frame_size, parameter_count); | 888 FrameDescription(output_frame_size, parameter_count); |
865 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 889 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
866 | 890 |
867 CHECK(frame_index >= 0 && frame_index < output_count_); | 891 CHECK(frame_index >= 0 && frame_index < output_count_); |
868 CHECK_NULL(output_[frame_index]); | 892 CHECK_NULL(output_[frame_index]); |
869 output_[frame_index] = output_frame; | 893 output_[frame_index] = output_frame; |
870 | 894 |
871 // The top address for the bottommost output frame can be computed from | 895 // The top address for the bottommost output frame can be computed from |
872 // the input frame pointer and the output frame's height. For all | 896 // the input frame pointer and the output frame's height. For all |
873 // subsequent output frames, it can be computed from the previous one's | 897 // subsequent output frames, it can be computed from the previous one's |
874 // top address and the current frame's size. | 898 // top address and the current frame's size. |
875 Register fp_reg = JavaScriptFrame::fp_register(); | 899 Register fp_reg = JavaScriptFrame::fp_register(); |
876 intptr_t top_address; | 900 intptr_t top_address; |
877 if (is_bottommost) { | 901 if (is_bottommost) { |
878 // 2 = context and function in the frame. | 902 top_address = caller_frame_top_ - output_frame_size; |
879 // If the optimized frame had alignment padding, adjust the frame pointer | |
880 // to point to the new position of the old frame pointer after padding | |
881 // is removed. Subtract 2 * kPointerSize for the context and function slots. | |
882 top_address = input_->GetRegister(fp_reg.code()) - | |
883 StandardFrameConstants::kFixedFrameSizeFromFp - | |
884 height_in_bytes; | |
885 } else { | 903 } else { |
886 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 904 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
887 } | 905 } |
888 output_frame->SetTop(top_address); | 906 output_frame->SetTop(top_address); |
889 | 907 |
890 // Compute the incoming parameter translation. | 908 // Compute the incoming parameter translation. |
891 unsigned output_offset = output_frame_size; | 909 unsigned output_offset = output_frame_size; |
892 unsigned input_offset = input_frame_size; | |
893 for (int i = 0; i < parameter_count; ++i) { | 910 for (int i = 0; i < parameter_count; ++i) { |
894 output_offset -= kPointerSize; | 911 output_offset -= kPointerSize; |
895 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 912 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
896 output_offset); | 913 output_offset); |
897 } | 914 } |
898 input_offset -= (parameter_count * kPointerSize); | |
899 | 915 |
900 // There are no translation commands for the caller's pc and fp, the | 916 // There are no translation commands for the caller's pc and fp, the |
901 // context, and the function. Synthesize their values and set them up | 917 // context, and the function. Synthesize their values and set them up |
902 // explicitly. | 918 // explicitly. |
903 // | 919 // |
904 // The caller's pc for the bottommost output frame is the same as in the | 920 // The caller's pc for the bottommost output frame is the same as in the |
905 // input frame. For all subsequent output frames, it can be read from the | 921 // input frame. For all subsequent output frames, it can be read from the |
906 // previous one. This frame's pc can be computed from the non-optimized | 922 // previous one. This frame's pc can be computed from the non-optimized |
907 // function code and AST id of the bailout. | 923 // function code and AST id of the bailout. |
908 output_offset -= kPCOnStackSize; | 924 output_offset -= kPCOnStackSize; |
909 input_offset -= kPCOnStackSize; | |
910 intptr_t value; | 925 intptr_t value; |
911 if (is_bottommost) { | 926 if (is_bottommost) { |
912 value = input_->GetFrameSlot(input_offset); | 927 value = caller_pc_; |
913 } else { | 928 } else { |
914 value = output_[frame_index - 1]->GetPc(); | 929 value = output_[frame_index - 1]->GetPc(); |
915 } | 930 } |
916 output_frame->SetCallerPc(output_offset, value); | 931 output_frame->SetCallerPc(output_offset, value); |
917 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); | 932 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); |
918 | 933 |
919 // The caller's frame pointer for the bottommost output frame is the same | 934 // The caller's frame pointer for the bottommost output frame is the same |
920 // as in the input frame. For all subsequent output frames, it can be | 935 // as in the input frame. For all subsequent output frames, it can be |
921 // read from the previous one. Also compute and set this frame's frame | 936 // read from the previous one. Also compute and set this frame's frame |
922 // pointer. | 937 // pointer. |
923 output_offset -= kFPOnStackSize; | 938 output_offset -= kFPOnStackSize; |
924 input_offset -= kFPOnStackSize; | |
925 if (is_bottommost) { | 939 if (is_bottommost) { |
926 value = input_->GetFrameSlot(input_offset); | 940 value = caller_fp_; |
927 } else { | 941 } else { |
928 value = output_[frame_index - 1]->GetFp(); | 942 value = output_[frame_index - 1]->GetFp(); |
929 } | 943 } |
930 output_frame->SetCallerFp(output_offset, value); | 944 output_frame->SetCallerFp(output_offset, value); |
931 intptr_t fp_value = top_address + output_offset; | 945 intptr_t fp_value = top_address + output_offset; |
932 DCHECK(!is_bottommost || input_->GetRegister(fp_reg.code()) == fp_value); | 946 DCHECK(!is_bottommost || stack_fp_ == fp_value); |
933 output_frame->SetFp(fp_value); | 947 output_frame->SetFp(fp_value); |
934 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 948 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); |
935 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 949 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
936 | 950 |
937 if (FLAG_enable_embedded_constant_pool) { | 951 if (FLAG_enable_embedded_constant_pool) { |
938 // For the bottommost output frame the constant pool pointer can be gotten | 952 // For the bottommost output frame the constant pool pointer can be gotten |
939 // from the input frame. For subsequent output frames, it can be read from | 953 // from the input frame. For subsequent output frames, it can be read from |
940 // the previous frame. | 954 // the previous frame. |
941 output_offset -= kPointerSize; | 955 output_offset -= kPointerSize; |
942 input_offset -= kPointerSize; | |
943 if (is_bottommost) { | 956 if (is_bottommost) { |
944 value = input_->GetFrameSlot(input_offset); | 957 value = caller_constant_pool_; |
945 } else { | 958 } else { |
946 value = output_[frame_index - 1]->GetConstantPool(); | 959 value = output_[frame_index - 1]->GetConstantPool(); |
947 } | 960 } |
948 output_frame->SetCallerConstantPool(output_offset, value); | 961 output_frame->SetCallerConstantPool(output_offset, value); |
949 DebugPrintOutputSlot(value, frame_index, output_offset, | 962 DebugPrintOutputSlot(value, frame_index, output_offset, |
950 "caller's constant_pool\n"); | 963 "caller's constant_pool\n"); |
951 } | 964 } |
952 | 965 |
953 // For the bottommost output frame the context can be gotten from the input | 966 // For the bottommost output frame the context can be gotten from the input |
954 // frame. For all subsequent output frames it can be gotten from the function | 967 // frame. For all subsequent output frames it can be gotten from the function |
955 // so long as we don't inline functions that need local contexts. | 968 // so long as we don't inline functions that need local contexts. |
956 Register context_reg = JavaScriptFrame::context_register(); | 969 Register context_reg = JavaScriptFrame::context_register(); |
957 output_offset -= kPointerSize; | 970 output_offset -= kPointerSize; |
958 input_offset -= kPointerSize; | |
959 | 971 |
960 TranslatedFrame::iterator context_pos = value_iterator; | 972 TranslatedFrame::iterator context_pos = value_iterator; |
961 int context_input_index = input_index; | 973 int context_input_index = input_index; |
962 // When deoptimizing into a catch block, we need to take the context | 974 // When deoptimizing into a catch block, we need to take the context |
963 // from just above the top of the operand stack (we push the context | 975 // from just above the top of the operand stack (we push the context |
964 // at the entry of the try block). | 976 // at the entry of the try block). |
965 if (goto_catch_handler) { | 977 if (goto_catch_handler) { |
966 for (unsigned i = 0; i < height + 1; ++i) { | 978 for (unsigned i = 0; i < height + 1; ++i) { |
967 context_pos++; | 979 context_pos++; |
968 context_input_index++; | 980 context_input_index++; |
969 } | 981 } |
970 } | 982 } |
971 // Read the context from the translations. | 983 // Read the context from the translations. |
972 Object* context = context_pos->GetRawValue(); | 984 Object* context = context_pos->GetRawValue(); |
973 if (context == isolate_->heap()->undefined_value()) { | 985 if (context == isolate_->heap()->undefined_value()) { |
974 // If the context was optimized away, just use the context from | 986 // If the context was optimized away, just use the context from |
975 // the activation. This should only apply to Crankshaft code. | 987 // the activation. This should only apply to Crankshaft code. |
976 CHECK(!compiled_code_->is_turbofanned()); | 988 CHECK(!compiled_code_->is_turbofanned()); |
977 context = | 989 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_) |
978 is_bottommost | 990 : function->context(); |
979 ? reinterpret_cast<Object*>(input_->GetFrameSlot(input_offset)) | |
980 : function->context(); | |
981 } | 991 } |
982 value = reinterpret_cast<intptr_t>(context); | 992 value = reinterpret_cast<intptr_t>(context); |
983 output_frame->SetContext(value); | 993 output_frame->SetContext(value); |
984 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); | 994 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); |
985 WriteValueToOutput(context, context_input_index, frame_index, output_offset, | 995 WriteValueToOutput(context, context_input_index, frame_index, output_offset, |
986 "context "); | 996 "context "); |
987 if (context == isolate_->heap()->arguments_marker()) { | 997 if (context == isolate_->heap()->arguments_marker()) { |
988 Address output_address = | 998 Address output_address = |
989 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + | 999 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + |
990 output_offset; | 1000 output_offset; |
991 values_to_materialize_.push_back({output_address, context_pos}); | 1001 values_to_materialize_.push_back({output_address, context_pos}); |
992 } | 1002 } |
993 value_iterator++; | 1003 value_iterator++; |
994 input_index++; | 1004 input_index++; |
995 | 1005 |
996 // The function was mentioned explicitly in the BEGIN_FRAME. | 1006 // The function was mentioned explicitly in the BEGIN_FRAME. |
997 output_offset -= kPointerSize; | 1007 output_offset -= kPointerSize; |
998 input_offset -= kPointerSize; | |
999 value = reinterpret_cast<intptr_t>(function); | 1008 value = reinterpret_cast<intptr_t>(function); |
1000 // The function for the bottommost output frame should also agree with the | 1009 // The function for the bottommost output frame should also agree with the |
1001 // input frame. | 1010 // input frame. |
1002 DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value); | 1011 DCHECK(!is_bottommost || reinterpret_cast<intptr_t>(function_) == value); |
1003 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); | 1012 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); |
1004 | 1013 |
1005 // Translate the rest of the frame. | 1014 // Translate the rest of the frame. |
1006 for (unsigned i = 0; i < height; ++i) { | 1015 for (unsigned i = 0; i < height; ++i) { |
1007 output_offset -= kPointerSize; | 1016 output_offset -= kPointerSize; |
1008 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1017 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1009 output_offset); | 1018 output_offset); |
1010 } | 1019 } |
1011 if (goto_catch_handler) { | 1020 if (goto_catch_handler) { |
1012 // Write out the exception for the catch handler. | 1021 // Write out the exception for the catch handler. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 bytecode_offset, height_in_bytes, | 1098 bytecode_offset, height_in_bytes, |
1090 goto_catch_handler ? " (throw)" : ""); | 1099 goto_catch_handler ? " (throw)" : ""); |
1091 } | 1100 } |
1092 if (goto_catch_handler) { | 1101 if (goto_catch_handler) { |
1093 bytecode_offset = catch_handler_pc_offset_; | 1102 bytecode_offset = catch_handler_pc_offset_; |
1094 } | 1103 } |
1095 | 1104 |
1096 // The 'fixed' part of the frame consists of the incoming parameters and | 1105 // The 'fixed' part of the frame consists of the incoming parameters and |
1097 // the part described by InterpreterFrameConstants. | 1106 // the part described by InterpreterFrameConstants. |
1098 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); | 1107 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); |
1099 unsigned input_frame_size = input_->GetFrameSize(); | |
1100 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1108 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1101 | 1109 |
1102 // Allocate and store the output frame description. | 1110 // Allocate and store the output frame description. |
1103 int parameter_count = shared->internal_formal_parameter_count() + 1; | 1111 int parameter_count = shared->internal_formal_parameter_count() + 1; |
1104 FrameDescription* output_frame = new (output_frame_size) | 1112 FrameDescription* output_frame = new (output_frame_size) |
1105 FrameDescription(output_frame_size, parameter_count); | 1113 FrameDescription(output_frame_size, parameter_count); |
1106 output_frame->SetFrameType(StackFrame::INTERPRETED); | 1114 output_frame->SetFrameType(StackFrame::INTERPRETED); |
1107 | 1115 |
1108 bool is_bottommost = (0 == frame_index); | 1116 bool is_bottommost = (0 == frame_index); |
1109 bool is_topmost = (output_count_ - 1 == frame_index); | 1117 bool is_topmost = (output_count_ - 1 == frame_index); |
1110 CHECK(frame_index >= 0 && frame_index < output_count_); | 1118 CHECK(frame_index >= 0 && frame_index < output_count_); |
1111 CHECK_NULL(output_[frame_index]); | 1119 CHECK_NULL(output_[frame_index]); |
1112 output_[frame_index] = output_frame; | 1120 output_[frame_index] = output_frame; |
1113 | 1121 |
1114 // The top address for the bottommost output frame can be computed from | 1122 // The top address for the bottommost output frame can be computed from |
1115 // the input frame pointer and the output frame's height. For all | 1123 // the input frame pointer and the output frame's height. For all |
1116 // subsequent output frames, it can be computed from the previous one's | 1124 // subsequent output frames, it can be computed from the previous one's |
1117 // top address and the current frame's size. | 1125 // top address and the current frame's size. |
1118 Register fp_reg = InterpretedFrame::fp_register(); | 1126 Register fp_reg = InterpretedFrame::fp_register(); |
1119 intptr_t top_address; | 1127 intptr_t top_address; |
1120 if (is_bottommost) { | 1128 if (is_bottommost) { |
1121 // Subtract interpreter fixed frame size for the context function slots, | 1129 top_address = caller_frame_top_ - output_frame_size; |
1122 // new,target and bytecode offset. | |
1123 top_address = input_->GetRegister(fp_reg.code()) - | |
1124 InterpreterFrameConstants::kFixedFrameSizeFromFp - | |
1125 height_in_bytes; | |
1126 } else { | 1130 } else { |
1127 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1131 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
1128 } | 1132 } |
1129 output_frame->SetTop(top_address); | 1133 output_frame->SetTop(top_address); |
1130 | 1134 |
1131 // Compute the incoming parameter translation. | 1135 // Compute the incoming parameter translation. |
1132 unsigned output_offset = output_frame_size; | 1136 unsigned output_offset = output_frame_size; |
1133 unsigned input_offset = input_frame_size; | |
1134 for (int i = 0; i < parameter_count; ++i) { | 1137 for (int i = 0; i < parameter_count; ++i) { |
1135 output_offset -= kPointerSize; | 1138 output_offset -= kPointerSize; |
1136 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1139 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1137 output_offset); | 1140 output_offset); |
1138 } | 1141 } |
1139 input_offset -= (parameter_count * kPointerSize); | |
1140 | 1142 |
1141 // There are no translation commands for the caller's pc and fp, the | 1143 // There are no translation commands for the caller's pc and fp, the |
1142 // context, the function, new.target and the bytecode offset. Synthesize | 1144 // context, the function, new.target and the bytecode offset. Synthesize |
1143 // their values and set them up | 1145 // their values and set them up |
1144 // explicitly. | 1146 // explicitly. |
1145 // | 1147 // |
1146 // The caller's pc for the bottommost output frame is the same as in the | 1148 // The caller's pc for the bottommost output frame is the same as in the |
1147 // input frame. For all subsequent output frames, it can be read from the | 1149 // input frame. For all subsequent output frames, it can be read from the |
1148 // previous one. This frame's pc can be computed from the non-optimized | 1150 // previous one. This frame's pc can be computed from the non-optimized |
1149 // function code and AST id of the bailout. | 1151 // function code and AST id of the bailout. |
1150 output_offset -= kPCOnStackSize; | 1152 output_offset -= kPCOnStackSize; |
1151 input_offset -= kPCOnStackSize; | |
1152 intptr_t value; | 1153 intptr_t value; |
1153 if (is_bottommost) { | 1154 if (is_bottommost) { |
1154 value = input_->GetFrameSlot(input_offset); | 1155 value = caller_pc_; |
1155 } else { | 1156 } else { |
1156 value = output_[frame_index - 1]->GetPc(); | 1157 value = output_[frame_index - 1]->GetPc(); |
1157 } | 1158 } |
1158 output_frame->SetCallerPc(output_offset, value); | 1159 output_frame->SetCallerPc(output_offset, value); |
1159 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); | 1160 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's pc\n"); |
1160 | 1161 |
1161 // The caller's frame pointer for the bottommost output frame is the same | 1162 // The caller's frame pointer for the bottommost output frame is the same |
1162 // as in the input frame. For all subsequent output frames, it can be | 1163 // as in the input frame. For all subsequent output frames, it can be |
1163 // read from the previous one. Also compute and set this frame's frame | 1164 // read from the previous one. Also compute and set this frame's frame |
1164 // pointer. | 1165 // pointer. |
1165 output_offset -= kFPOnStackSize; | 1166 output_offset -= kFPOnStackSize; |
1166 input_offset -= kFPOnStackSize; | |
1167 if (is_bottommost) { | 1167 if (is_bottommost) { |
1168 value = input_->GetFrameSlot(input_offset); | 1168 value = caller_fp_; |
1169 } else { | 1169 } else { |
1170 value = output_[frame_index - 1]->GetFp(); | 1170 value = output_[frame_index - 1]->GetFp(); |
1171 } | 1171 } |
1172 output_frame->SetCallerFp(output_offset, value); | 1172 output_frame->SetCallerFp(output_offset, value); |
1173 intptr_t fp_value = top_address + output_offset; | 1173 intptr_t fp_value = top_address + output_offset; |
1174 DCHECK(!is_bottommost || input_->GetRegister(fp_reg.code()) == fp_value); | 1174 DCHECK(!is_bottommost || stack_fp_ == fp_value); |
1175 output_frame->SetFp(fp_value); | 1175 output_frame->SetFp(fp_value); |
1176 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 1176 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); |
1177 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 1177 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
1178 | 1178 |
1179 if (FLAG_enable_embedded_constant_pool) { | 1179 if (FLAG_enable_embedded_constant_pool) { |
1180 // For the bottommost output frame the constant pool pointer can be gotten | 1180 // For the bottommost output frame the constant pool pointer can be gotten |
1181 // from the input frame. For subsequent output frames, it can be read from | 1181 // from the input frame. For subsequent output frames, it can be read from |
1182 // the previous frame. | 1182 // the previous frame. |
1183 output_offset -= kPointerSize; | 1183 output_offset -= kPointerSize; |
1184 input_offset -= kPointerSize; | |
1185 if (is_bottommost) { | 1184 if (is_bottommost) { |
1186 value = input_->GetFrameSlot(input_offset); | 1185 value = caller_constant_pool_; |
1187 } else { | 1186 } else { |
1188 value = output_[frame_index - 1]->GetConstantPool(); | 1187 value = output_[frame_index - 1]->GetConstantPool(); |
1189 } | 1188 } |
1190 output_frame->SetCallerConstantPool(output_offset, value); | 1189 output_frame->SetCallerConstantPool(output_offset, value); |
1191 DebugPrintOutputSlot(value, frame_index, output_offset, | 1190 DebugPrintOutputSlot(value, frame_index, output_offset, |
1192 "caller's constant_pool\n"); | 1191 "caller's constant_pool\n"); |
1193 } | 1192 } |
1194 | 1193 |
1195 // For the bottommost output frame the context can be gotten from the input | 1194 // For the bottommost output frame the context can be gotten from the input |
1196 // frame. For all subsequent output frames it can be gotten from the function | 1195 // frame. For all subsequent output frames it can be gotten from the function |
1197 // so long as we don't inline functions that need local contexts. | 1196 // so long as we don't inline functions that need local contexts. |
1198 Register context_reg = InterpretedFrame::context_register(); | 1197 Register context_reg = InterpretedFrame::context_register(); |
1199 output_offset -= kPointerSize; | 1198 output_offset -= kPointerSize; |
1200 input_offset -= kPointerSize; | |
1201 | 1199 |
1202 // When deoptimizing into a catch block, we need to take the context | 1200 // When deoptimizing into a catch block, we need to take the context |
1203 // from a register that was specified in the handler table. | 1201 // from a register that was specified in the handler table. |
1204 TranslatedFrame::iterator context_pos = value_iterator; | 1202 TranslatedFrame::iterator context_pos = value_iterator; |
1205 int context_input_index = input_index; | 1203 int context_input_index = input_index; |
1206 if (goto_catch_handler) { | 1204 if (goto_catch_handler) { |
1207 // Skip to the translated value of the register specified | 1205 // Skip to the translated value of the register specified |
1208 // in the handler table. | 1206 // in the handler table. |
1209 for (int i = 0; i < catch_handler_data_ + 1; ++i) { | 1207 for (int i = 0; i < catch_handler_data_ + 1; ++i) { |
1210 context_pos++; | 1208 context_pos++; |
1211 context_input_index++; | 1209 context_input_index++; |
1212 } | 1210 } |
1213 } | 1211 } |
1214 // Read the context from the translations. | 1212 // Read the context from the translations. |
1215 Object* context = context_pos->GetRawValue(); | 1213 Object* context = context_pos->GetRawValue(); |
1216 // The context should not be a placeholder for a materialized object. | 1214 // The context should not be a placeholder for a materialized object. |
1217 CHECK(context != isolate_->heap()->arguments_marker()); | 1215 CHECK(context != isolate_->heap()->arguments_marker()); |
1218 value = reinterpret_cast<intptr_t>(context); | 1216 value = reinterpret_cast<intptr_t>(context); |
1219 output_frame->SetContext(value); | 1217 output_frame->SetContext(value); |
1220 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); | 1218 if (is_topmost) output_frame->SetRegister(context_reg.code(), value); |
1221 WriteValueToOutput(context, context_input_index, frame_index, output_offset, | 1219 WriteValueToOutput(context, context_input_index, frame_index, output_offset, |
1222 "context "); | 1220 "context "); |
1223 value_iterator++; | 1221 value_iterator++; |
1224 input_index++; | 1222 input_index++; |
1225 | 1223 |
1226 // The function was mentioned explicitly in the BEGIN_FRAME. | 1224 // The function was mentioned explicitly in the BEGIN_FRAME. |
1227 output_offset -= kPointerSize; | 1225 output_offset -= kPointerSize; |
1228 input_offset -= kPointerSize; | |
1229 value = reinterpret_cast<intptr_t>(function); | 1226 value = reinterpret_cast<intptr_t>(function); |
1230 // The function for the bottommost output frame should also agree with the | 1227 // The function for the bottommost output frame should also agree with the |
1231 // input frame. | 1228 // input frame. |
1232 DCHECK(!is_bottommost || input_->GetFrameSlot(input_offset) == value); | 1229 DCHECK(!is_bottommost || reinterpret_cast<intptr_t>(function_) == value); |
1233 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); | 1230 WriteValueToOutput(function, 0, frame_index, output_offset, "function "); |
1234 | 1231 |
1235 // The new.target slot is only used during function activiation which is | 1232 // The new.target slot is only used during function activiation which is |
1236 // before the first deopt point, so should never be needed. Just set it to | 1233 // before the first deopt point, so should never be needed. Just set it to |
1237 // undefined. | 1234 // undefined. |
1238 output_offset -= kPointerSize; | 1235 output_offset -= kPointerSize; |
1239 input_offset -= kPointerSize; | |
1240 Object* new_target = isolate_->heap()->undefined_value(); | 1236 Object* new_target = isolate_->heap()->undefined_value(); |
1241 WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target "); | 1237 WriteValueToOutput(new_target, 0, frame_index, output_offset, "new_target "); |
1242 | 1238 |
1243 // Set the bytecode array pointer. | 1239 // Set the bytecode array pointer. |
1244 output_offset -= kPointerSize; | 1240 output_offset -= kPointerSize; |
1245 input_offset -= kPointerSize; | |
1246 Object* bytecode_array = shared->bytecode_array(); | 1241 Object* bytecode_array = shared->bytecode_array(); |
1247 WriteValueToOutput(bytecode_array, 0, frame_index, output_offset, | 1242 WriteValueToOutput(bytecode_array, 0, frame_index, output_offset, |
1248 "bytecode array "); | 1243 "bytecode array "); |
1249 | 1244 |
1250 // The bytecode offset was mentioned explicitly in the BEGIN_FRAME. | 1245 // The bytecode offset was mentioned explicitly in the BEGIN_FRAME. |
1251 output_offset -= kPointerSize; | 1246 output_offset -= kPointerSize; |
1252 input_offset -= kPointerSize; | |
1253 int raw_bytecode_offset = | 1247 int raw_bytecode_offset = |
1254 BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset; | 1248 BytecodeArray::kHeaderSize - kHeapObjectTag + bytecode_offset; |
1255 Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset); | 1249 Smi* smi_bytecode_offset = Smi::FromInt(raw_bytecode_offset); |
1256 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, | 1250 WriteValueToOutput(smi_bytecode_offset, 0, frame_index, output_offset, |
1257 "bytecode offset "); | 1251 "bytecode offset "); |
1258 | 1252 |
1259 // Translate the rest of the interpreter registers in the frame. | 1253 // Translate the rest of the interpreter registers in the frame. |
1260 for (unsigned i = 0; i < height - 1; ++i) { | 1254 for (unsigned i = 0; i < height - 1; ++i) { |
1261 output_offset -= kPointerSize; | 1255 output_offset -= kPointerSize; |
1262 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1256 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1729 int param_count = descriptor.GetRegisterParameterCount(); | 1723 int param_count = descriptor.GetRegisterParameterCount(); |
1730 int stack_param_count = descriptor.GetStackParameterCount(); | 1724 int stack_param_count = descriptor.GetStackParameterCount(); |
1731 // The translated frame contains all of the register parameters | 1725 // The translated frame contains all of the register parameters |
1732 // plus the context. | 1726 // plus the context. |
1733 CHECK_EQ(translated_frame->height(), param_count + 1); | 1727 CHECK_EQ(translated_frame->height(), param_count + 1); |
1734 CHECK_GE(param_count, 0); | 1728 CHECK_GE(param_count, 0); |
1735 | 1729 |
1736 int height_in_bytes = kPointerSize * (param_count + stack_param_count) + | 1730 int height_in_bytes = kPointerSize * (param_count + stack_param_count) + |
1737 sizeof(Arguments) + kPointerSize; | 1731 sizeof(Arguments) + kPointerSize; |
1738 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; | 1732 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; |
1739 int input_frame_size = input_->GetFrameSize(); | |
1740 int output_frame_size = height_in_bytes + fixed_frame_size; | 1733 int output_frame_size = height_in_bytes + fixed_frame_size; |
1741 if (trace_scope_ != NULL) { | 1734 if (trace_scope_ != NULL) { |
1742 PrintF(trace_scope_->file(), | 1735 PrintF(trace_scope_->file(), |
1743 " translating %s => StubFailureTrampolineStub, height=%d\n", | 1736 " translating %s => StubFailureTrampolineStub, height=%d\n", |
1744 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)), | 1737 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)), |
1745 height_in_bytes); | 1738 height_in_bytes); |
1746 } | 1739 } |
1747 | 1740 |
1748 // The stub failure trampoline is a single frame. | 1741 // The stub failure trampoline is a single frame. |
1749 FrameDescription* output_frame = | 1742 FrameDescription* output_frame = |
1750 new (output_frame_size) FrameDescription(output_frame_size); | 1743 new (output_frame_size) FrameDescription(output_frame_size); |
1751 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); | 1744 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); |
1752 CHECK_EQ(frame_index, 0); | 1745 CHECK_EQ(frame_index, 0); |
1753 output_[frame_index] = output_frame; | 1746 output_[frame_index] = output_frame; |
1754 | 1747 |
1755 // The top address for the output frame can be computed from the input | 1748 // The top address for the output frame can be computed from the input |
1756 // frame pointer and the output frame's height. Subtract space for the | 1749 // frame pointer and the output frame's height. Subtract space for the |
1757 // context and function slots. | 1750 // context and function slots. |
1758 Register fp_reg = StubFailureTrampolineFrame::fp_register(); | 1751 Register fp_reg = StubFailureTrampolineFrame::fp_register(); |
1759 intptr_t top_address = input_->GetRegister(fp_reg.code()) - | 1752 intptr_t top_address = stack_fp_ - // input_->GetRegister(fp_reg.code()) - |
1760 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes; | 1753 StandardFrameConstants::kFixedFrameSizeFromFp - |
| 1754 height_in_bytes; |
1761 output_frame->SetTop(top_address); | 1755 output_frame->SetTop(top_address); |
1762 | 1756 |
1763 // Read caller's PC (JSFunction continuation) from the input frame. | 1757 // Set caller's PC (JSFunction continuation). |
1764 unsigned input_frame_offset = input_frame_size - kPCOnStackSize; | |
1765 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; | 1758 unsigned output_frame_offset = output_frame_size - kFPOnStackSize; |
1766 intptr_t value = input_->GetFrameSlot(input_frame_offset); | 1759 intptr_t value = caller_pc_; |
1767 output_frame->SetCallerPc(output_frame_offset, value); | 1760 output_frame->SetCallerPc(output_frame_offset, value); |
1768 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1761 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
1769 "caller's pc\n"); | 1762 "caller's pc\n"); |
1770 | 1763 |
1771 // Read caller's FP from the input frame, and set this frame's FP. | 1764 // Set caller's FP from the input frame, and set this frame's FP. |
1772 input_frame_offset -= kFPOnStackSize; | 1765 value = caller_fp_; |
1773 value = input_->GetFrameSlot(input_frame_offset); | |
1774 output_frame_offset -= kFPOnStackSize; | 1766 output_frame_offset -= kFPOnStackSize; |
1775 output_frame->SetCallerFp(output_frame_offset, value); | 1767 output_frame->SetCallerFp(output_frame_offset, value); |
1776 intptr_t frame_ptr = input_->GetRegister(fp_reg.code()); | 1768 intptr_t frame_ptr = stack_fp_; |
1777 output_frame->SetRegister(fp_reg.code(), frame_ptr); | 1769 output_frame->SetRegister(fp_reg.code(), frame_ptr); |
1778 output_frame->SetFp(frame_ptr); | 1770 output_frame->SetFp(frame_ptr); |
1779 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1771 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
1780 "caller's fp\n"); | 1772 "caller's fp\n"); |
1781 | 1773 |
1782 if (FLAG_enable_embedded_constant_pool) { | 1774 if (FLAG_enable_embedded_constant_pool) { |
1783 // Read the caller's constant pool from the input frame. | 1775 // Read the caller's constant pool from the input frame. |
1784 input_frame_offset -= kPointerSize; | 1776 value = caller_constant_pool_; |
1785 value = input_->GetFrameSlot(input_frame_offset); | |
1786 output_frame_offset -= kPointerSize; | 1777 output_frame_offset -= kPointerSize; |
1787 output_frame->SetCallerConstantPool(output_frame_offset, value); | 1778 output_frame->SetCallerConstantPool(output_frame_offset, value); |
1788 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1779 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
1789 "caller's constant_pool\n"); | 1780 "caller's constant_pool\n"); |
1790 } | 1781 } |
1791 | 1782 |
1792 // Remember where the context will need to be written back from the deopt | 1783 // Remember where the context will need to be written back from the deopt |
1793 // translation. | 1784 // translation. |
1794 output_frame_offset -= kPointerSize; | 1785 output_frame_offset -= kPointerSize; |
1795 unsigned context_frame_offset = output_frame_offset; | 1786 unsigned context_frame_offset = output_frame_offset; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1924 | 1915 |
1925 | 1916 |
1926 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { | 1917 void Deoptimizer::MaterializeHeapObjects(JavaScriptFrameIterator* it) { |
1927 DCHECK_NE(DEBUGGER, bailout_type_); | 1918 DCHECK_NE(DEBUGGER, bailout_type_); |
1928 | 1919 |
1929 // Walk to the last JavaScript output frame to find out if it has | 1920 // Walk to the last JavaScript output frame to find out if it has |
1930 // adapted arguments. | 1921 // adapted arguments. |
1931 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { | 1922 for (int frame_index = 0; frame_index < jsframe_count(); ++frame_index) { |
1932 if (frame_index != 0) it->Advance(); | 1923 if (frame_index != 0) it->Advance(); |
1933 } | 1924 } |
1934 translated_state_.Prepare(it->frame()->has_adapted_arguments(), stack_fp_); | 1925 translated_state_.Prepare(it->frame()->has_adapted_arguments(), |
| 1926 reinterpret_cast<Address>(stack_fp_)); |
1935 | 1927 |
1936 for (auto& materialization : values_to_materialize_) { | 1928 for (auto& materialization : values_to_materialize_) { |
1937 Handle<Object> value = materialization.value_->GetValue(); | 1929 Handle<Object> value = materialization.value_->GetValue(); |
1938 | 1930 |
1939 if (trace_scope_ != nullptr) { | 1931 if (trace_scope_ != nullptr) { |
1940 PrintF("Materialization [0x%08" V8PRIxPTR "] <- 0x%08" V8PRIxPTR " ; ", | 1932 PrintF("Materialization [0x%08" V8PRIxPTR "] <- 0x%08" V8PRIxPTR " ; ", |
1941 reinterpret_cast<intptr_t>(materialization.output_slot_address_), | 1933 reinterpret_cast<intptr_t>(materialization.output_slot_address_), |
1942 reinterpret_cast<intptr_t>(*value)); | 1934 reinterpret_cast<intptr_t>(*value)); |
1943 value->ShortPrint(trace_scope_->file()); | 1935 value->ShortPrint(trace_scope_->file()); |
1944 PrintF(trace_scope_->file(), "\n"); | 1936 PrintF(trace_scope_->file(), "\n"); |
1945 } | 1937 } |
1946 | 1938 |
1947 *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) = | 1939 *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) = |
1948 reinterpret_cast<intptr_t>(*value); | 1940 reinterpret_cast<intptr_t>(*value); |
1949 } | 1941 } |
1950 | 1942 |
1951 isolate_->materialized_object_store()->Remove(stack_fp_); | 1943 isolate_->materialized_object_store()->Remove( |
| 1944 reinterpret_cast<Address>(stack_fp_)); |
1952 } | 1945 } |
1953 | 1946 |
1954 | 1947 |
1955 void Deoptimizer::WriteTranslatedValueToOutput( | 1948 void Deoptimizer::WriteTranslatedValueToOutput( |
1956 TranslatedFrame::iterator* iterator, int* input_index, int frame_index, | 1949 TranslatedFrame::iterator* iterator, int* input_index, int frame_index, |
1957 unsigned output_offset, const char* debug_hint_string, | 1950 unsigned output_offset, const char* debug_hint_string, |
1958 Address output_address_for_materialization) { | 1951 Address output_address_for_materialization) { |
1959 Object* value = (*iterator)->GetRawValue(); | 1952 Object* value = (*iterator)->GetRawValue(); |
1960 | 1953 |
1961 WriteValueToOutput(value, *input_index, frame_index, output_offset, | 1954 WriteValueToOutput(value, *input_index, frame_index, output_offset, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1999 Address output_address = | 1992 Address output_address = |
2000 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + | 1993 reinterpret_cast<Address>(output_[frame_index]->GetTop()) + |
2001 output_offset; | 1994 output_offset; |
2002 PrintF(trace_scope_->file(), | 1995 PrintF(trace_scope_->file(), |
2003 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", | 1996 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s", |
2004 reinterpret_cast<intptr_t>(output_address), output_offset, value, | 1997 reinterpret_cast<intptr_t>(output_address), output_offset, value, |
2005 debug_hint_string == nullptr ? "" : debug_hint_string); | 1998 debug_hint_string == nullptr ? "" : debug_hint_string); |
2006 } | 1999 } |
2007 } | 2000 } |
2008 | 2001 |
2009 | 2002 unsigned Deoptimizer::ComputeInputFrameAboveFpFixedSize() const { |
2010 unsigned Deoptimizer::ComputeInputFrameSize() const { | 2003 unsigned fixed_size = StandardFrameConstants::kFixedFrameSizeAboveFp; |
2011 unsigned fixed_size = StandardFrameConstants::kFixedFrameSize; | |
2012 if (!function_->IsSmi()) { | 2004 if (!function_->IsSmi()) { |
2013 fixed_size += ComputeIncomingArgumentSize(function_->shared()); | 2005 fixed_size += ComputeIncomingArgumentSize(function_->shared()); |
2014 } else { | 2006 } else { |
2015 CHECK_EQ(Smi::cast(function_), Smi::FromInt(StackFrame::STUB)); | 2007 CHECK_EQ(Smi::cast(function_), Smi::FromInt(StackFrame::STUB)); |
2016 } | 2008 } |
| 2009 return fixed_size; |
| 2010 } |
| 2011 |
| 2012 unsigned Deoptimizer::ComputeInputFrameSize() const { |
2017 // The fp-to-sp delta already takes the context, constant pool pointer and the | 2013 // The fp-to-sp delta already takes the context, constant pool pointer and the |
2018 // function into account so we have to avoid double counting them. | 2014 // function into account so we have to avoid double counting them. |
2019 unsigned result = fixed_size + fp_to_sp_delta_ - | 2015 unsigned fixed_size_from_fp = ComputeInputFrameAboveFpFixedSize(); |
2020 StandardFrameConstants::kFixedFrameSizeFromFp; | 2016 unsigned result = fixed_size_from_fp + fp_to_sp_delta_; |
2021 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 2017 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
2022 unsigned stack_slots = compiled_code_->stack_slots(); | 2018 unsigned stack_slots = compiled_code_->stack_slots(); |
2023 unsigned outgoing_size = | 2019 unsigned outgoing_size = |
2024 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); | 2020 ComputeOutgoingArgumentSize(compiled_code_, bailout_id_); |
2025 CHECK(result == | 2021 CHECK(result == |
2026 fixed_size + (stack_slots * kPointerSize) - | 2022 fixed_size_from_fp + (stack_slots * kPointerSize) - |
2027 StandardFrameConstants::kFixedFrameSize + outgoing_size); | 2023 StandardFrameConstants::kFixedFrameSizeAboveFp + outgoing_size); |
2028 } | 2024 } |
2029 return result; | 2025 return result; |
2030 } | 2026 } |
2031 | 2027 |
2032 // static | 2028 // static |
2033 unsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) { | 2029 unsigned Deoptimizer::ComputeJavascriptFixedSize(SharedFunctionInfo* shared) { |
2034 // The fixed part of the frame consists of the return address, frame | 2030 // The fixed part of the frame consists of the return address, frame |
2035 // pointer, function, context, and all the incoming arguments. | 2031 // pointer, function, context, and all the incoming arguments. |
2036 return ComputeIncomingArgumentSize(shared) + | 2032 return ComputeIncomingArgumentSize(shared) + |
2037 StandardFrameConstants::kFixedFrameSize; | 2033 StandardFrameConstants::kFixedFrameSize; |
(...skipping 1700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3738 CHECK(value_info->IsMaterializedObject()); | 3734 CHECK(value_info->IsMaterializedObject()); |
3739 | 3735 |
3740 value_info->value_ = | 3736 value_info->value_ = |
3741 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3737 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3742 } | 3738 } |
3743 } | 3739 } |
3744 } | 3740 } |
3745 | 3741 |
3746 } // namespace internal | 3742 } // namespace internal |
3747 } // namespace v8 | 3743 } // namespace v8 |
OLD | NEW |