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

Side by Side Diff: src/deoptimizer.cc

Issue 1698743002: Make the frame inspector use TranslatedState rather than the full deoptimizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address review comments, changed some DCHECKs to CHECKs Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/deoptimizer.h" 5 #include "src/deoptimizer.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/ast/prettyprinter.h" 8 #include "src/ast/prettyprinter.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/disasm.h" 10 #include "src/disasm.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/ia32/deoptimizer-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698