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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 | 825 |
826 | 826 |
827 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, | 827 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
828 int frame_index) { | 828 int frame_index) { |
829 TranslatedFrame* translated_frame = | 829 TranslatedFrame* translated_frame = |
830 &(translated_state_.frames()[frame_index]); | 830 &(translated_state_.frames()[frame_index]); |
831 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 831 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
832 int input_index = 0; | 832 int input_index = 0; |
833 | 833 |
834 BailoutId node_id = translated_frame->node_id(); | 834 BailoutId node_id = translated_frame->node_id(); |
835 JSFunction* function = translated_frame->raw_function(); | |
836 unsigned height = | 835 unsigned height = |
837 translated_frame->height() - 1; // Do not count the context. | 836 translated_frame->height() - 1; // Do not count the context. |
838 unsigned height_in_bytes = height * kPointerSize; | 837 unsigned height_in_bytes = height * kPointerSize; |
| 838 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
| 839 value_iterator++; |
839 if (trace_scope_ != NULL) { | 840 if (trace_scope_ != NULL) { |
840 PrintF(trace_scope_->file(), " translating frame "); | 841 PrintF(trace_scope_->file(), " translating frame "); |
841 function->PrintName(trace_scope_->file()); | 842 function->PrintName(trace_scope_->file()); |
842 PrintF(trace_scope_->file(), | 843 PrintF(trace_scope_->file(), |
843 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | 844 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); |
844 } | 845 } |
845 | 846 |
846 // The 'fixed' part of the frame consists of the incoming parameters and | 847 // The 'fixed' part of the frame consists of the incoming parameters and |
847 // the part described by JavaScriptFrameConstants. | 848 // the part described by JavaScriptFrameConstants. |
848 unsigned fixed_frame_size = ComputeFixedSize(function); | 849 unsigned fixed_frame_size = ComputeFixedSize(function); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 } | 1065 } |
1065 | 1066 |
1066 | 1067 |
1067 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, | 1068 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, |
1068 int frame_index) { | 1069 int frame_index) { |
1069 TranslatedFrame* translated_frame = | 1070 TranslatedFrame* translated_frame = |
1070 &(translated_state_.frames()[frame_index]); | 1071 &(translated_state_.frames()[frame_index]); |
1071 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1072 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1072 int input_index = 0; | 1073 int input_index = 0; |
1073 | 1074 |
1074 JSFunction* function = translated_frame->raw_function(); | |
1075 unsigned height = translated_frame->height(); | 1075 unsigned height = translated_frame->height(); |
1076 unsigned height_in_bytes = height * kPointerSize; | 1076 unsigned height_in_bytes = height * kPointerSize; |
| 1077 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
| 1078 value_iterator++; |
1077 if (trace_scope_ != NULL) { | 1079 if (trace_scope_ != NULL) { |
1078 PrintF(trace_scope_->file(), | 1080 PrintF(trace_scope_->file(), |
1079 " translating arguments adaptor => height=%d\n", height_in_bytes); | 1081 " translating arguments adaptor => height=%d\n", height_in_bytes); |
1080 } | 1082 } |
1081 | 1083 |
1082 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; | 1084 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; |
1083 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1085 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1084 | 1086 |
1085 // Allocate and store the output frame description. | 1087 // Allocate and store the output frame description. |
1086 FrameDescription* output_frame = | 1088 FrameDescription* output_frame = |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 | 1198 |
1197 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, | 1199 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, |
1198 int frame_index) { | 1200 int frame_index) { |
1199 TranslatedFrame* translated_frame = | 1201 TranslatedFrame* translated_frame = |
1200 &(translated_state_.frames()[frame_index]); | 1202 &(translated_state_.frames()[frame_index]); |
1201 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1203 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1202 int input_index = 0; | 1204 int input_index = 0; |
1203 | 1205 |
1204 Builtins* builtins = isolate_->builtins(); | 1206 Builtins* builtins = isolate_->builtins(); |
1205 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 1207 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); |
1206 JSFunction* function = translated_frame->raw_function(); | |
1207 unsigned height = translated_frame->height(); | 1208 unsigned height = translated_frame->height(); |
1208 unsigned height_in_bytes = height * kPointerSize; | 1209 unsigned height_in_bytes = height * kPointerSize; |
| 1210 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
| 1211 value_iterator++; |
1209 if (trace_scope_ != NULL) { | 1212 if (trace_scope_ != NULL) { |
1210 PrintF(trace_scope_->file(), | 1213 PrintF(trace_scope_->file(), |
1211 " translating construct stub => height=%d\n", height_in_bytes); | 1214 " translating construct stub => height=%d\n", height_in_bytes); |
1212 } | 1215 } |
1213 | 1216 |
1214 unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize; | 1217 unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize; |
1215 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1218 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1216 | 1219 |
1217 // Allocate and store the output frame description. | 1220 // Allocate and store the output frame description. |
1218 FrameDescription* output_frame = | 1221 FrameDescription* output_frame = |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 | 1367 |
1365 | 1368 |
1366 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, | 1369 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, |
1367 int frame_index, | 1370 int frame_index, |
1368 bool is_setter_stub_frame) { | 1371 bool is_setter_stub_frame) { |
1369 TranslatedFrame* translated_frame = | 1372 TranslatedFrame* translated_frame = |
1370 &(translated_state_.frames()[frame_index]); | 1373 &(translated_state_.frames()[frame_index]); |
1371 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1374 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1372 int input_index = 0; | 1375 int input_index = 0; |
1373 | 1376 |
1374 JSFunction* accessor = translated_frame->raw_function(); | 1377 JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue()); |
| 1378 value_iterator++; |
1375 // The receiver (and the implicit return value, if any) are expected in | 1379 // The receiver (and the implicit return value, if any) are expected in |
1376 // registers by the LoadIC/StoreIC, so they don't belong to the output stack | 1380 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
1377 // frame. This means that we have to use a height of 0. | 1381 // frame. This means that we have to use a height of 0. |
1378 unsigned height = 0; | 1382 unsigned height = 0; |
1379 unsigned height_in_bytes = height * kPointerSize; | 1383 unsigned height_in_bytes = height * kPointerSize; |
1380 const char* kind = is_setter_stub_frame ? "setter" : "getter"; | 1384 const char* kind = is_setter_stub_frame ? "setter" : "getter"; |
1381 if (trace_scope_ != NULL) { | 1385 if (trace_scope_ != NULL) { |
1382 PrintF(trace_scope_->file(), | 1386 PrintF(trace_scope_->file(), |
1383 " translating %s stub => height=%u\n", kind, height_in_bytes); | 1387 " translating %s stub => height=%u\n", kind, height_in_bytes); |
1384 } | 1388 } |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 | 1809 |
1806 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( | 1810 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( |
1807 int frame_index, int parameter_count, int expression_count, | 1811 int frame_index, int parameter_count, int expression_count, |
1808 DeoptimizedFrameInfo* info) { | 1812 DeoptimizedFrameInfo* info) { |
1809 CHECK_EQ(DEBUGGER, bailout_type_); | 1813 CHECK_EQ(DEBUGGER, bailout_type_); |
1810 | 1814 |
1811 translated_state_.Prepare(false, nullptr); | 1815 translated_state_.Prepare(false, nullptr); |
1812 | 1816 |
1813 TranslatedFrame* frame = &(translated_state_.frames()[frame_index]); | 1817 TranslatedFrame* frame = &(translated_state_.frames()[frame_index]); |
1814 CHECK(frame->kind() == TranslatedFrame::kFunction); | 1818 CHECK(frame->kind() == TranslatedFrame::kFunction); |
1815 int frame_arg_count = | 1819 int frame_arg_count = frame->shared_info()->internal_formal_parameter_count(); |
1816 frame->function()->shared()->internal_formal_parameter_count(); | |
1817 | 1820 |
1818 // The height is #expressions + 1 for context. | 1821 // The height is #expressions + 1 for context. |
1819 CHECK_EQ(expression_count + 1, frame->height()); | 1822 CHECK_EQ(expression_count + 1, frame->height()); |
1820 TranslatedFrame* argument_frame = frame; | 1823 TranslatedFrame* argument_frame = frame; |
1821 if (frame_index > 0) { | 1824 if (frame_index > 0) { |
1822 TranslatedFrame* previous_frame = | 1825 TranslatedFrame* previous_frame = |
1823 &(translated_state_.frames()[frame_index - 1]); | 1826 &(translated_state_.frames()[frame_index - 1]); |
1824 if (previous_frame->kind() == TranslatedFrame::kArgumentsAdaptor) { | 1827 if (previous_frame->kind() == TranslatedFrame::kArgumentsAdaptor) { |
1825 argument_frame = previous_frame; | 1828 argument_frame = previous_frame; |
1826 CHECK_EQ(parameter_count, argument_frame->height() - 1); | 1829 CHECK_EQ(parameter_count, argument_frame->height() - 1); |
1827 } else { | 1830 } else { |
1828 CHECK_EQ(frame_arg_count, parameter_count); | 1831 CHECK_EQ(frame_arg_count, parameter_count); |
1829 } | 1832 } |
1830 } else { | 1833 } else { |
1831 CHECK_EQ(frame_arg_count, parameter_count); | 1834 CHECK_EQ(frame_arg_count, parameter_count); |
1832 } | 1835 } |
1833 | 1836 |
1834 TranslatedFrame::iterator arg_iter = argument_frame->begin(); | 1837 TranslatedFrame::iterator arg_iter = argument_frame->begin(); |
| 1838 arg_iter++; // Skip the function. |
1835 arg_iter++; // Skip the receiver. | 1839 arg_iter++; // Skip the receiver. |
1836 for (int i = 0; i < parameter_count; i++, arg_iter++) { | 1840 for (int i = 0; i < parameter_count; i++, arg_iter++) { |
1837 if (!arg_iter->IsMaterializedObject()) { | 1841 if (!arg_iter->IsMaterializedObject()) { |
1838 info->SetParameter(i, *(arg_iter->GetValue())); | 1842 info->SetParameter(i, *(arg_iter->GetValue())); |
1839 } | 1843 } |
1840 } | 1844 } |
1841 | 1845 |
1842 TranslatedFrame::iterator iter = frame->begin(); | 1846 TranslatedFrame::iterator iter = frame->begin(); |
1843 // Skip the arguments, receiver and context. | 1847 // Skip the function, receiver, context and arguments. |
1844 for (int i = 0; i < frame_arg_count + 2; i++, iter++) { | 1848 for (int i = 0; i < frame_arg_count + 3; i++, iter++) { |
1845 } | 1849 } |
1846 | 1850 |
1847 for (int i = 0; i < expression_count; i++, iter++) { | 1851 for (int i = 0; i < expression_count; i++, iter++) { |
1848 if (!iter->IsMaterializedObject()) { | 1852 if (!iter->IsMaterializedObject()) { |
1849 info->SetExpression(i, *(iter->GetValue())); | 1853 info->SetExpression(i, *(iter->GetValue())); |
1850 } | 1854 } |
1851 } | 1855 } |
1852 } | 1856 } |
1853 | 1857 |
1854 | 1858 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 void Translation::StoreArgumentsObject(bool args_known, | 2233 void Translation::StoreArgumentsObject(bool args_known, |
2230 int args_index, | 2234 int args_index, |
2231 int args_length) { | 2235 int args_length) { |
2232 buffer_->Add(ARGUMENTS_OBJECT, zone()); | 2236 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
2233 buffer_->Add(args_known, zone()); | 2237 buffer_->Add(args_known, zone()); |
2234 buffer_->Add(args_index, zone()); | 2238 buffer_->Add(args_index, zone()); |
2235 buffer_->Add(args_length, zone()); | 2239 buffer_->Add(args_length, zone()); |
2236 } | 2240 } |
2237 | 2241 |
2238 | 2242 |
| 2243 void Translation::StoreJSFrameFunction() { |
| 2244 buffer_->Add(JS_FRAME_FUNCTION, zone()); |
| 2245 } |
| 2246 |
| 2247 |
2239 int Translation::NumberOfOperandsFor(Opcode opcode) { | 2248 int Translation::NumberOfOperandsFor(Opcode opcode) { |
2240 switch (opcode) { | 2249 switch (opcode) { |
| 2250 case JS_FRAME_FUNCTION: |
| 2251 return 0; |
2241 case GETTER_STUB_FRAME: | 2252 case GETTER_STUB_FRAME: |
2242 case SETTER_STUB_FRAME: | 2253 case SETTER_STUB_FRAME: |
2243 case DUPLICATED_OBJECT: | 2254 case DUPLICATED_OBJECT: |
2244 case ARGUMENTS_OBJECT: | 2255 case ARGUMENTS_OBJECT: |
2245 case CAPTURED_OBJECT: | 2256 case CAPTURED_OBJECT: |
2246 case REGISTER: | 2257 case REGISTER: |
2247 case INT32_REGISTER: | 2258 case INT32_REGISTER: |
2248 case UINT32_REGISTER: | 2259 case UINT32_REGISTER: |
2249 case BOOL_REGISTER: | 2260 case BOOL_REGISTER: |
2250 case DOUBLE_REGISTER: | 2261 case DOUBLE_REGISTER: |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2734 | 2745 |
2735 void TranslatedValue::Handlify() { | 2746 void TranslatedValue::Handlify() { |
2736 if (kind() == kTagged) { | 2747 if (kind() == kTagged) { |
2737 value_ = Handle<Object>(raw_literal(), isolate()); | 2748 value_ = Handle<Object>(raw_literal(), isolate()); |
2738 raw_literal_ = nullptr; | 2749 raw_literal_ = nullptr; |
2739 } | 2750 } |
2740 } | 2751 } |
2741 | 2752 |
2742 | 2753 |
2743 TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id, | 2754 TranslatedFrame TranslatedFrame::JSFrame(BailoutId node_id, |
2744 JSFunction* function, int height) { | 2755 SharedFunctionInfo* shared_info, |
2745 TranslatedFrame frame(kFunction, function->GetIsolate(), function, height); | 2756 int height) { |
| 2757 TranslatedFrame frame(kFunction, shared_info->GetIsolate(), shared_info, |
| 2758 height); |
2746 frame.node_id_ = node_id; | 2759 frame.node_id_ = node_id; |
2747 return frame; | 2760 return frame; |
2748 } | 2761 } |
2749 | 2762 |
2750 | 2763 |
2751 TranslatedFrame TranslatedFrame::AccessorFrame(Kind kind, | 2764 TranslatedFrame TranslatedFrame::AccessorFrame( |
2752 JSFunction* function) { | 2765 Kind kind, SharedFunctionInfo* shared_info) { |
2753 DCHECK(kind == kSetter || kind == kGetter); | 2766 DCHECK(kind == kSetter || kind == kGetter); |
2754 return TranslatedFrame(kind, function->GetIsolate(), function); | 2767 return TranslatedFrame(kind, shared_info->GetIsolate(), shared_info); |
2755 } | 2768 } |
2756 | 2769 |
2757 | 2770 |
2758 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame(JSFunction* function, | 2771 TranslatedFrame TranslatedFrame::ArgumentsAdaptorFrame( |
2759 int height) { | 2772 SharedFunctionInfo* shared_info, int height) { |
2760 return TranslatedFrame(kArgumentsAdaptor, function->GetIsolate(), function, | 2773 return TranslatedFrame(kArgumentsAdaptor, shared_info->GetIsolate(), |
| 2774 shared_info, height); |
| 2775 } |
| 2776 |
| 2777 |
| 2778 TranslatedFrame TranslatedFrame::ConstructStubFrame( |
| 2779 SharedFunctionInfo* shared_info, int height) { |
| 2780 return TranslatedFrame(kConstructStub, shared_info->GetIsolate(), shared_info, |
2761 height); | 2781 height); |
2762 } | 2782 } |
2763 | 2783 |
2764 | |
2765 TranslatedFrame TranslatedFrame::ConstructStubFrame(JSFunction* function, | |
2766 int height) { | |
2767 return TranslatedFrame(kConstructStub, function->GetIsolate(), function, | |
2768 height); | |
2769 } | |
2770 | |
2771 | 2784 |
2772 int TranslatedFrame::GetValueCount() { | 2785 int TranslatedFrame::GetValueCount() { |
2773 switch (kind()) { | 2786 switch (kind()) { |
2774 case kFunction: { | 2787 case kFunction: { |
2775 int parameter_count = | 2788 int parameter_count = |
2776 (raw_function_ == nullptr | 2789 raw_shared_info_->internal_formal_parameter_count() + 1; |
2777 ? function_->shared()->internal_formal_parameter_count() | 2790 return height_ + parameter_count + 1; |
2778 : raw_function_->shared()->internal_formal_parameter_count()) + | |
2779 1; | |
2780 return height_ + parameter_count; | |
2781 } | 2791 } |
2782 | 2792 |
2783 case kGetter: | 2793 case kGetter: |
2784 return 1; // Receiver. | 2794 return 2; // Function and receiver. |
2785 | 2795 |
2786 case kSetter: | 2796 case kSetter: |
2787 return 2; // Receiver and the value to set. | 2797 return 3; // Function, receiver and the value to set. |
2788 | 2798 |
2789 case kArgumentsAdaptor: | 2799 case kArgumentsAdaptor: |
2790 case kConstructStub: | 2800 case kConstructStub: |
| 2801 return 1 + height_; |
| 2802 |
2791 case kCompiledStub: | 2803 case kCompiledStub: |
2792 return height_; | 2804 return height_; |
2793 | 2805 |
2794 case kInvalid: | 2806 case kInvalid: |
2795 UNREACHABLE(); | 2807 UNREACHABLE(); |
2796 break; | 2808 break; |
2797 } | 2809 } |
2798 UNREACHABLE(); | 2810 UNREACHABLE(); |
2799 return -1; | 2811 return -1; |
2800 } | 2812 } |
2801 | 2813 |
2802 | 2814 |
2803 void TranslatedFrame::Handlify(Isolate* isolate) { | 2815 void TranslatedFrame::Handlify() { |
2804 if (raw_function_ != nullptr) { | 2816 if (raw_shared_info_ != nullptr) { |
2805 function_ = Handle<JSFunction>(raw_function_, isolate); | 2817 shared_info_ = Handle<SharedFunctionInfo>(raw_shared_info_); |
2806 raw_function_ = nullptr; | 2818 raw_shared_info_ = nullptr; |
2807 } | 2819 } |
2808 for (auto& value : values_) { | 2820 for (auto& value : values_) { |
2809 value.Handlify(); | 2821 value.Handlify(); |
2810 } | 2822 } |
2811 } | 2823 } |
2812 | 2824 |
2813 | 2825 |
2814 TranslatedFrame TranslatedState::CreateNextTranslatedFrame( | 2826 TranslatedFrame TranslatedState::CreateNextTranslatedFrame( |
2815 TranslationIterator* iterator, FixedArray* literal_array, Address fp, | 2827 TranslationIterator* iterator, FixedArray* literal_array, Address fp, |
2816 JSFunction* frame_function, FILE* trace_file) { | 2828 JSFunction* frame_function, FILE* trace_file) { |
2817 Translation::Opcode opcode = | 2829 Translation::Opcode opcode = |
2818 static_cast<Translation::Opcode>(iterator->Next()); | 2830 static_cast<Translation::Opcode>(iterator->Next()); |
2819 switch (opcode) { | 2831 switch (opcode) { |
2820 case Translation::JS_FRAME: { | 2832 case Translation::JS_FRAME: { |
2821 BailoutId node_id = BailoutId(iterator->Next()); | 2833 BailoutId node_id = BailoutId(iterator->Next()); |
2822 int closure_id = iterator->Next(); | 2834 SharedFunctionInfo* shared_info = |
2823 JSFunction* function = | 2835 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2824 (closure_id == Translation::kSelfLiteralId) | |
2825 ? frame_function | |
2826 : JSFunction::cast(literal_array->get(closure_id)); | |
2827 int height = iterator->Next(); | 2836 int height = iterator->Next(); |
2828 if (trace_file != nullptr) { | 2837 if (trace_file != nullptr) { |
2829 PrintF(trace_file, " reading input frame "); | 2838 SmartArrayPointer<char> name = shared_info->DebugName()->ToCString(); |
2830 function->PrintName(trace_file); | 2839 PrintF(trace_file, " reading input frame %s", name.get()); |
2831 int arg_count = | 2840 int arg_count = shared_info->internal_formal_parameter_count() + 1; |
2832 function->shared()->internal_formal_parameter_count() + 1; | |
2833 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", | 2841 PrintF(trace_file, " => node=%d, args=%d, height=%d; inputs:\n", |
2834 arg_count, node_id.ToInt(), height); | 2842 arg_count, node_id.ToInt(), height); |
2835 } | 2843 } |
2836 return TranslatedFrame::JSFrame(node_id, function, height); | 2844 return TranslatedFrame::JSFrame(node_id, shared_info, height); |
2837 } | 2845 } |
2838 | 2846 |
2839 case Translation::ARGUMENTS_ADAPTOR_FRAME: { | 2847 case Translation::ARGUMENTS_ADAPTOR_FRAME: { |
2840 JSFunction* function = | 2848 SharedFunctionInfo* shared_info = |
2841 JSFunction::cast(literal_array->get(iterator->Next())); | 2849 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2842 int height = iterator->Next(); | 2850 int height = iterator->Next(); |
2843 if (trace_file != nullptr) { | 2851 if (trace_file != nullptr) { |
2844 PrintF(trace_file, " reading arguments adaptor frame"); | 2852 SmartArrayPointer<char> name = shared_info->DebugName()->ToCString(); |
2845 function->PrintName(trace_file); | 2853 PrintF(trace_file, " reading arguments adaptor frame %s", name.get()); |
2846 PrintF(trace_file, " => height=%d; inputs:\n", height); | 2854 PrintF(trace_file, " => height=%d; inputs:\n", height); |
2847 } | 2855 } |
2848 return TranslatedFrame::ArgumentsAdaptorFrame(function, height); | 2856 return TranslatedFrame::ArgumentsAdaptorFrame(shared_info, height); |
2849 } | 2857 } |
2850 | 2858 |
2851 case Translation::CONSTRUCT_STUB_FRAME: { | 2859 case Translation::CONSTRUCT_STUB_FRAME: { |
2852 JSFunction* function = | 2860 SharedFunctionInfo* shared_info = |
2853 JSFunction::cast(literal_array->get(iterator->Next())); | 2861 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2854 int height = iterator->Next(); | 2862 int height = iterator->Next(); |
2855 if (trace_file != nullptr) { | 2863 if (trace_file != nullptr) { |
2856 PrintF(trace_file, " reading construct stub frame "); | 2864 SmartArrayPointer<char> name = shared_info->DebugName()->ToCString(); |
2857 function->PrintName(trace_file); | 2865 PrintF(trace_file, " reading construct stub frame %s", name.get()); |
2858 PrintF(trace_file, " => height=%d; inputs:\n", height); | 2866 PrintF(trace_file, " => height=%d; inputs:\n", height); |
2859 } | 2867 } |
2860 return TranslatedFrame::ConstructStubFrame(function, height); | 2868 return TranslatedFrame::ConstructStubFrame(shared_info, height); |
2861 } | 2869 } |
2862 | 2870 |
2863 case Translation::GETTER_STUB_FRAME: { | 2871 case Translation::GETTER_STUB_FRAME: { |
2864 JSFunction* function = | 2872 SharedFunctionInfo* shared_info = |
2865 JSFunction::cast(literal_array->get(iterator->Next())); | 2873 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2866 if (trace_file != nullptr) { | 2874 if (trace_file != nullptr) { |
2867 PrintF(trace_file, " reading getter frame "); | 2875 SmartArrayPointer<char> name = shared_info->DebugName()->ToCString(); |
2868 function->PrintName(trace_file); | 2876 PrintF(trace_file, " reading getter frame %s; inputs:\n", name.get()); |
2869 PrintF(trace_file, "; inputs:\n"); | |
2870 } | 2877 } |
2871 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, function); | 2878 return TranslatedFrame::AccessorFrame(TranslatedFrame::kGetter, |
| 2879 shared_info); |
2872 } | 2880 } |
2873 | 2881 |
2874 case Translation::SETTER_STUB_FRAME: { | 2882 case Translation::SETTER_STUB_FRAME: { |
2875 JSFunction* function = | 2883 SharedFunctionInfo* shared_info = |
2876 JSFunction::cast(literal_array->get(iterator->Next())); | 2884 SharedFunctionInfo::cast(literal_array->get(iterator->Next())); |
2877 if (trace_file != nullptr) { | 2885 if (trace_file != nullptr) { |
2878 PrintF(trace_file, " reading setter frame "); | 2886 SmartArrayPointer<char> name = shared_info->DebugName()->ToCString(); |
2879 function->PrintName(trace_file); | 2887 PrintF(trace_file, " reading setter frame %s; inputs:\n", name.get()); |
2880 PrintF(trace_file, "; inputs:\n"); | |
2881 } | 2888 } |
2882 return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter, function); | 2889 return TranslatedFrame::AccessorFrame(TranslatedFrame::kSetter, |
| 2890 shared_info); |
2883 } | 2891 } |
2884 | 2892 |
2885 case Translation::COMPILED_STUB_FRAME: { | 2893 case Translation::COMPILED_STUB_FRAME: { |
2886 int height = iterator->Next(); | 2894 int height = iterator->Next(); |
2887 if (trace_file != nullptr) { | 2895 if (trace_file != nullptr) { |
2888 PrintF(trace_file, | 2896 PrintF(trace_file, |
2889 " reading compiler stub frame => height=%d; inputs:\n", height); | 2897 " reading compiler stub frame => height=%d; inputs:\n", height); |
2890 } | 2898 } |
2891 return TranslatedFrame::CompiledStubFrame(height, | 2899 return TranslatedFrame::CompiledStubFrame(height, |
2892 literal_array->GetIsolate()); | 2900 literal_array->GetIsolate()); |
2893 } | 2901 } |
2894 | 2902 |
2895 case Translation::BEGIN: | 2903 case Translation::BEGIN: |
2896 case Translation::DUPLICATED_OBJECT: | 2904 case Translation::DUPLICATED_OBJECT: |
2897 case Translation::ARGUMENTS_OBJECT: | 2905 case Translation::ARGUMENTS_OBJECT: |
2898 case Translation::CAPTURED_OBJECT: | 2906 case Translation::CAPTURED_OBJECT: |
2899 case Translation::REGISTER: | 2907 case Translation::REGISTER: |
2900 case Translation::INT32_REGISTER: | 2908 case Translation::INT32_REGISTER: |
2901 case Translation::UINT32_REGISTER: | 2909 case Translation::UINT32_REGISTER: |
2902 case Translation::BOOL_REGISTER: | 2910 case Translation::BOOL_REGISTER: |
2903 case Translation::DOUBLE_REGISTER: | 2911 case Translation::DOUBLE_REGISTER: |
2904 case Translation::STACK_SLOT: | 2912 case Translation::STACK_SLOT: |
2905 case Translation::INT32_STACK_SLOT: | 2913 case Translation::INT32_STACK_SLOT: |
2906 case Translation::UINT32_STACK_SLOT: | 2914 case Translation::UINT32_STACK_SLOT: |
2907 case Translation::BOOL_STACK_SLOT: | 2915 case Translation::BOOL_STACK_SLOT: |
2908 case Translation::DOUBLE_STACK_SLOT: | 2916 case Translation::DOUBLE_STACK_SLOT: |
2909 case Translation::LITERAL: | 2917 case Translation::LITERAL: |
| 2918 case Translation::JS_FRAME_FUNCTION: |
2910 break; | 2919 break; |
2911 } | 2920 } |
2912 FATAL("We should never get here - unexpected deopt info."); | 2921 FATAL("We should never get here - unexpected deopt info."); |
2913 return TranslatedFrame::InvalidFrame(); | 2922 return TranslatedFrame::InvalidFrame(); |
2914 } | 2923 } |
2915 | 2924 |
2916 | 2925 |
2917 // static | 2926 // static |
2918 void TranslatedFrame::AdvanceIterator( | 2927 void TranslatedFrame::AdvanceIterator( |
2919 std::deque<TranslatedValue>::iterator* iter) { | 2928 std::deque<TranslatedValue>::iterator* iter) { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3096 int literal_index = iterator->Next(); | 3105 int literal_index = iterator->Next(); |
3097 Object* value = literal_array->get(literal_index); | 3106 Object* value = literal_array->get(literal_index); |
3098 if (trace_file != nullptr) { | 3107 if (trace_file != nullptr) { |
3099 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ", | 3108 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (literal %d) ", |
3100 reinterpret_cast<intptr_t>(value), literal_index); | 3109 reinterpret_cast<intptr_t>(value), literal_index); |
3101 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); | 3110 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
3102 } | 3111 } |
3103 | 3112 |
3104 return TranslatedValue::NewTagged(this, value); | 3113 return TranslatedValue::NewTagged(this, value); |
3105 } | 3114 } |
| 3115 |
| 3116 case Translation::JS_FRAME_FUNCTION: { |
| 3117 int slot_offset = JavaScriptFrameConstants::kFunctionOffset; |
| 3118 intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset)); |
| 3119 if (trace_file != nullptr) { |
| 3120 PrintF(trace_file, "0x%08" V8PRIxPTR " ; (frame function) ", value); |
| 3121 reinterpret_cast<Object*>(value)->ShortPrint(trace_file); |
| 3122 } |
| 3123 return TranslatedValue::NewTagged(this, reinterpret_cast<Object*>(value)); |
| 3124 } |
3106 } | 3125 } |
3107 | 3126 |
3108 FATAL("We should never get here - unexpected deopt info."); | 3127 FATAL("We should never get here - unexpected deopt info."); |
3109 return TranslatedValue(nullptr, TranslatedValue::kInvalid); | 3128 return TranslatedValue(nullptr, TranslatedValue::kInvalid); |
3110 } | 3129 } |
3111 | 3130 |
3112 | 3131 |
3113 TranslatedState::TranslatedState(JavaScriptFrame* frame) | 3132 TranslatedState::TranslatedState(JavaScriptFrame* frame) |
3114 : isolate_(nullptr), | 3133 : isolate_(nullptr), |
3115 stack_frame_pointer_(nullptr), | 3134 stack_frame_pointer_(nullptr), |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3200 } | 3219 } |
3201 | 3220 |
3202 CHECK(!iterator->HasNext() || | 3221 CHECK(!iterator->HasNext() || |
3203 static_cast<Translation::Opcode>(iterator->Next()) == | 3222 static_cast<Translation::Opcode>(iterator->Next()) == |
3204 Translation::BEGIN); | 3223 Translation::BEGIN); |
3205 } | 3224 } |
3206 | 3225 |
3207 | 3226 |
3208 void TranslatedState::Prepare(bool has_adapted_arguments, | 3227 void TranslatedState::Prepare(bool has_adapted_arguments, |
3209 Address stack_frame_pointer) { | 3228 Address stack_frame_pointer) { |
3210 for (auto& frame : frames_) { | 3229 for (auto& frame : frames_) frame.Handlify(); |
3211 frame.Handlify(isolate_); | |
3212 } | |
3213 | 3230 |
3214 stack_frame_pointer_ = stack_frame_pointer; | 3231 stack_frame_pointer_ = stack_frame_pointer; |
3215 has_adapted_arguments_ = has_adapted_arguments; | 3232 has_adapted_arguments_ = has_adapted_arguments; |
3216 | 3233 |
3217 UpdateFromPreviouslyMaterializedObjects(); | 3234 UpdateFromPreviouslyMaterializedObjects(); |
3218 } | 3235 } |
3219 | 3236 |
3220 | 3237 |
3221 Handle<Object> TranslatedState::MaterializeAt(int frame_index, | 3238 Handle<Object> TranslatedState::MaterializeAt(int frame_index, |
3222 int* value_index) { | 3239 int* value_index) { |
(...skipping 19 matching lines...) Expand all Loading... |
3242 | 3259 |
3243 case TranslatedValue::kArgumentsObject: { | 3260 case TranslatedValue::kArgumentsObject: { |
3244 int length = slot->GetChildrenCount(); | 3261 int length = slot->GetChildrenCount(); |
3245 Handle<JSObject> arguments; | 3262 Handle<JSObject> arguments; |
3246 if (GetAdaptedArguments(&arguments, frame_index)) { | 3263 if (GetAdaptedArguments(&arguments, frame_index)) { |
3247 // Store the materialized object and consume the nested values. | 3264 // Store the materialized object and consume the nested values. |
3248 for (int i = 0; i < length; ++i) { | 3265 for (int i = 0; i < length; ++i) { |
3249 MaterializeAt(frame_index, value_index); | 3266 MaterializeAt(frame_index, value_index); |
3250 } | 3267 } |
3251 } else { | 3268 } else { |
3252 Handle<JSFunction> function = frame->function(); | 3269 Handle<JSFunction> function = |
| 3270 Handle<JSFunction>::cast(frame->front().GetValue()); |
3253 arguments = isolate_->factory()->NewArgumentsObject(function, length); | 3271 arguments = isolate_->factory()->NewArgumentsObject(function, length); |
3254 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); | 3272 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); |
3255 DCHECK_EQ(array->length(), length); | 3273 DCHECK_EQ(array->length(), length); |
3256 arguments->set_elements(*array); | 3274 arguments->set_elements(*array); |
3257 for (int i = 0; i < length; ++i) { | 3275 for (int i = 0; i < length; ++i) { |
3258 Handle<Object> value = MaterializeAt(frame_index, value_index); | 3276 Handle<Object> value = MaterializeAt(frame_index, value_index); |
3259 array->set(i, *value); | 3277 array->set(i, *value); |
3260 } | 3278 } |
3261 } | 3279 } |
3262 slot->value_ = arguments; | 3280 slot->value_ = arguments; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3373 | 3391 |
3374 bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, | 3392 bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, |
3375 int frame_index) { | 3393 int frame_index) { |
3376 if (frame_index == 0) { | 3394 if (frame_index == 0) { |
3377 // Top level frame -> we need to go to the parent frame on the stack. | 3395 // Top level frame -> we need to go to the parent frame on the stack. |
3378 if (!has_adapted_arguments_) return false; | 3396 if (!has_adapted_arguments_) return false; |
3379 | 3397 |
3380 // This is top level frame, so we need to go to the stack to get | 3398 // This is top level frame, so we need to go to the stack to get |
3381 // this function's argument. (Note that this relies on not inlining | 3399 // this function's argument. (Note that this relies on not inlining |
3382 // recursive functions!) | 3400 // recursive functions!) |
3383 Handle<JSFunction> function = frames_[frame_index].function(); | 3401 Handle<JSFunction> function = |
| 3402 Handle<JSFunction>::cast(frames_[frame_index].front().GetValue()); |
3384 *result = Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); | 3403 *result = Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); |
3385 return true; | 3404 return true; |
3386 } else { | 3405 } else { |
3387 TranslatedFrame* previous_frame = &(frames_[frame_index]); | 3406 TranslatedFrame* previous_frame = &(frames_[frame_index]); |
3388 if (previous_frame->kind() != TranslatedFrame::kArgumentsAdaptor) { | 3407 if (previous_frame->kind() != TranslatedFrame::kArgumentsAdaptor) { |
3389 return false; | 3408 return false; |
3390 } | 3409 } |
3391 // We get the adapted arguments from the parent translation. | 3410 // We get the adapted arguments from the parent translation. |
3392 int length = previous_frame->GetValueCount(); | 3411 int length = previous_frame->height(); |
3393 Handle<JSFunction> function = previous_frame->function(); | 3412 Handle<JSFunction> function = |
| 3413 Handle<JSFunction>::cast(previous_frame->front().GetValue()); |
3394 Handle<JSObject> arguments = | 3414 Handle<JSObject> arguments = |
3395 isolate_->factory()->NewArgumentsObject(function, length); | 3415 isolate_->factory()->NewArgumentsObject(function, length); |
3396 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); | 3416 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); |
3397 arguments->set_elements(*array); | 3417 arguments->set_elements(*array); |
3398 TranslatedFrame::iterator arg_iterator = previous_frame->begin(); | 3418 TranslatedFrame::iterator arg_iterator = previous_frame->begin(); |
| 3419 arg_iterator++; // Skip function. |
3399 for (int i = 0; i < length; ++i) { | 3420 for (int i = 0; i < length; ++i) { |
3400 Handle<Object> value = arg_iterator->GetValue(); | 3421 Handle<Object> value = arg_iterator->GetValue(); |
3401 array->set(i, *value); | 3422 array->set(i, *value); |
3402 arg_iterator++; | 3423 arg_iterator++; |
3403 } | 3424 } |
3404 CHECK(arg_iterator == previous_frame->end()); | 3425 CHECK(arg_iterator == previous_frame->end()); |
3405 *result = arguments; | 3426 *result = arguments; |
3406 return true; | 3427 return true; |
3407 } | 3428 } |
3408 } | 3429 } |
3409 | 3430 |
3410 | 3431 |
3411 TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex( | 3432 TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex( |
3412 int jsframe_index, int* args_count) { | 3433 int jsframe_index, int* args_count) { |
3413 for (size_t i = 0; i < frames_.size(); i++) { | 3434 for (size_t i = 0; i < frames_.size(); i++) { |
3414 if (frames_[i].kind() == TranslatedFrame::kFunction) { | 3435 if (frames_[i].kind() == TranslatedFrame::kFunction) { |
3415 if (jsframe_index > 0) { | 3436 if (jsframe_index > 0) { |
3416 jsframe_index--; | 3437 jsframe_index--; |
3417 } else { | 3438 } else { |
3418 // We have the JS function frame, now check if it has arguments adaptor. | 3439 // We have the JS function frame, now check if it has arguments adaptor. |
3419 if (i > 0 && | 3440 if (i > 0 && |
3420 frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) { | 3441 frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) { |
3421 *args_count = frames_[i - 1].height(); | 3442 *args_count = frames_[i - 1].height(); |
3422 return &(frames_[i - 1]); | 3443 return &(frames_[i - 1]); |
3423 } | 3444 } |
3424 *args_count = | 3445 *args_count = |
3425 frames_[i].function()->shared()->internal_formal_parameter_count() + | 3446 frames_[i].shared_info()->internal_formal_parameter_count() + 1; |
3426 1; | |
3427 return &(frames_[i]); | 3447 return &(frames_[i]); |
3428 } | 3448 } |
3429 } | 3449 } |
3430 } | 3450 } |
3431 return nullptr; | 3451 return nullptr; |
3432 } | 3452 } |
3433 | 3453 |
3434 | 3454 |
3435 void TranslatedState::StoreMaterializedValuesAndDeopt() { | 3455 void TranslatedState::StoreMaterializedValuesAndDeopt() { |
3436 MaterializedObjectStore* materialized_store = | 3456 MaterializedObjectStore* materialized_store = |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3468 previously_materialized_objects->set(i, *value); | 3488 previously_materialized_objects->set(i, *value); |
3469 value_changed = true; | 3489 value_changed = true; |
3470 } else { | 3490 } else { |
3471 DCHECK(previously_materialized_objects->get(i) == *value); | 3491 DCHECK(previously_materialized_objects->get(i) == *value); |
3472 } | 3492 } |
3473 } | 3493 } |
3474 } | 3494 } |
3475 if (new_store && value_changed) { | 3495 if (new_store && value_changed) { |
3476 materialized_store->Set(stack_frame_pointer_, | 3496 materialized_store->Set(stack_frame_pointer_, |
3477 previously_materialized_objects); | 3497 previously_materialized_objects); |
3478 DCHECK(frames_[0].kind() == TranslatedFrame::kFunction); | 3498 DCHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind()); |
3479 Deoptimizer::DeoptimizeFunction(*(frames_[0].function())); | 3499 Object* const function = frames_[0].front().GetRawValue(); |
| 3500 Deoptimizer::DeoptimizeFunction(JSFunction::cast(function)); |
3480 } | 3501 } |
3481 } | 3502 } |
3482 | 3503 |
3483 | 3504 |
3484 void TranslatedState::UpdateFromPreviouslyMaterializedObjects() { | 3505 void TranslatedState::UpdateFromPreviouslyMaterializedObjects() { |
3485 MaterializedObjectStore* materialized_store = | 3506 MaterializedObjectStore* materialized_store = |
3486 isolate_->materialized_object_store(); | 3507 isolate_->materialized_object_store(); |
3487 Handle<FixedArray> previously_materialized_objects = | 3508 Handle<FixedArray> previously_materialized_objects = |
3488 materialized_store->Get(stack_frame_pointer_); | 3509 materialized_store->Get(stack_frame_pointer_); |
3489 | 3510 |
(...skipping 15 matching lines...) Expand all Loading... |
3505 DCHECK(value_info->IsMaterializedObject()); | 3526 DCHECK(value_info->IsMaterializedObject()); |
3506 | 3527 |
3507 value_info->value_ = | 3528 value_info->value_ = |
3508 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3529 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3509 } | 3530 } |
3510 } | 3531 } |
3511 } | 3532 } |
3512 | 3533 |
3513 } // namespace internal | 3534 } // namespace internal |
3514 } // namespace v8 | 3535 } // namespace v8 |
OLD | NEW |