| 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 | 467 |
| 468 Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function, | 468 Deoptimizer::Deoptimizer(Isolate* isolate, JSFunction* function, |
| 469 BailoutType type, unsigned bailout_id, Address from, | 469 BailoutType type, unsigned bailout_id, Address from, |
| 470 int fp_to_sp_delta, Code* optimized_code) | 470 int fp_to_sp_delta, Code* optimized_code) |
| 471 : isolate_(isolate), | 471 : isolate_(isolate), |
| 472 function_(function), | 472 function_(function), |
| 473 bailout_id_(bailout_id), | 473 bailout_id_(bailout_id), |
| 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 has_alignment_padding_(0), | |
| 478 deoptimizing_throw_(false), | 477 deoptimizing_throw_(false), |
| 479 catch_handler_data_(-1), | 478 catch_handler_data_(-1), |
| 480 catch_handler_pc_offset_(-1), | 479 catch_handler_pc_offset_(-1), |
| 481 input_(nullptr), | 480 input_(nullptr), |
| 482 output_count_(0), | 481 output_count_(0), |
| 483 jsframe_count_(0), | 482 jsframe_count_(0), |
| 484 output_(nullptr), | 483 output_(nullptr), |
| 485 trace_scope_(nullptr) { | 484 trace_scope_(nullptr) { |
| 486 if (isolate->deoptimizer_lazy_throw()) { | 485 if (isolate->deoptimizer_lazy_throw()) { |
| 487 isolate->set_deoptimizer_lazy_throw(false); | 486 isolate->set_deoptimizer_lazy_throw(false); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 } | 756 } |
| 758 | 757 |
| 759 DCHECK(output_ == NULL); | 758 DCHECK(output_ == NULL); |
| 760 output_ = new FrameDescription*[count]; | 759 output_ = new FrameDescription*[count]; |
| 761 for (size_t i = 0; i < count; ++i) { | 760 for (size_t i = 0; i < count; ++i) { |
| 762 output_[i] = NULL; | 761 output_[i] = NULL; |
| 763 } | 762 } |
| 764 output_count_ = static_cast<int>(count); | 763 output_count_ = static_cast<int>(count); |
| 765 | 764 |
| 766 Register fp_reg = JavaScriptFrame::fp_register(); | 765 Register fp_reg = JavaScriptFrame::fp_register(); |
| 767 stack_fp_ = reinterpret_cast<Address>( | 766 stack_fp_ = reinterpret_cast<Address>(input_->GetRegister(fp_reg.code())); |
| 768 input_->GetRegister(fp_reg.code()) + | |
| 769 has_alignment_padding_ * kPointerSize); | |
| 770 | 767 |
| 771 // Translate each output frame. | 768 // Translate each output frame. |
| 772 for (size_t i = 0; i < count; ++i) { | 769 for (size_t i = 0; i < count; ++i) { |
| 773 // Read the ast node id, function, and frame height for this output frame. | 770 // Read the ast node id, function, and frame height for this output frame. |
| 774 int frame_index = static_cast<int>(i); | 771 int frame_index = static_cast<int>(i); |
| 775 switch (translated_state_.frames()[i].kind()) { | 772 switch (translated_state_.frames()[i].kind()) { |
| 776 case TranslatedFrame::kFunction: | 773 case TranslatedFrame::kFunction: |
| 777 DoComputeJSFrame(frame_index, deoptimizing_throw_ && i == count - 1); | 774 DoComputeJSFrame(frame_index, deoptimizing_throw_ && i == count - 1); |
| 778 jsframe_count_++; | 775 jsframe_count_++; |
| 779 break; | 776 break; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 803 } | 800 } |
| 804 } | 801 } |
| 805 | 802 |
| 806 // Print some helpful diagnostic information. | 803 // Print some helpful diagnostic information. |
| 807 if (trace_scope_ != NULL) { | 804 if (trace_scope_ != NULL) { |
| 808 double ms = timer.Elapsed().InMillisecondsF(); | 805 double ms = timer.Elapsed().InMillisecondsF(); |
| 809 int index = output_count_ - 1; // Index of the topmost frame. | 806 int index = output_count_ - 1; // Index of the topmost frame. |
| 810 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", | 807 PrintF(trace_scope_->file(), "[deoptimizing (%s): end ", |
| 811 MessageFor(bailout_type_)); | 808 MessageFor(bailout_type_)); |
| 812 PrintFunctionName(); | 809 PrintFunctionName(); |
| 813 PrintF(trace_scope_->file(), | 810 PrintF( |
| 814 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s," | 811 trace_scope_->file(), |
| 815 " took %0.3f ms]\n", | 812 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n", |
| 816 bailout_id_, | 813 bailout_id_, node_id.ToInt(), output_[index]->GetPc(), |
| 817 node_id.ToInt(), | 814 FullCodeGenerator::State2String(static_cast<FullCodeGenerator::State>( |
| 818 output_[index]->GetPc(), | 815 output_[index]->GetState()->value())), |
| 819 FullCodeGenerator::State2String( | 816 ms); |
| 820 static_cast<FullCodeGenerator::State>( | |
| 821 output_[index]->GetState()->value())), | |
| 822 has_alignment_padding_ ? "with padding" : "no padding", | |
| 823 ms); | |
| 824 } | 817 } |
| 825 } | 818 } |
| 826 | 819 |
| 827 void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) { | 820 void Deoptimizer::DoComputeJSFrame(int frame_index, bool goto_catch_handler) { |
| 828 TranslatedFrame* translated_frame = | 821 TranslatedFrame* translated_frame = |
| 829 &(translated_state_.frames()[frame_index]); | 822 &(translated_state_.frames()[frame_index]); |
| 830 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); | 823 SharedFunctionInfo* shared = translated_frame->raw_shared_info(); |
| 831 | 824 |
| 832 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 825 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
| 833 bool is_bottommost = (0 == frame_index); | 826 bool is_bottommost = (0 == frame_index); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 CHECK_NULL(output_[frame_index]); | 868 CHECK_NULL(output_[frame_index]); |
| 876 output_[frame_index] = output_frame; | 869 output_[frame_index] = output_frame; |
| 877 | 870 |
| 878 // The top address for the bottommost output frame can be computed from | 871 // The top address for the bottommost output frame can be computed from |
| 879 // the input frame pointer and the output frame's height. For all | 872 // the input frame pointer and the output frame's height. For all |
| 880 // subsequent output frames, it can be computed from the previous one's | 873 // subsequent output frames, it can be computed from the previous one's |
| 881 // top address and the current frame's size. | 874 // top address and the current frame's size. |
| 882 Register fp_reg = JavaScriptFrame::fp_register(); | 875 Register fp_reg = JavaScriptFrame::fp_register(); |
| 883 intptr_t top_address; | 876 intptr_t top_address; |
| 884 if (is_bottommost) { | 877 if (is_bottommost) { |
| 885 // Determine whether the input frame contains alignment padding. | |
| 886 has_alignment_padding_ = | |
| 887 (!compiled_code_->is_turbofanned() && HasAlignmentPadding(shared)) ? 1 | |
| 888 : 0; | |
| 889 // 2 = context and function in the frame. | 878 // 2 = context and function in the frame. |
| 890 // If the optimized frame had alignment padding, adjust the frame pointer | 879 // If the optimized frame had alignment padding, adjust the frame pointer |
| 891 // to point to the new position of the old frame pointer after padding | 880 // to point to the new position of the old frame pointer after padding |
| 892 // is removed. Subtract 2 * kPointerSize for the context and function slots. | 881 // is removed. Subtract 2 * kPointerSize for the context and function slots. |
| 893 top_address = input_->GetRegister(fp_reg.code()) - | 882 top_address = input_->GetRegister(fp_reg.code()) - |
| 894 StandardFrameConstants::kFixedFrameSizeFromFp - | 883 StandardFrameConstants::kFixedFrameSizeFromFp - |
| 895 height_in_bytes + has_alignment_padding_ * kPointerSize; | 884 height_in_bytes; |
| 896 } else { | 885 } else { |
| 897 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 886 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
| 898 } | 887 } |
| 899 output_frame->SetTop(top_address); | 888 output_frame->SetTop(top_address); |
| 900 | 889 |
| 901 // Compute the incoming parameter translation. | 890 // Compute the incoming parameter translation. |
| 902 unsigned output_offset = output_frame_size; | 891 unsigned output_offset = output_frame_size; |
| 903 unsigned input_offset = input_frame_size; | 892 unsigned input_offset = input_frame_size; |
| 904 for (int i = 0; i < parameter_count; ++i) { | 893 for (int i = 0; i < parameter_count; ++i) { |
| 905 output_offset -= kPointerSize; | 894 output_offset -= kPointerSize; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 933 // pointer. | 922 // pointer. |
| 934 output_offset -= kFPOnStackSize; | 923 output_offset -= kFPOnStackSize; |
| 935 input_offset -= kFPOnStackSize; | 924 input_offset -= kFPOnStackSize; |
| 936 if (is_bottommost) { | 925 if (is_bottommost) { |
| 937 value = input_->GetFrameSlot(input_offset); | 926 value = input_->GetFrameSlot(input_offset); |
| 938 } else { | 927 } else { |
| 939 value = output_[frame_index - 1]->GetFp(); | 928 value = output_[frame_index - 1]->GetFp(); |
| 940 } | 929 } |
| 941 output_frame->SetCallerFp(output_offset, value); | 930 output_frame->SetCallerFp(output_offset, value); |
| 942 intptr_t fp_value = top_address + output_offset; | 931 intptr_t fp_value = top_address + output_offset; |
| 943 DCHECK(!is_bottommost || (input_->GetRegister(fp_reg.code()) + | 932 DCHECK(!is_bottommost || input_->GetRegister(fp_reg.code()) == fp_value); |
| 944 has_alignment_padding_ * kPointerSize) == fp_value); | |
| 945 output_frame->SetFp(fp_value); | 933 output_frame->SetFp(fp_value); |
| 946 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 934 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); |
| 947 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 935 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
| 948 DCHECK(!is_bottommost || !has_alignment_padding_ || | |
| 949 (fp_value & kPointerSize) != 0); | |
| 950 | 936 |
| 951 if (FLAG_enable_embedded_constant_pool) { | 937 if (FLAG_enable_embedded_constant_pool) { |
| 952 // For the bottommost output frame the constant pool pointer can be gotten | 938 // For the bottommost output frame the constant pool pointer can be gotten |
| 953 // from the input frame. For subsequent output frames, it can be read from | 939 // from the input frame. For subsequent output frames, it can be read from |
| 954 // the previous frame. | 940 // the previous frame. |
| 955 output_offset -= kPointerSize; | 941 output_offset -= kPointerSize; |
| 956 input_offset -= kPointerSize; | 942 input_offset -= kPointerSize; |
| 957 if (is_bottommost) { | 943 if (is_bottommost) { |
| 958 value = input_->GetFrameSlot(input_offset); | 944 value = input_->GetFrameSlot(input_offset); |
| 959 } else { | 945 } else { |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 // pointer. | 1164 // pointer. |
| 1179 output_offset -= kFPOnStackSize; | 1165 output_offset -= kFPOnStackSize; |
| 1180 input_offset -= kFPOnStackSize; | 1166 input_offset -= kFPOnStackSize; |
| 1181 if (is_bottommost) { | 1167 if (is_bottommost) { |
| 1182 value = input_->GetFrameSlot(input_offset); | 1168 value = input_->GetFrameSlot(input_offset); |
| 1183 } else { | 1169 } else { |
| 1184 value = output_[frame_index - 1]->GetFp(); | 1170 value = output_[frame_index - 1]->GetFp(); |
| 1185 } | 1171 } |
| 1186 output_frame->SetCallerFp(output_offset, value); | 1172 output_frame->SetCallerFp(output_offset, value); |
| 1187 intptr_t fp_value = top_address + output_offset; | 1173 intptr_t fp_value = top_address + output_offset; |
| 1188 DCHECK(!is_bottommost || | 1174 DCHECK(!is_bottommost || input_->GetRegister(fp_reg.code()) == fp_value); |
| 1189 (input_->GetRegister(fp_reg.code()) + | |
| 1190 has_alignment_padding_ * kPointerSize) == fp_value); | |
| 1191 output_frame->SetFp(fp_value); | 1175 output_frame->SetFp(fp_value); |
| 1192 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); | 1176 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value); |
| 1193 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); | 1177 DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n"); |
| 1194 DCHECK(!is_bottommost || !has_alignment_padding_ || | |
| 1195 (fp_value & kPointerSize) != 0); | |
| 1196 | 1178 |
| 1197 if (FLAG_enable_embedded_constant_pool) { | 1179 if (FLAG_enable_embedded_constant_pool) { |
| 1198 // 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 |
| 1199 // 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 |
| 1200 // the previous frame. | 1182 // the previous frame. |
| 1201 output_offset -= kPointerSize; | 1183 output_offset -= kPointerSize; |
| 1202 input_offset -= kPointerSize; | 1184 input_offset -= kPointerSize; |
| 1203 if (is_bottommost) { | 1185 if (is_bottommost) { |
| 1204 value = input_->GetFrameSlot(input_offset); | 1186 value = input_->GetFrameSlot(input_offset); |
| 1205 } else { | 1187 } else { |
| (...skipping 2550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3756 CHECK(value_info->IsMaterializedObject()); | 3738 CHECK(value_info->IsMaterializedObject()); |
| 3757 | 3739 |
| 3758 value_info->value_ = | 3740 value_info->value_ = |
| 3759 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3741 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
| 3760 } | 3742 } |
| 3761 } | 3743 } |
| 3762 } | 3744 } |
| 3763 | 3745 |
| 3764 } // namespace internal | 3746 } // namespace internal |
| 3765 } // namespace v8 | 3747 } // namespace v8 |
| OLD | NEW |