Chromium Code Reviews| 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 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 DCHECK(parameter_count == parameters_count()); | |
|
Benedikt Meurer
2016/02/15 05:48:26
Nit: Remove this useless DCHECK.
Jarin
2016/02/15 06:53:54
Done.
| |
| 2544 for (int i = 0; i < parameter_count; i++) { | |
| 2545 Handle<Object> parameter = GetValueForDebugger(parameter_it, isolate); | |
| 2546 SetParameter(i, parameter); | |
| 2547 parameter_it++; | |
| 2548 } | |
| 2549 | |
| 2550 // Skip the function, the receiver and the arguments. | |
| 2551 int skip_count = | |
| 2552 frame_it->shared_info()->internal_formal_parameter_count() + 2; | |
| 2553 TranslatedFrame::iterator stack_it = frame_it->begin(); | |
| 2554 for (int i = 0; i < skip_count; i++) { | |
| 2555 stack_it++; | |
| 2556 } | |
| 2557 | |
| 2558 // Get the context. | |
| 2559 context_ = GetValueForDebugger(stack_it, isolate); | |
| 2560 stack_it++; | |
| 2561 | |
| 2562 // Get the expression stack. | |
| 2563 int stack_height = frame_it->height(); | |
| 2564 if (frame_it->kind() == TranslatedFrame::kFunction) { | |
| 2565 // For full-code frames, we should not count the context. | |
| 2566 // TODO(jarin): Clean up the indexing in translated frames. | |
| 2567 stack_height--; | |
| 2568 } | |
| 2569 expression_stack_.resize(static_cast<size_t>(stack_height)); | |
| 2570 for (int i = 0; i < stack_height; i++) { | |
| 2571 Handle<Object> expression = GetValueForDebugger(stack_it, isolate); | |
| 2572 SetExpression(i, expression); | |
| 2573 stack_it++; | |
| 2574 } | |
| 2575 | |
| 2576 // For interpreter frame, skip the accumulator. | |
| 2577 if (parameter_frame->kind() == TranslatedFrame::kInterpretedFunction) { | |
| 2578 stack_it++; | |
| 2579 } | |
| 2580 DCHECK(stack_it == frame_it->end()); | |
|
Benedikt Meurer
2016/02/15 05:48:26
Nit: Please use a CHECK here.
Jarin
2016/02/15 06:53:54
Done.
| |
| 2581 } | |
| 2582 | |
| 2583 | |
| 2656 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { | 2584 const char* Deoptimizer::GetDeoptReason(DeoptReason deopt_reason) { |
| 2657 DCHECK(deopt_reason < kLastDeoptReason); | 2585 DCHECK(deopt_reason < kLastDeoptReason); |
| 2658 #define DEOPT_MESSAGES_TEXTS(C, T) T, | 2586 #define DEOPT_MESSAGES_TEXTS(C, T) T, |
| 2659 static const char* deopt_messages_[] = { | 2587 static const char* deopt_messages_[] = { |
| 2660 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; | 2588 DEOPT_MESSAGES_LIST(DEOPT_MESSAGES_TEXTS)}; |
| 2661 #undef DEOPT_MESSAGES_TEXTS | 2589 #undef DEOPT_MESSAGES_TEXTS |
| 2662 return deopt_messages_[deopt_reason]; | 2590 return deopt_messages_[deopt_reason]; |
| 2663 } | 2591 } |
| 2664 | 2592 |
| 2665 | 2593 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2922 switch (kind()) { | 2850 switch (kind()) { |
| 2923 case kCapturedObject: | 2851 case kCapturedObject: |
| 2924 case kDuplicatedObject: | 2852 case kDuplicatedObject: |
| 2925 case kArgumentsObject: | 2853 case kArgumentsObject: |
| 2926 return true; | 2854 return true; |
| 2927 default: | 2855 default: |
| 2928 return false; | 2856 return false; |
| 2929 } | 2857 } |
| 2930 } | 2858 } |
| 2931 | 2859 |
| 2860 bool TranslatedValue::IsMaterializableByDebugger() const { | |
| 2861 // At the moment, we only allow materialization of doubles. | |
| 2862 return (kind() == kDouble); | |
| 2863 } | |
| 2932 | 2864 |
| 2933 int TranslatedValue::GetChildrenCount() const { | 2865 int TranslatedValue::GetChildrenCount() const { |
| 2934 if (kind() == kCapturedObject || kind() == kArgumentsObject) { | 2866 if (kind() == kCapturedObject || kind() == kArgumentsObject) { |
| 2935 return object_length(); | 2867 return object_length(); |
| 2936 } else { | 2868 } else { |
| 2937 return 0; | 2869 return 0; |
| 2938 } | 2870 } |
| 2939 } | 2871 } |
| 2940 | 2872 |
| 2941 | 2873 |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3801 DCHECK(value_info->IsMaterializedObject()); | 3733 DCHECK(value_info->IsMaterializedObject()); |
| 3802 | 3734 |
| 3803 value_info->value_ = | 3735 value_info->value_ = |
| 3804 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3736 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
| 3805 } | 3737 } |
| 3806 } | 3738 } |
| 3807 } | 3739 } |
| 3808 | 3740 |
| 3809 } // namespace internal | 3741 } // namespace internal |
| 3810 } // namespace v8 | 3742 } // namespace v8 |
| OLD | NEW |