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