Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: src/deoptimizer.cc

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

Powered by Google App Engine
This is Rietveld 408576698