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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 return frame_index - 1; | 127 return frame_index - 1; |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( | 131 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( |
132 JavaScriptFrame* frame, | 132 JavaScriptFrame* frame, |
133 int jsframe_index, | 133 int jsframe_index, |
134 Isolate* isolate) { | 134 Isolate* isolate) { |
135 CHECK(frame->is_optimized()); | 135 CHECK(frame->is_optimized()); |
136 | 136 |
137 // Get the function and code from the frame. | 137 TranslatedState translated_values(frame); |
138 JSFunction* function = frame->function(); | 138 translated_values.Prepare(false, frame->fp()); |
139 Code* code = frame->LookupCode(); | |
140 | 139 |
141 // Locate the deoptimization point in the code. As we are at a call the | 140 TranslatedState::iterator frame_it = translated_values.end(); |
142 // return address must be at a place in the code with deoptimization support. | 141 int counter = jsframe_index; |
143 SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc()); | 142 for (auto it = translated_values.begin(); it != translated_values.end(); |
144 int deoptimization_index = safepoint_entry.deoptimization_index(); | 143 it++) { |
145 CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex); | 144 if (it->kind() == TranslatedFrame::kFunction || |
| 145 it->kind() == TranslatedFrame::kInterpretedFunction) { |
| 146 if (counter == 0) { |
| 147 frame_it = it; |
| 148 break; |
| 149 } |
| 150 counter--; |
| 151 } |
| 152 } |
| 153 CHECK(frame_it != translated_values.end()); |
146 | 154 |
147 // Always use the actual stack slots when calculating the fp to sp | 155 DeoptimizedFrameInfo* info = |
148 // delta adding two for the function and context. | 156 new DeoptimizedFrameInfo(&translated_values, frame_it, isolate); |
149 unsigned stack_slots = code->stack_slots(); | |
150 unsigned arguments_stack_height = | |
151 Deoptimizer::ComputeOutgoingArgumentSize(code, deoptimization_index); | |
152 unsigned fp_to_sp_delta = (stack_slots * kPointerSize) + | |
153 StandardFrameConstants::kFixedFrameSizeFromFp + | |
154 arguments_stack_height; | |
155 | |
156 Deoptimizer* deoptimizer = new Deoptimizer(isolate, | |
157 function, | |
158 Deoptimizer::DEBUGGER, | |
159 deoptimization_index, | |
160 frame->pc(), | |
161 fp_to_sp_delta, | |
162 code); | |
163 Address tos = frame->fp() - fp_to_sp_delta; | |
164 deoptimizer->FillInputFrame(tos, frame); | |
165 | |
166 // Calculate the output frames. | |
167 Deoptimizer::ComputeOutputFrames(deoptimizer); | |
168 | |
169 // Create the GC safe output frame information and register it for GC | |
170 // handling. | |
171 CHECK_LT(jsframe_index, deoptimizer->jsframe_count()); | |
172 | |
173 // Convert JS frame index into frame index. | |
174 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index); | |
175 | |
176 bool has_arguments_adaptor = | |
177 frame_index > 0 && | |
178 deoptimizer->output_[frame_index - 1]->GetFrameType() == | |
179 StackFrame::ARGUMENTS_ADAPTOR; | |
180 | |
181 int construct_offset = has_arguments_adaptor ? 2 : 1; | |
182 bool has_construct_stub = | |
183 frame_index >= construct_offset && | |
184 deoptimizer->output_[frame_index - construct_offset]->GetFrameType() == | |
185 StackFrame::CONSTRUCT; | |
186 | |
187 DeoptimizedFrameInfo* info = new DeoptimizedFrameInfo(deoptimizer, | |
188 frame_index, | |
189 has_arguments_adaptor, | |
190 has_construct_stub); | |
191 | |
192 // Done with the GC-unsafe frame descriptions. This re-enables allocation. | |
193 deoptimizer->DeleteFrameDescriptions(); | |
194 | |
195 // Allocate a heap number for the doubles belonging to this frame. | |
196 deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame( | |
197 frame_index, info->parameters_count(), info->expression_count(), info); | |
198 | |
199 // Finished using the deoptimizer instance. | |
200 delete deoptimizer; | |
201 | 157 |
202 return info; | 158 return info; |
203 } | 159 } |
204 | 160 |
205 | 161 |
206 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, | 162 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, |
207 Isolate* isolate) { | 163 Isolate* isolate) { |
208 delete info; | 164 delete info; |
209 } | 165 } |
210 | 166 |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 trace_scope_ = TraceEnabledFor(type, frame_type) ? | 512 trace_scope_ = TraceEnabledFor(type, frame_type) ? |
557 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; | 513 new CodeTracer::Scope(isolate->GetCodeTracer()) : NULL; |
558 #ifdef DEBUG | 514 #ifdef DEBUG |
559 CHECK(AllowHeapAllocation::IsAllowed()); | 515 CHECK(AllowHeapAllocation::IsAllowed()); |
560 disallow_heap_allocation_ = new DisallowHeapAllocation(); | 516 disallow_heap_allocation_ = new DisallowHeapAllocation(); |
561 #endif // DEBUG | 517 #endif // DEBUG |
562 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { | 518 if (compiled_code_->kind() == Code::OPTIMIZED_FUNCTION) { |
563 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_)); | 519 PROFILE(isolate_, CodeDeoptEvent(compiled_code_, from_, fp_to_sp_delta_)); |
564 } | 520 } |
565 unsigned size = ComputeInputFrameSize(); | 521 unsigned size = ComputeInputFrameSize(); |
566 input_ = new(size) FrameDescription(size, function); | 522 int parameter_count = |
| 523 function == nullptr |
| 524 ? 0 |
| 525 : (function->shared()->internal_formal_parameter_count() + 1); |
| 526 input_ = new (size) FrameDescription(size, parameter_count); |
567 input_->SetFrameType(frame_type); | 527 input_->SetFrameType(frame_type); |
568 } | 528 } |
569 | 529 |
570 | 530 |
571 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, | 531 Code* Deoptimizer::FindOptimizedCode(JSFunction* function, |
572 Code* optimized_code) { | 532 Code* optimized_code) { |
573 switch (bailout_type_) { | 533 switch (bailout_type_) { |
574 case Deoptimizer::SOFT: | 534 case Deoptimizer::SOFT: |
575 case Deoptimizer::EAGER: | 535 case Deoptimizer::EAGER: |
576 case Deoptimizer::LAZY: { | 536 case Deoptimizer::LAZY: { |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 | 829 |
870 BailoutId node_id = translated_frame->node_id(); | 830 BailoutId node_id = translated_frame->node_id(); |
871 unsigned height = | 831 unsigned height = |
872 translated_frame->height() - 1; // Do not count the context. | 832 translated_frame->height() - 1; // Do not count the context. |
873 unsigned height_in_bytes = height * kPointerSize; | 833 unsigned height_in_bytes = height * kPointerSize; |
874 if (goto_catch_handler) { | 834 if (goto_catch_handler) { |
875 // Take the stack height from the handler table. | 835 // Take the stack height from the handler table. |
876 height = catch_handler_data_; | 836 height = catch_handler_data_; |
877 // We also make space for the exception itself. | 837 // We also make space for the exception itself. |
878 height_in_bytes = (height + 1) * kPointerSize; | 838 height_in_bytes = (height + 1) * kPointerSize; |
879 DCHECK(is_topmost); | 839 CHECK(is_topmost); |
880 } | 840 } |
881 | 841 |
882 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 842 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); |
883 value_iterator++; | 843 value_iterator++; |
884 input_index++; | 844 input_index++; |
885 if (trace_scope_ != NULL) { | 845 if (trace_scope_ != NULL) { |
886 PrintF(trace_scope_->file(), " translating frame "); | 846 PrintF(trace_scope_->file(), " translating frame "); |
887 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString(); | 847 base::SmartArrayPointer<char> name = shared->DebugName()->ToCString(); |
888 PrintF(trace_scope_->file(), "%s", name.get()); | 848 PrintF(trace_scope_->file(), "%s", name.get()); |
889 PrintF(trace_scope_->file(), | 849 PrintF(trace_scope_->file(), |
890 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); | 850 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); |
891 PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(), | 851 PrintF(trace_scope_->file(), " => node=%d, height=%d%s\n", node_id.ToInt(), |
892 height_in_bytes, goto_catch_handler ? " (throw)" : ""); | 852 height_in_bytes, goto_catch_handler ? " (throw)" : ""); |
893 } | 853 } |
894 | 854 |
895 // The 'fixed' part of the frame consists of the incoming parameters and | 855 // The 'fixed' part of the frame consists of the incoming parameters and |
896 // the part described by JavaScriptFrameConstants. | 856 // the part described by JavaScriptFrameConstants. |
897 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared); | 857 unsigned fixed_frame_size = ComputeJavascriptFixedSize(shared); |
898 unsigned input_frame_size = input_->GetFrameSize(); | 858 unsigned input_frame_size = input_->GetFrameSize(); |
899 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 859 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
900 | 860 |
901 // Allocate and store the output frame description. | 861 // Allocate and store the output frame description. |
902 FrameDescription* output_frame = | 862 int parameter_count = shared->internal_formal_parameter_count() + 1; |
903 new(output_frame_size) FrameDescription(output_frame_size, function); | 863 FrameDescription* output_frame = new (output_frame_size) |
| 864 FrameDescription(output_frame_size, parameter_count); |
904 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); | 865 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); |
905 | 866 |
906 CHECK(frame_index >= 0 && frame_index < output_count_); | 867 CHECK(frame_index >= 0 && frame_index < output_count_); |
907 CHECK_NULL(output_[frame_index]); | 868 CHECK_NULL(output_[frame_index]); |
908 output_[frame_index] = output_frame; | 869 output_[frame_index] = output_frame; |
909 | 870 |
910 // 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 |
911 // 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 |
912 // 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 |
913 // top address and the current frame's size. | 874 // top address and the current frame's size. |
(...skipping 10 matching lines...) Expand all Loading... |
924 // is removed. Subtract 2 * kPointerSize for the context and function slots. | 885 // is removed. Subtract 2 * kPointerSize for the context and function slots. |
925 top_address = input_->GetRegister(fp_reg.code()) - | 886 top_address = input_->GetRegister(fp_reg.code()) - |
926 StandardFrameConstants::kFixedFrameSizeFromFp - | 887 StandardFrameConstants::kFixedFrameSizeFromFp - |
927 height_in_bytes + has_alignment_padding_ * kPointerSize; | 888 height_in_bytes + has_alignment_padding_ * kPointerSize; |
928 } else { | 889 } else { |
929 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 890 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
930 } | 891 } |
931 output_frame->SetTop(top_address); | 892 output_frame->SetTop(top_address); |
932 | 893 |
933 // Compute the incoming parameter translation. | 894 // Compute the incoming parameter translation. |
934 int parameter_count = shared->internal_formal_parameter_count() + 1; | |
935 unsigned output_offset = output_frame_size; | 895 unsigned output_offset = output_frame_size; |
936 unsigned input_offset = input_frame_size; | 896 unsigned input_offset = input_frame_size; |
937 for (int i = 0; i < parameter_count; ++i) { | 897 for (int i = 0; i < parameter_count; ++i) { |
938 output_offset -= kPointerSize; | 898 output_offset -= kPointerSize; |
939 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 899 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
940 output_offset); | 900 output_offset); |
941 } | 901 } |
942 input_offset -= (parameter_count * kPointerSize); | 902 input_offset -= (parameter_count * kPointerSize); |
943 | 903 |
944 // There are no translation commands for the caller's pc and fp, the | 904 // There are no translation commands for the caller's pc and fp, the |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 bytecode_offset = catch_handler_pc_offset_; | 1100 bytecode_offset = catch_handler_pc_offset_; |
1141 } | 1101 } |
1142 | 1102 |
1143 // The 'fixed' part of the frame consists of the incoming parameters and | 1103 // The 'fixed' part of the frame consists of the incoming parameters and |
1144 // the part described by InterpreterFrameConstants. | 1104 // the part described by InterpreterFrameConstants. |
1145 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); | 1105 unsigned fixed_frame_size = ComputeInterpretedFixedSize(shared); |
1146 unsigned input_frame_size = input_->GetFrameSize(); | 1106 unsigned input_frame_size = input_->GetFrameSize(); |
1147 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1107 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1148 | 1108 |
1149 // Allocate and store the output frame description. | 1109 // Allocate and store the output frame description. |
1150 FrameDescription* output_frame = | 1110 int parameter_count = shared->internal_formal_parameter_count() + 1; |
1151 new (output_frame_size) FrameDescription(output_frame_size, function); | 1111 FrameDescription* output_frame = new (output_frame_size) |
| 1112 FrameDescription(output_frame_size, parameter_count); |
1152 output_frame->SetFrameType(StackFrame::INTERPRETED); | 1113 output_frame->SetFrameType(StackFrame::INTERPRETED); |
1153 | 1114 |
1154 bool is_bottommost = (0 == frame_index); | 1115 bool is_bottommost = (0 == frame_index); |
1155 bool is_topmost = (output_count_ - 1 == frame_index); | 1116 bool is_topmost = (output_count_ - 1 == frame_index); |
1156 CHECK(frame_index >= 0 && frame_index < output_count_); | 1117 CHECK(frame_index >= 0 && frame_index < output_count_); |
1157 CHECK_NULL(output_[frame_index]); | 1118 CHECK_NULL(output_[frame_index]); |
1158 output_[frame_index] = output_frame; | 1119 output_[frame_index] = output_frame; |
1159 | 1120 |
1160 // The top address for the bottommost output frame can be computed from | 1121 // The top address for the bottommost output frame can be computed from |
1161 // the input frame pointer and the output frame's height. For all | 1122 // the input frame pointer and the output frame's height. For all |
1162 // subsequent output frames, it can be computed from the previous one's | 1123 // subsequent output frames, it can be computed from the previous one's |
1163 // top address and the current frame's size. | 1124 // top address and the current frame's size. |
1164 Register fp_reg = InterpretedFrame::fp_register(); | 1125 Register fp_reg = InterpretedFrame::fp_register(); |
1165 intptr_t top_address; | 1126 intptr_t top_address; |
1166 if (is_bottommost) { | 1127 if (is_bottommost) { |
1167 // Subtract interpreter fixed frame size for the context function slots, | 1128 // Subtract interpreter fixed frame size for the context function slots, |
1168 // new,target and bytecode offset. | 1129 // new,target and bytecode offset. |
1169 top_address = input_->GetRegister(fp_reg.code()) - | 1130 top_address = input_->GetRegister(fp_reg.code()) - |
1170 InterpreterFrameConstants::kFixedFrameSizeFromFp - | 1131 InterpreterFrameConstants::kFixedFrameSizeFromFp - |
1171 height_in_bytes; | 1132 height_in_bytes; |
1172 } else { | 1133 } else { |
1173 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1134 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
1174 } | 1135 } |
1175 output_frame->SetTop(top_address); | 1136 output_frame->SetTop(top_address); |
1176 | 1137 |
1177 // Compute the incoming parameter translation. | 1138 // Compute the incoming parameter translation. |
1178 int parameter_count = shared->internal_formal_parameter_count() + 1; | |
1179 unsigned output_offset = output_frame_size; | 1139 unsigned output_offset = output_frame_size; |
1180 unsigned input_offset = input_frame_size; | 1140 unsigned input_offset = input_frame_size; |
1181 for (int i = 0; i < parameter_count; ++i) { | 1141 for (int i = 0; i < parameter_count; ++i) { |
1182 output_offset -= kPointerSize; | 1142 output_offset -= kPointerSize; |
1183 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1143 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1184 output_offset); | 1144 output_offset); |
1185 } | 1145 } |
1186 input_offset -= (parameter_count * kPointerSize); | 1146 input_offset -= (parameter_count * kPointerSize); |
1187 | 1147 |
1188 // There are no translation commands for the caller's pc and fp, the | 1148 // There are no translation commands for the caller's pc and fp, the |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 input_index++; | 1336 input_index++; |
1377 if (trace_scope_ != NULL) { | 1337 if (trace_scope_ != NULL) { |
1378 PrintF(trace_scope_->file(), | 1338 PrintF(trace_scope_->file(), |
1379 " translating arguments adaptor => height=%d\n", height_in_bytes); | 1339 " translating arguments adaptor => height=%d\n", height_in_bytes); |
1380 } | 1340 } |
1381 | 1341 |
1382 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; | 1342 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; |
1383 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1343 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1384 | 1344 |
1385 // Allocate and store the output frame description. | 1345 // Allocate and store the output frame description. |
1386 FrameDescription* output_frame = | 1346 int parameter_count = height; |
1387 new(output_frame_size) FrameDescription(output_frame_size, function); | 1347 FrameDescription* output_frame = new (output_frame_size) |
| 1348 FrameDescription(output_frame_size, parameter_count); |
1388 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); | 1349 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); |
1389 | 1350 |
1390 // Arguments adaptor can not be topmost or bottommost. | 1351 // Arguments adaptor can not be topmost or bottommost. |
1391 CHECK(frame_index > 0 && frame_index < output_count_ - 1); | 1352 CHECK(frame_index > 0 && frame_index < output_count_ - 1); |
1392 CHECK(output_[frame_index] == NULL); | 1353 CHECK(output_[frame_index] == NULL); |
1393 output_[frame_index] = output_frame; | 1354 output_[frame_index] = output_frame; |
1394 | 1355 |
1395 // The top address of the frame is computed from the previous | 1356 // The top address of the frame is computed from the previous |
1396 // frame's top and this frame's size. | 1357 // frame's top and this frame's size. |
1397 intptr_t top_address; | 1358 intptr_t top_address; |
1398 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1359 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
1399 output_frame->SetTop(top_address); | 1360 output_frame->SetTop(top_address); |
1400 | 1361 |
1401 // Compute the incoming parameter translation. | 1362 // Compute the incoming parameter translation. |
1402 int parameter_count = height; | |
1403 unsigned output_offset = output_frame_size; | 1363 unsigned output_offset = output_frame_size; |
1404 for (int i = 0; i < parameter_count; ++i) { | 1364 for (int i = 0; i < parameter_count; ++i) { |
1405 output_offset -= kPointerSize; | 1365 output_offset -= kPointerSize; |
1406 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, | 1366 WriteTranslatedValueToOutput(&value_iterator, &input_index, frame_index, |
1407 output_offset); | 1367 output_offset); |
1408 } | 1368 } |
1409 | 1369 |
1410 // Read caller's PC from the previous frame. | 1370 // Read caller's PC from the previous frame. |
1411 output_offset -= kPCOnStackSize; | 1371 output_offset -= kPCOnStackSize; |
1412 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 1372 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1472 void Deoptimizer::DoComputeConstructStubFrame(int frame_index) { | 1432 void Deoptimizer::DoComputeConstructStubFrame(int frame_index) { |
1473 TranslatedFrame* translated_frame = | 1433 TranslatedFrame* translated_frame = |
1474 &(translated_state_.frames()[frame_index]); | 1434 &(translated_state_.frames()[frame_index]); |
1475 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1435 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1476 int input_index = 0; | 1436 int input_index = 0; |
1477 | 1437 |
1478 Builtins* builtins = isolate_->builtins(); | 1438 Builtins* builtins = isolate_->builtins(); |
1479 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 1439 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); |
1480 unsigned height = translated_frame->height(); | 1440 unsigned height = translated_frame->height(); |
1481 unsigned height_in_bytes = height * kPointerSize; | 1441 unsigned height_in_bytes = height * kPointerSize; |
1482 JSFunction* function = JSFunction::cast(value_iterator->GetRawValue()); | 1442 // Skip function. |
1483 value_iterator++; | 1443 value_iterator++; |
1484 input_index++; | 1444 input_index++; |
1485 if (trace_scope_ != NULL) { | 1445 if (trace_scope_ != NULL) { |
1486 PrintF(trace_scope_->file(), | 1446 PrintF(trace_scope_->file(), |
1487 " translating construct stub => height=%d\n", height_in_bytes); | 1447 " translating construct stub => height=%d\n", height_in_bytes); |
1488 } | 1448 } |
1489 | 1449 |
1490 unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize; | 1450 unsigned fixed_frame_size = ConstructFrameConstants::kFrameSize; |
1491 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1451 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1492 | 1452 |
1493 // Allocate and store the output frame description. | 1453 // Allocate and store the output frame description. |
1494 FrameDescription* output_frame = | 1454 FrameDescription* output_frame = |
1495 new(output_frame_size) FrameDescription(output_frame_size, function); | 1455 new (output_frame_size) FrameDescription(output_frame_size); |
1496 output_frame->SetFrameType(StackFrame::CONSTRUCT); | 1456 output_frame->SetFrameType(StackFrame::CONSTRUCT); |
1497 | 1457 |
1498 // Construct stub can not be topmost or bottommost. | 1458 // Construct stub can not be topmost or bottommost. |
1499 DCHECK(frame_index > 0 && frame_index < output_count_ - 1); | 1459 DCHECK(frame_index > 0 && frame_index < output_count_ - 1); |
1500 DCHECK(output_[frame_index] == NULL); | 1460 DCHECK(output_[frame_index] == NULL); |
1501 output_[frame_index] = output_frame; | 1461 output_[frame_index] = output_frame; |
1502 | 1462 |
1503 // The top address of the frame is computed from the previous | 1463 // The top address of the frame is computed from the previous |
1504 // frame's top and this frame's size. | 1464 // frame's top and this frame's size. |
1505 intptr_t top_address; | 1465 intptr_t top_address; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 } | 1558 } |
1599 | 1559 |
1600 | 1560 |
1601 void Deoptimizer::DoComputeAccessorStubFrame(int frame_index, | 1561 void Deoptimizer::DoComputeAccessorStubFrame(int frame_index, |
1602 bool is_setter_stub_frame) { | 1562 bool is_setter_stub_frame) { |
1603 TranslatedFrame* translated_frame = | 1563 TranslatedFrame* translated_frame = |
1604 &(translated_state_.frames()[frame_index]); | 1564 &(translated_state_.frames()[frame_index]); |
1605 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1565 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1606 int input_index = 0; | 1566 int input_index = 0; |
1607 | 1567 |
1608 JSFunction* accessor = JSFunction::cast(value_iterator->GetRawValue()); | 1568 // Skip accessor. |
1609 value_iterator++; | 1569 value_iterator++; |
1610 input_index++; | 1570 input_index++; |
1611 // The receiver (and the implicit return value, if any) are expected in | 1571 // The receiver (and the implicit return value, if any) are expected in |
1612 // registers by the LoadIC/StoreIC, so they don't belong to the output stack | 1572 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
1613 // frame. This means that we have to use a height of 0. | 1573 // frame. This means that we have to use a height of 0. |
1614 unsigned height = 0; | 1574 unsigned height = 0; |
1615 unsigned height_in_bytes = height * kPointerSize; | 1575 unsigned height_in_bytes = height * kPointerSize; |
1616 const char* kind = is_setter_stub_frame ? "setter" : "getter"; | 1576 const char* kind = is_setter_stub_frame ? "setter" : "getter"; |
1617 if (trace_scope_ != NULL) { | 1577 if (trace_scope_ != NULL) { |
1618 PrintF(trace_scope_->file(), | 1578 PrintF(trace_scope_->file(), |
1619 " translating %s stub => height=%u\n", kind, height_in_bytes); | 1579 " translating %s stub => height=%u\n", kind, height_in_bytes); |
1620 } | 1580 } |
1621 | 1581 |
1622 // We need 1 stack entry for the return address and enough entries for the | 1582 // We need 1 stack entry for the return address and enough entries for the |
1623 // StackFrame::INTERNAL (FP, context, frame type, code object and constant | 1583 // StackFrame::INTERNAL (FP, context, frame type, code object and constant |
1624 // pool (if enabled)- see MacroAssembler::EnterFrame). | 1584 // pool (if enabled)- see MacroAssembler::EnterFrame). |
1625 // For a setter stub frame we need one additional entry for the implicit | 1585 // For a setter stub frame we need one additional entry for the implicit |
1626 // return value, see StoreStubCompiler::CompileStoreViaSetter. | 1586 // return value, see StoreStubCompiler::CompileStoreViaSetter. |
1627 unsigned fixed_frame_entries = | 1587 unsigned fixed_frame_entries = |
1628 (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 + | 1588 (StandardFrameConstants::kFixedFrameSize / kPointerSize) + 1 + |
1629 (is_setter_stub_frame ? 1 : 0); | 1589 (is_setter_stub_frame ? 1 : 0); |
1630 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; | 1590 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; |
1631 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 1591 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
1632 | 1592 |
1633 // Allocate and store the output frame description. | 1593 // Allocate and store the output frame description. |
1634 FrameDescription* output_frame = | 1594 FrameDescription* output_frame = |
1635 new(output_frame_size) FrameDescription(output_frame_size, accessor); | 1595 new (output_frame_size) FrameDescription(output_frame_size); |
1636 output_frame->SetFrameType(StackFrame::INTERNAL); | 1596 output_frame->SetFrameType(StackFrame::INTERNAL); |
1637 | 1597 |
1638 // A frame for an accessor stub can not be the topmost or bottommost one. | 1598 // A frame for an accessor stub can not be the topmost or bottommost one. |
1639 CHECK(frame_index > 0 && frame_index < output_count_ - 1); | 1599 CHECK(frame_index > 0 && frame_index < output_count_ - 1); |
1640 CHECK_NULL(output_[frame_index]); | 1600 CHECK_NULL(output_[frame_index]); |
1641 output_[frame_index] = output_frame; | 1601 output_[frame_index] = output_frame; |
1642 | 1602 |
1643 // The top address of the frame is computed from the previous frame's top and | 1603 // The top address of the frame is computed from the previous frame's top and |
1644 // this frame's size. | 1604 // this frame's size. |
1645 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 1605 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 int output_frame_size = height_in_bytes + fixed_frame_size; | 1744 int output_frame_size = height_in_bytes + fixed_frame_size; |
1785 if (trace_scope_ != NULL) { | 1745 if (trace_scope_ != NULL) { |
1786 PrintF(trace_scope_->file(), | 1746 PrintF(trace_scope_->file(), |
1787 " translating %s => StubFailureTrampolineStub, height=%d\n", | 1747 " translating %s => StubFailureTrampolineStub, height=%d\n", |
1788 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)), | 1748 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key)), |
1789 height_in_bytes); | 1749 height_in_bytes); |
1790 } | 1750 } |
1791 | 1751 |
1792 // The stub failure trampoline is a single frame. | 1752 // The stub failure trampoline is a single frame. |
1793 FrameDescription* output_frame = | 1753 FrameDescription* output_frame = |
1794 new(output_frame_size) FrameDescription(output_frame_size, NULL); | 1754 new (output_frame_size) FrameDescription(output_frame_size); |
1795 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); | 1755 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); |
1796 CHECK_EQ(frame_index, 0); | 1756 CHECK_EQ(frame_index, 0); |
1797 output_[frame_index] = output_frame; | 1757 output_[frame_index] = output_frame; |
1798 | 1758 |
1799 // The top address for the output frame can be computed from the input | 1759 // The top address for the output frame can be computed from the input |
1800 // frame pointer and the output frame's height. Subtract space for the | 1760 // frame pointer and the output frame's height. Subtract space for the |
1801 // context and function slots. | 1761 // context and function slots. |
1802 Register fp_reg = StubFailureTrampolineFrame::fp_register(); | 1762 Register fp_reg = StubFailureTrampolineFrame::fp_register(); |
1803 intptr_t top_address = input_->GetRegister(fp_reg.code()) - | 1763 intptr_t top_address = input_->GetRegister(fp_reg.code()) - |
1804 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes; | 1764 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 } | 1945 } |
1986 | 1946 |
1987 *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) = | 1947 *(reinterpret_cast<intptr_t*>(materialization.output_slot_address_)) = |
1988 reinterpret_cast<intptr_t>(*value); | 1948 reinterpret_cast<intptr_t>(*value); |
1989 } | 1949 } |
1990 | 1950 |
1991 isolate_->materialized_object_store()->Remove(stack_fp_); | 1951 isolate_->materialized_object_store()->Remove(stack_fp_); |
1992 } | 1952 } |
1993 | 1953 |
1994 | 1954 |
1995 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( | |
1996 int frame_index, int parameter_count, int expression_count, | |
1997 DeoptimizedFrameInfo* info) { | |
1998 CHECK_EQ(DEBUGGER, bailout_type_); | |
1999 | |
2000 translated_state_.Prepare(false, nullptr); | |
2001 | |
2002 TranslatedFrame* frame = &(translated_state_.frames()[frame_index]); | |
2003 CHECK(frame->kind() == TranslatedFrame::kFunction); | |
2004 int frame_arg_count = frame->shared_info()->internal_formal_parameter_count(); | |
2005 | |
2006 // The height is #expressions + 1 for context. | |
2007 CHECK_EQ(expression_count + 1, frame->height()); | |
2008 TranslatedFrame* argument_frame = frame; | |
2009 if (frame_index > 0) { | |
2010 TranslatedFrame* previous_frame = | |
2011 &(translated_state_.frames()[frame_index - 1]); | |
2012 if (previous_frame->kind() == TranslatedFrame::kArgumentsAdaptor) { | |
2013 argument_frame = previous_frame; | |
2014 CHECK_EQ(parameter_count, argument_frame->height() - 1); | |
2015 } else { | |
2016 CHECK_EQ(frame_arg_count, parameter_count); | |
2017 } | |
2018 } else { | |
2019 CHECK_EQ(frame_arg_count, parameter_count); | |
2020 } | |
2021 | |
2022 TranslatedFrame::iterator arg_iter = argument_frame->begin(); | |
2023 arg_iter++; // Skip the function. | |
2024 arg_iter++; // Skip the receiver. | |
2025 for (int i = 0; i < parameter_count; i++, arg_iter++) { | |
2026 if (!arg_iter->IsMaterializedObject()) { | |
2027 info->SetParameter(i, arg_iter->GetValue()); | |
2028 } | |
2029 } | |
2030 | |
2031 TranslatedFrame::iterator iter = frame->begin(); | |
2032 // Skip the function, receiver, context and arguments. | |
2033 for (int i = 0; i < frame_arg_count + 3; i++, iter++) { | |
2034 } | |
2035 | |
2036 for (int i = 0; i < expression_count; i++, iter++) { | |
2037 if (!iter->IsMaterializedObject()) { | |
2038 info->SetExpression(i, iter->GetValue()); | |
2039 } | |
2040 } | |
2041 } | |
2042 | |
2043 | |
2044 void Deoptimizer::WriteTranslatedValueToOutput( | 1955 void Deoptimizer::WriteTranslatedValueToOutput( |
2045 TranslatedFrame::iterator* iterator, int* input_index, int frame_index, | 1956 TranslatedFrame::iterator* iterator, int* input_index, int frame_index, |
2046 unsigned output_offset, const char* debug_hint_string, | 1957 unsigned output_offset, const char* debug_hint_string, |
2047 Address output_address_for_materialization) { | 1958 Address output_address_for_materialization) { |
2048 Object* value = (*iterator)->GetRawValue(); | 1959 Object* value = (*iterator)->GetRawValue(); |
2049 | 1960 |
2050 WriteValueToOutput(value, *input_index, frame_index, output_offset, | 1961 WriteValueToOutput(value, *input_index, frame_index, output_offset, |
2051 debug_hint_string); | 1962 debug_hint_string); |
2052 | 1963 |
2053 if (value == isolate_->heap()->arguments_marker()) { | 1964 if (value == isolate_->heap()->arguments_marker()) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 V8::FatalProcessOutOfMemory( | 2097 V8::FatalProcessOutOfMemory( |
2187 "Deoptimizer::EnsureCodeForDeoptimizationEntry"); | 2098 "Deoptimizer::EnsureCodeForDeoptimizationEntry"); |
2188 } | 2099 } |
2189 CopyBytes(chunk->area_start(), desc.buffer, | 2100 CopyBytes(chunk->area_start(), desc.buffer, |
2190 static_cast<size_t>(desc.instr_size)); | 2101 static_cast<size_t>(desc.instr_size)); |
2191 Assembler::FlushICache(isolate, chunk->area_start(), desc.instr_size); | 2102 Assembler::FlushICache(isolate, chunk->area_start(), desc.instr_size); |
2192 | 2103 |
2193 data->deopt_entry_code_entries_[type] = entry_count; | 2104 data->deopt_entry_code_entries_[type] = entry_count; |
2194 } | 2105 } |
2195 | 2106 |
2196 | 2107 FrameDescription::FrameDescription(uint32_t frame_size, int parameter_count) |
2197 FrameDescription::FrameDescription(uint32_t frame_size, | |
2198 JSFunction* function) | |
2199 : frame_size_(frame_size), | 2108 : frame_size_(frame_size), |
2200 function_(function), | 2109 parameter_count_(parameter_count), |
2201 top_(kZapUint32), | 2110 top_(kZapUint32), |
2202 pc_(kZapUint32), | 2111 pc_(kZapUint32), |
2203 fp_(kZapUint32), | 2112 fp_(kZapUint32), |
2204 context_(kZapUint32), | 2113 context_(kZapUint32), |
2205 constant_pool_(kZapUint32) { | 2114 constant_pool_(kZapUint32) { |
2206 // Zap all the registers. | 2115 // Zap all the registers. |
2207 for (int r = 0; r < Register::kNumRegisters; r++) { | 2116 for (int r = 0; r < Register::kNumRegisters; r++) { |
2208 // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register | 2117 // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register |
2209 // isn't used before the next safepoint, the GC will try to scan it as a | 2118 // isn't used before the next safepoint, the GC will try to scan it as a |
2210 // tagged value. kZapUint32 looks like a valid tagged pointer, but it isn't. | 2119 // tagged value. kZapUint32 looks like a valid tagged pointer, but it isn't. |
2211 SetRegister(r, kZapUint32); | 2120 SetRegister(r, kZapUint32); |
2212 } | 2121 } |
2213 | 2122 |
2214 // Zap all the slots. | 2123 // Zap all the slots. |
2215 for (unsigned o = 0; o < frame_size; o += kPointerSize) { | 2124 for (unsigned o = 0; o < frame_size; o += kPointerSize) { |
2216 SetFrameSlot(o, kZapUint32); | 2125 SetFrameSlot(o, kZapUint32); |
2217 } | 2126 } |
2218 } | 2127 } |
2219 | 2128 |
2220 | 2129 |
2221 int FrameDescription::ComputeFixedSize() { | 2130 int FrameDescription::ComputeFixedSize() { |
2222 if (type_ == StackFrame::INTERPRETED) { | 2131 if (type_ == StackFrame::INTERPRETED) { |
2223 return InterpreterFrameConstants::kFixedFrameSize + | 2132 return InterpreterFrameConstants::kFixedFrameSize + |
2224 (ComputeParametersCount() + 1) * kPointerSize; | 2133 parameter_count() * kPointerSize; |
2225 } else { | 2134 } else { |
2226 return StandardFrameConstants::kFixedFrameSize + | 2135 return StandardFrameConstants::kFixedFrameSize + |
2227 (ComputeParametersCount() + 1) * kPointerSize; | 2136 parameter_count() * kPointerSize; |
2228 } | 2137 } |
2229 } | 2138 } |
2230 | 2139 |
2231 | 2140 |
2232 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { | 2141 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) { |
2233 if (slot_index >= 0) { | 2142 if (slot_index >= 0) { |
2234 // Local or spill slots. Skip the fixed part of the frame | 2143 // Local or spill slots. Skip the fixed part of the frame |
2235 // including all arguments. | 2144 // including all arguments. |
2236 unsigned base = GetFrameSize() - ComputeFixedSize(); | 2145 unsigned base = GetFrameSize() - ComputeFixedSize(); |
2237 return base - ((slot_index + 1) * kPointerSize); | 2146 return base - ((slot_index + 1) * kPointerSize); |
2238 } else { | 2147 } else { |
2239 // Incoming parameter. | 2148 // Incoming parameter. |
2240 int arg_size = (ComputeParametersCount() + 1) * kPointerSize; | 2149 int arg_size = parameter_count() * kPointerSize; |
2241 unsigned base = GetFrameSize() - arg_size; | 2150 unsigned base = GetFrameSize() - arg_size; |
2242 return base - ((slot_index + 1) * kPointerSize); | 2151 return base - ((slot_index + 1) * kPointerSize); |
2243 } | 2152 } |
2244 } | 2153 } |
2245 | 2154 |
2246 | 2155 |
2247 int FrameDescription::ComputeParametersCount() { | |
2248 switch (type_) { | |
2249 case StackFrame::JAVA_SCRIPT: | |
2250 return function_->shared()->internal_formal_parameter_count(); | |
2251 case StackFrame::ARGUMENTS_ADAPTOR: { | |
2252 // Last slot contains number of incomming arguments as a smi. | |
2253 // Can't use GetExpression(0) because it would cause infinite recursion. | |
2254 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value(); | |
2255 } | |
2256 case StackFrame::STUB: | |
2257 return -1; // Minus receiver. | |
2258 default: | |
2259 FATAL("Unexpected stack frame type"); | |
2260 return 0; | |
2261 } | |
2262 } | |
2263 | |
2264 | |
2265 Object* FrameDescription::GetParameter(int index) { | |
2266 CHECK_GE(index, 0); | |
2267 CHECK_LT(index, ComputeParametersCount()); | |
2268 // The slot indexes for incoming arguments are negative. | |
2269 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount()); | |
2270 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); | |
2271 } | |
2272 | |
2273 | |
2274 unsigned FrameDescription::GetExpressionCount() { | |
2275 CHECK_EQ(StackFrame::JAVA_SCRIPT, type_); | |
2276 unsigned size = GetFrameSize() - ComputeFixedSize(); | |
2277 return size / kPointerSize; | |
2278 } | |
2279 | |
2280 | |
2281 Object* FrameDescription::GetExpression(int index) { | |
2282 DCHECK_EQ(StackFrame::JAVA_SCRIPT, type_); | |
2283 unsigned offset = GetOffsetFromSlotIndex(index); | |
2284 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); | |
2285 } | |
2286 | |
2287 | |
2288 void TranslationBuffer::Add(int32_t value, Zone* zone) { | 2156 void TranslationBuffer::Add(int32_t value, Zone* zone) { |
2289 // This wouldn't handle kMinInt correctly if it ever encountered it. | 2157 // This wouldn't handle kMinInt correctly if it ever encountered it. |
2290 DCHECK(value != kMinInt); | 2158 DCHECK(value != kMinInt); |
2291 // Encode the sign bit in the least significant bit. | 2159 // Encode the sign bit in the least significant bit. |
2292 bool is_negative = (value < 0); | 2160 bool is_negative = (value < 0); |
2293 uint32_t bits = ((is_negative ? -value : value) << 1) | | 2161 uint32_t bits = ((is_negative ? -value : value) << 1) | |
2294 static_cast<int32_t>(is_negative); | 2162 static_cast<int32_t>(is_negative); |
2295 // Encode the individual bytes using the least significant bit of | 2163 // Encode the individual bytes using the least significant bit of |
2296 // each byte to indicate whether or not more bytes follow. | 2164 // each byte to indicate whether or not more bytes follow. |
2297 do { | 2165 do { |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2599 for (int i = 0; i < array->length(); i++) { | 2467 for (int i = 0; i < array->length(); i++) { |
2600 new_array->set(i, array->get(i)); | 2468 new_array->set(i, array->get(i)); |
2601 } | 2469 } |
2602 for (int i = array->length(); i < length; i++) { | 2470 for (int i = array->length(); i < length; i++) { |
2603 new_array->set(i, isolate()->heap()->undefined_value()); | 2471 new_array->set(i, isolate()->heap()->undefined_value()); |
2604 } | 2472 } |
2605 isolate()->heap()->SetRootMaterializedObjects(*new_array); | 2473 isolate()->heap()->SetRootMaterializedObjects(*new_array); |
2606 return new_array; | 2474 return new_array; |
2607 } | 2475 } |
2608 | 2476 |
| 2477 namespace { |
2609 | 2478 |
2610 DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer, | 2479 Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it, |
2611 int frame_index, | 2480 Isolate* isolate) { |
2612 bool has_arguments_adaptor, | 2481 if (it->GetRawValue() == isolate->heap()->arguments_marker()) { |
2613 bool has_construct_stub) { | 2482 if (!it->IsMaterializableByDebugger()) { |
2614 FrameDescription* output_frame = deoptimizer->output_[frame_index]; | 2483 return isolate->factory()->undefined_value(); |
2615 function_ = | 2484 } |
2616 Handle<JSFunction>(output_frame->GetFunction(), deoptimizer->isolate()); | 2485 } |
2617 context_ = | 2486 return it->GetValue(); |
2618 Handle<Object>(reinterpret_cast<Object*>(output_frame->GetContext()), | 2487 } |
2619 deoptimizer->isolate()); | |
2620 has_construct_stub_ = has_construct_stub; | |
2621 expression_stack_.resize( | |
2622 static_cast<size_t>(output_frame->GetExpressionCount())); | |
2623 // Get the source position using the unoptimized code. | |
2624 Address pc = reinterpret_cast<Address>(output_frame->GetPc()); | |
2625 Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc)); | |
2626 int offset = static_cast<int>(pc - code->instruction_start()); | |
2627 source_position_ = code->SourcePosition(offset); | |
2628 | 2488 |
2629 for (int i = 0; i < static_cast<int>(expression_count()); i++) { | 2489 int ComputeSourcePosition(Handle<SharedFunctionInfo> shared, |
2630 Object* value = output_frame->GetExpression(i); | 2490 BailoutId node_id) { |
2631 // Replace materialization markers with the undefined value. | 2491 if (shared->HasBytecodeArray()) { |
2632 if (value == deoptimizer->isolate()->heap()->arguments_marker()) { | 2492 BytecodeArray* bytecodes = shared->bytecode_array(); |
2633 value = deoptimizer->isolate()->heap()->undefined_value(); | 2493 return bytecodes->SourcePosition(node_id.ToInt()); |
2634 } | 2494 } else { |
2635 SetExpression(i, Handle<Object>(value, deoptimizer->isolate())); | 2495 Code* non_optimized_code = shared->code(); |
2636 } | 2496 FixedArray* raw_data = non_optimized_code->deoptimization_data(); |
2637 | 2497 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); |
2638 if (has_arguments_adaptor) { | 2498 unsigned pc_and_state = Deoptimizer::GetOutputInfo(data, node_id, *shared); |
2639 output_frame = deoptimizer->output_[frame_index - 1]; | 2499 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); |
2640 CHECK_EQ(output_frame->GetFrameType(), StackFrame::ARGUMENTS_ADAPTOR); | 2500 return non_optimized_code->SourcePosition(pc_offset); |
2641 } | |
2642 | |
2643 parameters_.resize( | |
2644 static_cast<size_t>(output_frame->ComputeParametersCount())); | |
2645 for (int i = 0; i < output_frame->ComputeParametersCount(); i++) { | |
2646 Object* value = output_frame->GetParameter(i); | |
2647 // Replace materialization markers with the undefined value. | |
2648 if (value == deoptimizer->isolate()->heap()->arguments_marker()) { | |
2649 value = deoptimizer->isolate()->heap()->undefined_value(); | |
2650 } | |
2651 SetParameter(i, Handle<Object>(value, deoptimizer->isolate())); | |
2652 } | 2501 } |
2653 } | 2502 } |
2654 | 2503 |
| 2504 } // namespace |
2655 | 2505 |
| 2506 DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state, |
| 2507 TranslatedState::iterator frame_it, |
| 2508 Isolate* isolate) { |
| 2509 // If the previous frame is an adaptor frame, we will take the parameters |
| 2510 // from there. |
| 2511 TranslatedState::iterator parameter_frame = frame_it; |
| 2512 if (parameter_frame != state->begin()) { |
| 2513 parameter_frame--; |
| 2514 } |
| 2515 int parameter_count; |
| 2516 if (parameter_frame->kind() == TranslatedFrame::kArgumentsAdaptor) { |
| 2517 parameter_count = parameter_frame->height() - 1; // Ignore the receiver. |
| 2518 } else { |
| 2519 parameter_frame = frame_it; |
| 2520 parameter_count = |
| 2521 frame_it->shared_info()->internal_formal_parameter_count(); |
| 2522 } |
| 2523 TranslatedFrame::iterator parameter_it = parameter_frame->begin(); |
| 2524 parameter_it++; // Skip the function. |
| 2525 parameter_it++; // Skip the receiver. |
| 2526 |
| 2527 // Figure out whether there is a construct stub frame on top of |
| 2528 // the parameter frame. |
| 2529 has_construct_stub_ = |
| 2530 parameter_frame != state->begin() && |
| 2531 (parameter_frame - 1)->kind() == TranslatedFrame::kConstructStub; |
| 2532 |
| 2533 source_position_ = |
| 2534 ComputeSourcePosition(frame_it->shared_info(), frame_it->node_id()); |
| 2535 |
| 2536 TranslatedFrame::iterator value_it = frame_it->begin(); |
| 2537 // Get the function. Note that this might materialize the function. |
| 2538 // In case the debugger mutates this value, we should deoptimize |
| 2539 // the function and remember the value in the materialized value store. |
| 2540 function_ = Handle<JSFunction>::cast(value_it->GetValue()); |
| 2541 |
| 2542 parameters_.resize(static_cast<size_t>(parameter_count)); |
| 2543 for (int i = 0; i < parameter_count; i++) { |
| 2544 Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate); |
| 2545 SetParameter(i, parameter); |
| 2546 parameter_it++; |
| 2547 } |
| 2548 |
| 2549 // Skip the function, the receiver and the arguments. |
| 2550 int skip_count = |
| 2551 frame_it->shared_info()->internal_formal_parameter_count() + 2; |
| 2552 TranslatedFrame::iterator stack_it = frame_it->begin(); |
| 2553 for (int i = 0; i < skip_count; i++) { |
| 2554 stack_it++; |
| 2555 } |
| 2556 |
| 2557 // Get the context. |
| 2558 context_ = GetValueForDebugger(stack_it, isolate); |
| 2559 stack_it++; |
| 2560 |
| 2561 // Get the expression stack. |
| 2562 int stack_height = frame_it->height(); |
| 2563 if (frame_it->kind() == TranslatedFrame::kFunction) { |
| 2564 // For full-code frames, we should not count the context. |
| 2565 // TODO(jarin): Clean up the indexing in translated frames. |
| 2566 stack_height--; |
| 2567 } |
| 2568 expression_stack_.resize(static_cast<size_t>(stack_height)); |
| 2569 for (int i = 0; i < stack_height; i++) { |
| 2570 Handle<Object> expression = GetValueForDebugger(stack_it, isolate); |
| 2571 SetExpression(i, expression); |
| 2572 stack_it++; |
| 2573 } |
| 2574 |
| 2575 // For interpreter frame, skip the accumulator. |
| 2576 if (parameter_frame->kind() == TranslatedFrame::kInterpretedFunction) { |
| 2577 stack_it++; |
| 2578 } |
| 2579 CHECK(stack_it == frame_it->end()); |
| 2580 } |
| 2581 |
| 2582 |
2656 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { | 2583 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { |
2657 DCHECK(deopt_reason < kLastDeoptReason); | 2584 DCHECK(deopt_reason < kLastDeoptReason); |
2658 #define DEOPT_MESSAGES_TEXTS(C, T) T, | 2585 #define DEOPT_MESSAGES_TEXTS(C, T) T, |
2659 static const char* deopt_messages_[] = { | 2586 static const char* deopt_messages_[] = { |
2660 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; | 2587 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; |
2661 #undef DEOPT_MESSAGES_TEXTS | 2588 #undef DEOPT_MESSAGES_TEXTS |
2662 return deopt_messages_[deopt_reason]; | 2589 return deopt_messages_[deopt_reason]; |
2663 } | 2590 } |
2664 | 2591 |
2665 | 2592 |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2922 switch (kind()) { | 2849 switch (kind()) { |
2923 case kCapturedObject: | 2850 case kCapturedObject: |
2924 case kDuplicatedObject: | 2851 case kDuplicatedObject: |
2925 case kArgumentsObject: | 2852 case kArgumentsObject: |
2926 return true; | 2853 return true; |
2927 default: | 2854 default: |
2928 return false; | 2855 return false; |
2929 } | 2856 } |
2930 } | 2857 } |
2931 | 2858 |
| 2859 bool TranslatedValue::IsMaterializableByDebugger() const { |
| 2860 // At the moment, we only allow materialization of doubles. |
| 2861 return (kind() == kDouble); |
| 2862 } |
2932 | 2863 |
2933 int TranslatedValue::GetChildrenCount() const { | 2864 int TranslatedValue::GetChildrenCount() const { |
2934 if (kind() == kCapturedObject || kind() == kArgumentsObject) { | 2865 if (kind() == kCapturedObject || kind() == kArgumentsObject) { |
2935 return object_length(); | 2866 return object_length(); |
2936 } else { | 2867 } else { |
2937 return 0; | 2868 return 0; |
2938 } | 2869 } |
2939 } | 2870 } |
2940 | 2871 |
2941 | 2872 |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3470 stack_frame_pointer_ = stack_frame_pointer; | 3401 stack_frame_pointer_ = stack_frame_pointer; |
3471 has_adapted_arguments_ = has_adapted_arguments; | 3402 has_adapted_arguments_ = has_adapted_arguments; |
3472 | 3403 |
3473 UpdateFromPreviouslyMaterializedObjects(); | 3404 UpdateFromPreviouslyMaterializedObjects(); |
3474 } | 3405 } |
3475 | 3406 |
3476 | 3407 |
3477 Handle<Object> TranslatedState::MaterializeAt(int frame_index, | 3408 Handle<Object> TranslatedState::MaterializeAt(int frame_index, |
3478 int* value_index) { | 3409 int* value_index) { |
3479 TranslatedFrame* frame = &(frames_[frame_index]); | 3410 TranslatedFrame* frame = &(frames_[frame_index]); |
3480 DCHECK(static_cast<size_t>(*value_index) < frame->values_.size()); | 3411 CHECK(static_cast<size_t>(*value_index) < frame->values_.size()); |
3481 | 3412 |
3482 TranslatedValue* slot = &(frame->values_[*value_index]); | 3413 TranslatedValue* slot = &(frame->values_[*value_index]); |
3483 (*value_index)++; | 3414 (*value_index)++; |
3484 | 3415 |
3485 switch (slot->kind()) { | 3416 switch (slot->kind()) { |
3486 case TranslatedValue::kTagged: | 3417 case TranslatedValue::kTagged: |
3487 case TranslatedValue::kInt32: | 3418 case TranslatedValue::kInt32: |
3488 case TranslatedValue::kUInt32: | 3419 case TranslatedValue::kUInt32: |
3489 case TranslatedValue::kBoolBit: | 3420 case TranslatedValue::kBoolBit: |
3490 case TranslatedValue::kDouble: { | 3421 case TranslatedValue::kDouble: { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3626 } | 3557 } |
3627 UNREACHABLE(); | 3558 UNREACHABLE(); |
3628 break; | 3559 break; |
3629 } | 3560 } |
3630 | 3561 |
3631 case TranslatedValue::kDuplicatedObject: { | 3562 case TranslatedValue::kDuplicatedObject: { |
3632 int object_index = slot->object_index(); | 3563 int object_index = slot->object_index(); |
3633 TranslatedState::ObjectPosition pos = object_positions_[object_index]; | 3564 TranslatedState::ObjectPosition pos = object_positions_[object_index]; |
3634 | 3565 |
3635 // Make sure the duplicate is refering to a previous object. | 3566 // Make sure the duplicate is refering to a previous object. |
3636 DCHECK(pos.frame_index_ < frame_index || | 3567 CHECK(pos.frame_index_ < frame_index || |
3637 (pos.frame_index_ == frame_index && | 3568 (pos.frame_index_ == frame_index && |
3638 pos.value_index_ < *value_index - 1)); | 3569 pos.value_index_ < *value_index - 1)); |
3639 | 3570 |
3640 Handle<Object> object = | 3571 Handle<Object> object = |
3641 frames_[pos.frame_index_].values_[pos.value_index_].GetValue(); | 3572 frames_[pos.frame_index_].values_[pos.value_index_].GetValue(); |
3642 | 3573 |
3643 // The object should have a (non-sentinel) value. | 3574 // The object should have a (non-sentinel) value. |
3644 DCHECK(!object.is_null() && | 3575 CHECK(!object.is_null() && |
3645 !object.is_identical_to(isolate_->factory()->arguments_marker())); | 3576 !object.is_identical_to(isolate_->factory()->arguments_marker())); |
3646 | 3577 |
3647 slot->value_ = object; | 3578 slot->value_ = object; |
3648 return object; | 3579 return object; |
3649 } | 3580 } |
3650 | 3581 |
3651 case TranslatedValue::kInvalid: | 3582 case TranslatedValue::kInvalid: |
3652 UNREACHABLE(); | 3583 UNREACHABLE(); |
3653 break; | 3584 break; |
3654 } | 3585 } |
3655 | 3586 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3739 bool new_store = false; | 3670 bool new_store = false; |
3740 if (previously_materialized_objects.is_null()) { | 3671 if (previously_materialized_objects.is_null()) { |
3741 previously_materialized_objects = | 3672 previously_materialized_objects = |
3742 isolate_->factory()->NewFixedArray(length); | 3673 isolate_->factory()->NewFixedArray(length); |
3743 for (int i = 0; i < length; i++) { | 3674 for (int i = 0; i < length; i++) { |
3744 previously_materialized_objects->set(i, *marker); | 3675 previously_materialized_objects->set(i, *marker); |
3745 } | 3676 } |
3746 new_store = true; | 3677 new_store = true; |
3747 } | 3678 } |
3748 | 3679 |
3749 DCHECK_EQ(length, previously_materialized_objects->length()); | 3680 CHECK_EQ(length, previously_materialized_objects->length()); |
3750 | 3681 |
3751 bool value_changed = false; | 3682 bool value_changed = false; |
3752 for (int i = 0; i < length; i++) { | 3683 for (int i = 0; i < length; i++) { |
3753 TranslatedState::ObjectPosition pos = object_positions_[i]; | 3684 TranslatedState::ObjectPosition pos = object_positions_[i]; |
3754 TranslatedValue* value_info = | 3685 TranslatedValue* value_info = |
3755 &(frames_[pos.frame_index_].values_[pos.value_index_]); | 3686 &(frames_[pos.frame_index_].values_[pos.value_index_]); |
3756 | 3687 |
3757 DCHECK(value_info->IsMaterializedObject()); | 3688 CHECK(value_info->IsMaterializedObject()); |
3758 | 3689 |
3759 Handle<Object> value(value_info->GetRawValue(), isolate_); | 3690 Handle<Object> value(value_info->GetRawValue(), isolate_); |
3760 | 3691 |
3761 if (!value.is_identical_to(marker)) { | 3692 if (!value.is_identical_to(marker)) { |
3762 if (previously_materialized_objects->get(i) == *marker) { | 3693 if (previously_materialized_objects->get(i) == *marker) { |
3763 previously_materialized_objects->set(i, *value); | 3694 previously_materialized_objects->set(i, *value); |
3764 value_changed = true; | 3695 value_changed = true; |
3765 } else { | 3696 } else { |
3766 DCHECK(previously_materialized_objects->get(i) == *value); | 3697 CHECK(previously_materialized_objects->get(i) == *value); |
3767 } | 3698 } |
3768 } | 3699 } |
3769 } | 3700 } |
3770 if (new_store && value_changed) { | 3701 if (new_store && value_changed) { |
3771 materialized_store->Set(stack_frame_pointer_, | 3702 materialized_store->Set(stack_frame_pointer_, |
3772 previously_materialized_objects); | 3703 previously_materialized_objects); |
3773 DCHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind()); | 3704 CHECK_EQ(TranslatedFrame::kFunction, frames_[0].kind()); |
3774 Object* const function = frames_[0].front().GetRawValue(); | 3705 Object* const function = frames_[0].front().GetRawValue(); |
3775 Deoptimizer::DeoptimizeFunction(JSFunction::cast(function)); | 3706 Deoptimizer::DeoptimizeFunction(JSFunction::cast(function)); |
3776 } | 3707 } |
3777 } | 3708 } |
3778 | 3709 |
3779 | 3710 |
3780 void TranslatedState::UpdateFromPreviouslyMaterializedObjects() { | 3711 void TranslatedState::UpdateFromPreviouslyMaterializedObjects() { |
3781 MaterializedObjectStore* materialized_store = | 3712 MaterializedObjectStore* materialized_store = |
3782 isolate_->materialized_object_store(); | 3713 isolate_->materialized_object_store(); |
3783 Handle<FixedArray> previously_materialized_objects = | 3714 Handle<FixedArray> previously_materialized_objects = |
3784 materialized_store->Get(stack_frame_pointer_); | 3715 materialized_store->Get(stack_frame_pointer_); |
3785 | 3716 |
3786 // If we have no previously materialized objects, there is nothing to do. | 3717 // If we have no previously materialized objects, there is nothing to do. |
3787 if (previously_materialized_objects.is_null()) return; | 3718 if (previously_materialized_objects.is_null()) return; |
3788 | 3719 |
3789 Handle<Object> marker = isolate_->factory()->arguments_marker(); | 3720 Handle<Object> marker = isolate_->factory()->arguments_marker(); |
3790 | 3721 |
3791 int length = static_cast<int>(object_positions_.size()); | 3722 int length = static_cast<int>(object_positions_.size()); |
3792 DCHECK_EQ(length, previously_materialized_objects->length()); | 3723 CHECK_EQ(length, previously_materialized_objects->length()); |
3793 | 3724 |
3794 for (int i = 0; i < length; i++) { | 3725 for (int i = 0; i < length; i++) { |
3795 // For a previously materialized objects, inject their value into the | 3726 // For a previously materialized objects, inject their value into the |
3796 // translated values. | 3727 // translated values. |
3797 if (previously_materialized_objects->get(i) != *marker) { | 3728 if (previously_materialized_objects->get(i) != *marker) { |
3798 TranslatedState::ObjectPosition pos = object_positions_[i]; | 3729 TranslatedState::ObjectPosition pos = object_positions_[i]; |
3799 TranslatedValue* value_info = | 3730 TranslatedValue* value_info = |
3800 &(frames_[pos.frame_index_].values_[pos.value_index_]); | 3731 &(frames_[pos.frame_index_].values_[pos.value_index_]); |
3801 DCHECK(value_info->IsMaterializedObject()); | 3732 CHECK(value_info->IsMaterializedObject()); |
3802 | 3733 |
3803 value_info->value_ = | 3734 value_info->value_ = |
3804 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3735 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3805 } | 3736 } |
3806 } | 3737 } |
3807 } | 3738 } |
3808 | 3739 |
3809 } // namespace internal | 3740 } // namespace internal |
3810 } // namespace v8 | 3741 } // namespace v8 |
OLD | NEW |