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

Side by Side Diff: src/deoptimizer.cc

Issue 225283006: Fix materialization of accessor frames with captured receivers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 #endif 84 #endif
85 85
86 86
87 Code* Deoptimizer::FindDeoptimizingCode(Address addr) { 87 Code* Deoptimizer::FindDeoptimizingCode(Address addr) {
88 if (function_->IsHeapObject()) { 88 if (function_->IsHeapObject()) {
89 // Search all deoptimizing code in the native context of the function. 89 // Search all deoptimizing code in the native context of the function.
90 Context* native_context = function_->context()->native_context(); 90 Context* native_context = function_->context()->native_context();
91 Object* element = native_context->DeoptimizedCodeListHead(); 91 Object* element = native_context->DeoptimizedCodeListHead();
92 while (!element->IsUndefined()) { 92 while (!element->IsUndefined()) {
93 Code* code = Code::cast(element); 93 Code* code = Code::cast(element);
94 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 94 CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
95 if (code->contains(addr)) return code; 95 if (code->contains(addr)) return code;
96 element = code->next_code_link(); 96 element = code->next_code_link();
97 } 97 }
98 } 98 }
99 return NULL; 99 return NULL;
100 } 100 }
101 101
102 102
103 // We rely on this function not causing a GC. It is called from generated code 103 // We rely on this function not causing a GC. It is called from generated code
104 // without having a real stack frame in place. 104 // without having a real stack frame in place.
105 Deoptimizer* Deoptimizer::New(JSFunction* function, 105 Deoptimizer* Deoptimizer::New(JSFunction* function,
106 BailoutType type, 106 BailoutType type,
107 unsigned bailout_id, 107 unsigned bailout_id,
108 Address from, 108 Address from,
109 int fp_to_sp_delta, 109 int fp_to_sp_delta,
110 Isolate* isolate) { 110 Isolate* isolate) {
111 Deoptimizer* deoptimizer = new Deoptimizer(isolate, 111 Deoptimizer* deoptimizer = new Deoptimizer(isolate,
112 function, 112 function,
113 type, 113 type,
114 bailout_id, 114 bailout_id,
115 from, 115 from,
116 fp_to_sp_delta, 116 fp_to_sp_delta,
117 NULL); 117 NULL);
118 ASSERT(isolate->deoptimizer_data()->current_ == NULL); 118 CHECK(isolate->deoptimizer_data()->current_ == NULL);
119 isolate->deoptimizer_data()->current_ = deoptimizer; 119 isolate->deoptimizer_data()->current_ = deoptimizer;
120 return deoptimizer; 120 return deoptimizer;
121 } 121 }
122 122
123 123
124 // No larger than 2K on all platforms 124 // No larger than 2K on all platforms
125 static const int kDeoptTableMaxEpilogueCodeSize = 2 * KB; 125 static const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
126 126
127 127
128 size_t Deoptimizer::GetMaxDeoptTableSize() { 128 size_t Deoptimizer::GetMaxDeoptTableSize() {
129 int entries_size = 129 int entries_size =
130 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_; 130 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
131 int commit_page_size = static_cast<int>(OS::CommitPageSize()); 131 int commit_page_size = static_cast<int>(OS::CommitPageSize());
132 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) / 132 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
133 commit_page_size) + 1; 133 commit_page_size) + 1;
134 return static_cast<size_t>(commit_page_size * page_count); 134 return static_cast<size_t>(commit_page_size * page_count);
135 } 135 }
136 136
137 137
138 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { 138 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
139 Deoptimizer* result = isolate->deoptimizer_data()->current_; 139 Deoptimizer* result = isolate->deoptimizer_data()->current_;
140 ASSERT(result != NULL); 140 CHECK_NE(result, NULL);
141 result->DeleteFrameDescriptions(); 141 result->DeleteFrameDescriptions();
142 isolate->deoptimizer_data()->current_ = NULL; 142 isolate->deoptimizer_data()->current_ = NULL;
143 return result; 143 return result;
144 } 144 }
145 145
146 146
147 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) { 147 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
148 if (jsframe_index == 0) return 0; 148 if (jsframe_index == 0) return 0;
149 149
150 int frame_index = 0; 150 int frame_index = 0;
151 while (jsframe_index >= 0) { 151 while (jsframe_index >= 0) {
152 FrameDescription* frame = output_[frame_index]; 152 FrameDescription* frame = output_[frame_index];
153 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) { 153 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) {
154 jsframe_index--; 154 jsframe_index--;
155 } 155 }
156 frame_index++; 156 frame_index++;
157 } 157 }
158 158
159 return frame_index - 1; 159 return frame_index - 1;
160 } 160 }
161 161
162 162
163 #ifdef ENABLE_DEBUGGER_SUPPORT 163 #ifdef ENABLE_DEBUGGER_SUPPORT
164 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( 164 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
165 JavaScriptFrame* frame, 165 JavaScriptFrame* frame,
166 int jsframe_index, 166 int jsframe_index,
167 Isolate* isolate) { 167 Isolate* isolate) {
168 ASSERT(frame->is_optimized()); 168 CHECK(frame->is_optimized());
169 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL); 169 CHECK(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
170 170
171 // Get the function and code from the frame. 171 // Get the function and code from the frame.
172 JSFunction* function = frame->function(); 172 JSFunction* function = frame->function();
173 Code* code = frame->LookupCode(); 173 Code* code = frame->LookupCode();
174 174
175 // Locate the deoptimization point in the code. As we are at a call the 175 // Locate the deoptimization point in the code. As we are at a call the
176 // return address must be at a place in the code with deoptimization support. 176 // return address must be at a place in the code with deoptimization support.
177 SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc()); 177 SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
178 int deoptimization_index = safepoint_entry.deoptimization_index(); 178 int deoptimization_index = safepoint_entry.deoptimization_index();
179 ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex); 179 CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex);
180 180
181 // Always use the actual stack slots when calculating the fp to sp 181 // Always use the actual stack slots when calculating the fp to sp
182 // delta adding two for the function and context. 182 // delta adding two for the function and context.
183 unsigned stack_slots = code->stack_slots(); 183 unsigned stack_slots = code->stack_slots();
184 unsigned fp_to_sp_delta = (stack_slots * kPointerSize) + 184 unsigned fp_to_sp_delta = (stack_slots * kPointerSize) +
185 StandardFrameConstants::kFixedFrameSizeFromFp; 185 StandardFrameConstants::kFixedFrameSizeFromFp;
186 186
187 Deoptimizer* deoptimizer = new Deoptimizer(isolate, 187 Deoptimizer* deoptimizer = new Deoptimizer(isolate,
188 function, 188 function,
189 Deoptimizer::DEBUGGER, 189 Deoptimizer::DEBUGGER,
190 deoptimization_index, 190 deoptimization_index,
191 frame->pc(), 191 frame->pc(),
192 fp_to_sp_delta, 192 fp_to_sp_delta,
193 code); 193 code);
194 Address tos = frame->fp() - fp_to_sp_delta; 194 Address tos = frame->fp() - fp_to_sp_delta;
195 deoptimizer->FillInputFrame(tos, frame); 195 deoptimizer->FillInputFrame(tos, frame);
196 196
197 // Calculate the output frames. 197 // Calculate the output frames.
198 Deoptimizer::ComputeOutputFrames(deoptimizer); 198 Deoptimizer::ComputeOutputFrames(deoptimizer);
199 199
200 // Create the GC safe output frame information and register it for GC 200 // Create the GC safe output frame information and register it for GC
201 // handling. 201 // handling.
202 ASSERT_LT(jsframe_index, deoptimizer->jsframe_count()); 202 CHECK_LT(jsframe_index, deoptimizer->jsframe_count());
203 203
204 // Convert JS frame index into frame index. 204 // Convert JS frame index into frame index.
205 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index); 205 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
206 206
207 bool has_arguments_adaptor = 207 bool has_arguments_adaptor =
208 frame_index > 0 && 208 frame_index > 0 &&
209 deoptimizer->output_[frame_index - 1]->GetFrameType() == 209 deoptimizer->output_[frame_index - 1]->GetFrameType() ==
210 StackFrame::ARGUMENTS_ADAPTOR; 210 StackFrame::ARGUMENTS_ADAPTOR;
211 211
212 int construct_offset = has_arguments_adaptor ? 2 : 1; 212 int construct_offset = has_arguments_adaptor ? 2 : 1;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 244
245 // Finished using the deoptimizer instance. 245 // Finished using the deoptimizer instance.
246 delete deoptimizer; 246 delete deoptimizer;
247 247
248 return info; 248 return info;
249 } 249 }
250 250
251 251
252 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 252 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
253 Isolate* isolate) { 253 Isolate* isolate) {
254 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info); 254 CHECK_EQ(isolate->deoptimizer_data()->deoptimized_frame_info_, info);
255 delete info; 255 delete info;
256 isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL; 256 isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
257 } 257 }
258 #endif 258 #endif
259 259
260 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, 260 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
261 int count, 261 int count,
262 BailoutType type) { 262 BailoutType type) {
263 TableEntryGenerator generator(masm, type, count); 263 TableEntryGenerator generator(masm, type, count);
264 generator.Generate(); 264 generator.Generate();
265 } 265 }
266 266
267 267
268 void Deoptimizer::VisitAllOptimizedFunctionsForContext( 268 void Deoptimizer::VisitAllOptimizedFunctionsForContext(
269 Context* context, OptimizedFunctionVisitor* visitor) { 269 Context* context, OptimizedFunctionVisitor* visitor) {
270 DisallowHeapAllocation no_allocation; 270 DisallowHeapAllocation no_allocation;
271 271
272 ASSERT(context->IsNativeContext()); 272 CHECK(context->IsNativeContext());
273 273
274 visitor->EnterContext(context); 274 visitor->EnterContext(context);
275 275
276 // Visit the list of optimized functions, removing elements that 276 // Visit the list of optimized functions, removing elements that
277 // no longer refer to optimized code. 277 // no longer refer to optimized code.
278 JSFunction* prev = NULL; 278 JSFunction* prev = NULL;
279 Object* element = context->OptimizedFunctionsListHead(); 279 Object* element = context->OptimizedFunctionsListHead();
280 while (!element->IsUndefined()) { 280 while (!element->IsUndefined()) {
281 JSFunction* function = JSFunction::cast(element); 281 JSFunction* function = JSFunction::cast(element);
282 Object* next = function->next_function_link(); 282 Object* next = function->next_function_link();
283 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION || 283 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
284 (visitor->VisitFunction(function), 284 (visitor->VisitFunction(function),
285 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) { 285 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
286 // The function no longer refers to optimized code, or the visitor 286 // The function no longer refers to optimized code, or the visitor
287 // changed the code to which it refers to no longer be optimized code. 287 // changed the code to which it refers to no longer be optimized code.
288 // Remove the function from this list. 288 // Remove the function from this list.
289 if (prev != NULL) { 289 if (prev != NULL) {
290 prev->set_next_function_link(next); 290 prev->set_next_function_link(next);
291 } else { 291 } else {
292 context->SetOptimizedFunctionsListHead(next); 292 context->SetOptimizedFunctionsListHead(next);
293 } 293 }
294 // The visitor should not alter the link directly. 294 // The visitor should not alter the link directly.
295 ASSERT(function->next_function_link() == next); 295 CHECK_EQ(function->next_function_link(), next);
296 // Set the next function link to undefined to indicate it is no longer 296 // Set the next function link to undefined to indicate it is no longer
297 // in the optimized functions list. 297 // in the optimized functions list.
298 function->set_next_function_link(context->GetHeap()->undefined_value()); 298 function->set_next_function_link(context->GetHeap()->undefined_value());
299 } else { 299 } else {
300 // The visitor should not alter the link directly. 300 // The visitor should not alter the link directly.
301 ASSERT(function->next_function_link() == next); 301 CHECK_EQ(function->next_function_link(), next);
302 // preserve this element. 302 // preserve this element.
303 prev = function; 303 prev = function;
304 } 304 }
305 element = next; 305 element = next;
306 } 306 }
307 307
308 visitor->LeaveContext(context); 308 visitor->LeaveContext(context);
309 } 309 }
310 310
311 311
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 // Move marked code from the optimized code list to the deoptimized 393 // Move marked code from the optimized code list to the deoptimized
394 // code list, collecting them into a ZoneList. 394 // code list, collecting them into a ZoneList.
395 Zone zone(isolate); 395 Zone zone(isolate);
396 ZoneList<Code*> codes(10, &zone); 396 ZoneList<Code*> codes(10, &zone);
397 397
398 // Walk over all optimized code objects in this native context. 398 // Walk over all optimized code objects in this native context.
399 Code* prev = NULL; 399 Code* prev = NULL;
400 Object* element = context->OptimizedCodeListHead(); 400 Object* element = context->OptimizedCodeListHead();
401 while (!element->IsUndefined()) { 401 while (!element->IsUndefined()) {
402 Code* code = Code::cast(element); 402 Code* code = Code::cast(element);
403 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 403 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
404 Object* next = code->next_code_link(); 404 Object* next = code->next_code_link();
405 if (code->marked_for_deoptimization()) { 405 if (code->marked_for_deoptimization()) {
406 // Put the code into the list for later patching. 406 // Put the code into the list for later patching.
407 codes.Add(code, &zone); 407 codes.Add(code, &zone);
408 408
409 if (prev != NULL) { 409 if (prev != NULL) {
410 // Skip this code in the optimized code list. 410 // Skip this code in the optimized code list.
411 prev->set_next_code_link(next); 411 prev->set_next_code_link(next);
412 } else { 412 } else {
413 // There was no previous node, the next node is the new head. 413 // There was no previous node, the next node is the new head.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 481
482 482
483 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { 483 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
484 if (FLAG_trace_deopt) { 484 if (FLAG_trace_deopt) {
485 CodeTracer::Scope scope(object->GetHeap()->isolate()->GetCodeTracer()); 485 CodeTracer::Scope scope(object->GetHeap()->isolate()->GetCodeTracer());
486 PrintF(scope.file(), "[deoptimize global object @ 0x%08" V8PRIxPTR "]\n", 486 PrintF(scope.file(), "[deoptimize global object @ 0x%08" V8PRIxPTR "]\n",
487 reinterpret_cast<intptr_t>(object)); 487 reinterpret_cast<intptr_t>(object));
488 } 488 }
489 if (object->IsJSGlobalProxy()) { 489 if (object->IsJSGlobalProxy()) {
490 Object* proto = object->GetPrototype(); 490 Object* proto = object->GetPrototype();
491 ASSERT(proto->IsJSGlobalObject()); 491 CHECK(proto->IsJSGlobalObject());
492 Context* native_context = GlobalObject::cast(proto)->native_context(); 492 Context* native_context = GlobalObject::cast(proto)->native_context();
493 MarkAllCodeForContext(native_context); 493 MarkAllCodeForContext(native_context);
494 DeoptimizeMarkedCodeForContext(native_context); 494 DeoptimizeMarkedCodeForContext(native_context);
495 } else if (object->IsGlobalObject()) { 495 } else if (object->IsGlobalObject()) {
496 Context* native_context = GlobalObject::cast(object)->native_context(); 496 Context* native_context = GlobalObject::cast(object)->native_context();
497 MarkAllCodeForContext(native_context); 497 MarkAllCodeForContext(native_context);
498 DeoptimizeMarkedCodeForContext(native_context); 498 DeoptimizeMarkedCodeForContext(native_context);
499 } 499 }
500 } 500 }
501 501
502 502
503 void Deoptimizer::MarkAllCodeForContext(Context* context) { 503 void Deoptimizer::MarkAllCodeForContext(Context* context) {
504 Object* element = context->OptimizedCodeListHead(); 504 Object* element = context->OptimizedCodeListHead();
505 while (!element->IsUndefined()) { 505 while (!element->IsUndefined()) {
506 Code* code = Code::cast(element); 506 Code* code = Code::cast(element);
507 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 507 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
508 code->set_marked_for_deoptimization(true); 508 code->set_marked_for_deoptimization(true);
509 element = code->next_code_link(); 509 element = code->next_code_link();
510 } 510 }
511 } 511 }
512 512
513 513
514 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { 514 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
515 Code* code = function->code(); 515 Code* code = function->code();
516 if (code->kind() == Code::OPTIMIZED_FUNCTION) { 516 if (code->kind() == Code::OPTIMIZED_FUNCTION) {
517 // Mark the code for deoptimization and unlink any functions that also 517 // Mark the code for deoptimization and unlink any functions that also
(...skipping 14 matching lines...) Expand all
532 StackFrame::Type frame_type) { 532 StackFrame::Type frame_type) {
533 switch (deopt_type) { 533 switch (deopt_type) {
534 case EAGER: 534 case EAGER:
535 case SOFT: 535 case SOFT:
536 case LAZY: 536 case LAZY:
537 case DEBUGGER: 537 case DEBUGGER:
538 return (frame_type == StackFrame::STUB) 538 return (frame_type == StackFrame::STUB)
539 ? FLAG_trace_stub_failures 539 ? FLAG_trace_stub_failures
540 : FLAG_trace_deopt; 540 : FLAG_trace_deopt;
541 } 541 }
542 UNREACHABLE(); 542 FATAL("Unsupported deopt type");
543 return false; 543 return false;
544 } 544 }
545 545
546 546
547 const char* Deoptimizer::MessageFor(BailoutType type) { 547 const char* Deoptimizer::MessageFor(BailoutType type) {
548 switch (type) { 548 switch (type) {
549 case EAGER: return "eager"; 549 case EAGER: return "eager";
550 case SOFT: return "soft"; 550 case SOFT: return "soft";
551 case LAZY: return "lazy"; 551 case LAZY: return "lazy";
552 case DEBUGGER: return "debugger"; 552 case DEBUGGER: return "debugger";
553 } 553 }
554 UNREACHABLE(); 554 FATAL("Unsupported deopt type");
555 return NULL; 555 return NULL;
556 } 556 }
557 557
558 558
559 Deoptimizer::Deoptimizer(Isolate* isolate, 559 Deoptimizer::Deoptimizer(Isolate* isolate,
560 JSFunction* function, 560 JSFunction* function,
561 BailoutType type, 561 BailoutType type,
562 unsigned bailout_id, 562 unsigned bailout_id,
563 Address from, 563 Address from,
564 int fp_to_sp_delta, 564 int fp_to_sp_delta,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 case Deoptimizer::LAZY: { 634 case Deoptimizer::LAZY: {
635 Code* compiled_code = FindDeoptimizingCode(from_); 635 Code* compiled_code = FindDeoptimizingCode(from_);
636 return (compiled_code == NULL) 636 return (compiled_code == NULL)
637 ? static_cast<Code*>(isolate_->FindCodeObject(from_)) 637 ? static_cast<Code*>(isolate_->FindCodeObject(from_))
638 : compiled_code; 638 : compiled_code;
639 } 639 }
640 case Deoptimizer::DEBUGGER: 640 case Deoptimizer::DEBUGGER:
641 ASSERT(optimized_code->contains(from_)); 641 ASSERT(optimized_code->contains(from_));
642 return optimized_code; 642 return optimized_code;
643 } 643 }
644 UNREACHABLE(); 644 FATAL("Could not find code for optimized function");
645 return NULL; 645 return NULL;
646 } 646 }
647 647
648 648
649 void Deoptimizer::PrintFunctionName() { 649 void Deoptimizer::PrintFunctionName() {
650 if (function_->IsJSFunction()) { 650 if (function_->IsJSFunction()) {
651 function_->PrintName(trace_scope_->file()); 651 function_->PrintName(trace_scope_->file());
652 } else { 652 } else {
653 PrintF(trace_scope_->file(), 653 PrintF(trace_scope_->file(),
654 "%s", Code::Kind2String(compiled_code_->kind())); 654 "%s", Code::Kind2String(compiled_code_->kind()));
(...skipping 22 matching lines...) Expand all
677 delete disallow_heap_allocation_; 677 delete disallow_heap_allocation_;
678 disallow_heap_allocation_ = NULL; 678 disallow_heap_allocation_ = NULL;
679 #endif // DEBUG 679 #endif // DEBUG
680 } 680 }
681 681
682 682
683 Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate, 683 Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
684 int id, 684 int id,
685 BailoutType type, 685 BailoutType type,
686 GetEntryMode mode) { 686 GetEntryMode mode) {
687 ASSERT(id >= 0); 687 CHECK_GE(id, 0);
688 if (id >= kMaxNumberOfEntries) return NULL; 688 if (id >= kMaxNumberOfEntries) return NULL;
689 if (mode == ENSURE_ENTRY_CODE) { 689 if (mode == ENSURE_ENTRY_CODE) {
690 EnsureCodeForDeoptimizationEntry(isolate, type, id); 690 EnsureCodeForDeoptimizationEntry(isolate, type, id);
691 } else { 691 } else {
692 ASSERT(mode == CALCULATE_ENTRY_ADDRESS); 692 CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
693 } 693 }
694 DeoptimizerData* data = isolate->deoptimizer_data(); 694 DeoptimizerData* data = isolate->deoptimizer_data();
695 ASSERT(type < kBailoutTypesWithCodeEntry); 695 CHECK_LT(type, kBailoutTypesWithCodeEntry);
696 MemoryChunk* base = data->deopt_entry_code_[type]; 696 MemoryChunk* base = data->deopt_entry_code_[type];
697 return base->area_start() + (id * table_entry_size_); 697 return base->area_start() + (id * table_entry_size_);
698 } 698 }
699 699
700 700
701 int Deoptimizer::GetDeoptimizationId(Isolate* isolate, 701 int Deoptimizer::GetDeoptimizationId(Isolate* isolate,
702 Address addr, 702 Address addr,
703 BailoutType type) { 703 BailoutType type) {
704 DeoptimizerData* data = isolate->deoptimizer_data(); 704 DeoptimizerData* data = isolate->deoptimizer_data();
705 MemoryChunk* base = data->deopt_entry_code_[type]; 705 MemoryChunk* base = data->deopt_entry_code_[type];
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 case Translation::INT32_REGISTER: 848 case Translation::INT32_REGISTER:
849 case Translation::UINT32_REGISTER: 849 case Translation::UINT32_REGISTER:
850 case Translation::DOUBLE_REGISTER: 850 case Translation::DOUBLE_REGISTER:
851 case Translation::STACK_SLOT: 851 case Translation::STACK_SLOT:
852 case Translation::INT32_STACK_SLOT: 852 case Translation::INT32_STACK_SLOT:
853 case Translation::UINT32_STACK_SLOT: 853 case Translation::UINT32_STACK_SLOT:
854 case Translation::DOUBLE_STACK_SLOT: 854 case Translation::DOUBLE_STACK_SLOT:
855 case Translation::LITERAL: 855 case Translation::LITERAL:
856 case Translation::ARGUMENTS_OBJECT: 856 case Translation::ARGUMENTS_OBJECT:
857 default: 857 default:
858 UNREACHABLE(); 858 FATAL("Unsupported translation");
859 break; 859 break;
860 } 860 }
861 } 861 }
862 862
863 // Print some helpful diagnostic information. 863 // Print some helpful diagnostic information.
864 if (trace_scope_ != NULL) { 864 if (trace_scope_ != NULL) {
865 double ms = timer.Elapsed().InMillisecondsF(); 865 double ms = timer.Elapsed().InMillisecondsF();
866 int index = output_count_ - 1; // Index of the topmost frame. 866 int index = output_count_ - 1; // Index of the topmost frame.
867 JSFunction* function = output_[index]->GetFunction(); 867 JSFunction* function = output_[index]->GetFunction();
868 PrintF(trace_scope_->file(), 868 PrintF(trace_scope_->file(),
(...skipping 18 matching lines...) Expand all
887 887
888 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 888 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
889 int frame_index) { 889 int frame_index) {
890 BailoutId node_id = BailoutId(iterator->Next()); 890 BailoutId node_id = BailoutId(iterator->Next());
891 JSFunction* function; 891 JSFunction* function;
892 if (frame_index != 0) { 892 if (frame_index != 0) {
893 function = JSFunction::cast(ComputeLiteral(iterator->Next())); 893 function = JSFunction::cast(ComputeLiteral(iterator->Next()));
894 } else { 894 } else {
895 int closure_id = iterator->Next(); 895 int closure_id = iterator->Next();
896 USE(closure_id); 896 USE(closure_id);
897 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 897 CHECK_EQ(Translation::kSelfLiteralId, closure_id);
898 function = function_; 898 function = function_;
899 } 899 }
900 unsigned height = iterator->Next(); 900 unsigned height = iterator->Next();
901 unsigned height_in_bytes = height * kPointerSize; 901 unsigned height_in_bytes = height * kPointerSize;
902 if (trace_scope_ != NULL) { 902 if (trace_scope_ != NULL) {
903 PrintF(trace_scope_->file(), " translating "); 903 PrintF(trace_scope_->file(), " translating ");
904 function->PrintName(trace_scope_->file()); 904 function->PrintName(trace_scope_->file());
905 PrintF(trace_scope_->file(), 905 PrintF(trace_scope_->file(),
906 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); 906 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
907 } 907 }
908 908
909 // The 'fixed' part of the frame consists of the incoming parameters and 909 // The 'fixed' part of the frame consists of the incoming parameters and
910 // the part described by JavaScriptFrameConstants. 910 // the part described by JavaScriptFrameConstants.
911 unsigned fixed_frame_size = ComputeFixedSize(function); 911 unsigned fixed_frame_size = ComputeFixedSize(function);
912 unsigned input_frame_size = input_->GetFrameSize(); 912 unsigned input_frame_size = input_->GetFrameSize();
913 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 913 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
914 914
915 // Allocate and store the output frame description. 915 // Allocate and store the output frame description.
916 FrameDescription* output_frame = 916 FrameDescription* output_frame =
917 new(output_frame_size) FrameDescription(output_frame_size, function); 917 new(output_frame_size) FrameDescription(output_frame_size, function);
918 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); 918 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
919 919
920 bool is_bottommost = (0 == frame_index); 920 bool is_bottommost = (0 == frame_index);
921 bool is_topmost = (output_count_ - 1 == frame_index); 921 bool is_topmost = (output_count_ - 1 == frame_index);
922 ASSERT(frame_index >= 0 && frame_index < output_count_); 922 CHECK(frame_index >= 0 && frame_index < output_count_);
923 ASSERT(output_[frame_index] == NULL); 923 CHECK_EQ(output_[frame_index], NULL);
924 output_[frame_index] = output_frame; 924 output_[frame_index] = output_frame;
925 925
926 // The top address for the bottommost output frame can be computed from 926 // The top address for the bottommost output frame can be computed from
927 // the input frame pointer and the output frame's height. For all 927 // the input frame pointer and the output frame's height. For all
928 // subsequent output frames, it can be computed from the previous one's 928 // subsequent output frames, it can be computed from the previous one's
929 // top address and the current frame's size. 929 // top address and the current frame's size.
930 Register fp_reg = JavaScriptFrame::fp_register(); 930 Register fp_reg = JavaScriptFrame::fp_register();
931 intptr_t top_address; 931 intptr_t top_address;
932 if (is_bottommost) { 932 if (is_bottommost) {
933 // Determine whether the input frame contains alignment padding. 933 // Determine whether the input frame contains alignment padding.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1057 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1058 V8PRIxPTR "; function\n", 1058 V8PRIxPTR "; function\n",
1059 top_address + output_offset, output_offset, value); 1059 top_address + output_offset, output_offset, value);
1060 } 1060 }
1061 1061
1062 // Translate the rest of the frame. 1062 // Translate the rest of the frame.
1063 for (unsigned i = 0; i < height; ++i) { 1063 for (unsigned i = 0; i < height; ++i) {
1064 output_offset -= kPointerSize; 1064 output_offset -= kPointerSize;
1065 DoTranslateCommand(iterator, frame_index, output_offset); 1065 DoTranslateCommand(iterator, frame_index, output_offset);
1066 } 1066 }
1067 ASSERT(0 == output_offset); 1067 CHECK_EQ(0, output_offset);
1068 1068
1069 // Compute this frame's PC, state, and continuation. 1069 // Compute this frame's PC, state, and continuation.
1070 Code* non_optimized_code = function->shared()->code(); 1070 Code* non_optimized_code = function->shared()->code();
1071 FixedArray* raw_data = non_optimized_code->deoptimization_data(); 1071 FixedArray* raw_data = non_optimized_code->deoptimization_data();
1072 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); 1072 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
1073 Address start = non_optimized_code->instruction_start(); 1073 Address start = non_optimized_code->instruction_start();
1074 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); 1074 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
1075 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); 1075 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
1076 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); 1076 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
1077 output_frame->SetPc(pc_value); 1077 output_frame->SetPc(pc_value);
(...skipping 16 matching lines...) Expand all
1094 1094
1095 // Set the continuation for the topmost frame. 1095 // Set the continuation for the topmost frame.
1096 if (is_topmost && bailout_type_ != DEBUGGER) { 1096 if (is_topmost && bailout_type_ != DEBUGGER) {
1097 Builtins* builtins = isolate_->builtins(); 1097 Builtins* builtins = isolate_->builtins();
1098 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); 1098 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1099 if (bailout_type_ == LAZY) { 1099 if (bailout_type_ == LAZY) {
1100 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); 1100 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1101 } else if (bailout_type_ == SOFT) { 1101 } else if (bailout_type_ == SOFT) {
1102 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); 1102 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1103 } else { 1103 } else {
1104 ASSERT(bailout_type_ == EAGER); 1104 CHECK_EQ(bailout_type_, EAGER);
1105 } 1105 }
1106 output_frame->SetContinuation( 1106 output_frame->SetContinuation(
1107 reinterpret_cast<intptr_t>(continuation->entry())); 1107 reinterpret_cast<intptr_t>(continuation->entry()));
1108 } 1108 }
1109 } 1109 }
1110 1110
1111 1111
1112 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 1112 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
1113 int frame_index) { 1113 int frame_index) {
1114 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 1114 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
1115 unsigned height = iterator->Next(); 1115 unsigned height = iterator->Next();
1116 unsigned height_in_bytes = height * kPointerSize; 1116 unsigned height_in_bytes = height * kPointerSize;
1117 if (trace_scope_ != NULL) { 1117 if (trace_scope_ != NULL) {
1118 PrintF(trace_scope_->file(), 1118 PrintF(trace_scope_->file(),
1119 " translating arguments adaptor => height=%d\n", height_in_bytes); 1119 " translating arguments adaptor => height=%d\n", height_in_bytes);
1120 } 1120 }
1121 1121
1122 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; 1122 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
1123 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1123 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1124 1124
1125 // Allocate and store the output frame description. 1125 // Allocate and store the output frame description.
1126 FrameDescription* output_frame = 1126 FrameDescription* output_frame =
1127 new(output_frame_size) FrameDescription(output_frame_size, function); 1127 new(output_frame_size) FrameDescription(output_frame_size, function);
1128 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); 1128 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
1129 1129
1130 // Arguments adaptor can not be topmost or bottommost. 1130 // Arguments adaptor can not be topmost or bottommost.
1131 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 1131 CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1132 ASSERT(output_[frame_index] == NULL); 1132 CHECK(output_[frame_index] == NULL);
1133 output_[frame_index] = output_frame; 1133 output_[frame_index] = output_frame;
1134 1134
1135 // The top address of the frame is computed from the previous 1135 // The top address of the frame is computed from the previous
1136 // frame's top and this frame's size. 1136 // frame's top and this frame's size.
1137 intptr_t top_address; 1137 intptr_t top_address;
1138 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1138 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1139 output_frame->SetTop(top_address); 1139 output_frame->SetTop(top_address);
1140 1140
1141 // Compute the incoming parameter translation. 1141 // Compute the incoming parameter translation.
1142 int parameter_count = height; 1142 int parameter_count = height;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 int parameter_count = height; 1268 int parameter_count = height;
1269 unsigned output_offset = output_frame_size; 1269 unsigned output_offset = output_frame_size;
1270 for (int i = 0; i < parameter_count; ++i) { 1270 for (int i = 0; i < parameter_count; ++i) {
1271 output_offset -= kPointerSize; 1271 output_offset -= kPointerSize;
1272 int deferred_object_index = deferred_objects_.length(); 1272 int deferred_object_index = deferred_objects_.length();
1273 DoTranslateCommand(iterator, frame_index, output_offset); 1273 DoTranslateCommand(iterator, frame_index, output_offset);
1274 // The allocated receiver of a construct stub frame is passed as the 1274 // The allocated receiver of a construct stub frame is passed as the
1275 // receiver parameter through the translation. It might be encoding 1275 // receiver parameter through the translation. It might be encoding
1276 // a captured object, patch the slot address for a captured object. 1276 // a captured object, patch the slot address for a captured object.
1277 if (i == 0 && deferred_objects_.length() > deferred_object_index) { 1277 if (i == 0 && deferred_objects_.length() > deferred_object_index) {
1278 ASSERT(!deferred_objects_[deferred_object_index].is_arguments()); 1278 CHECK(!deferred_objects_[deferred_object_index].is_arguments());
1279 deferred_objects_[deferred_object_index].patch_slot_address(top_address); 1279 deferred_objects_[deferred_object_index].patch_slot_address(top_address);
1280 } 1280 }
1281 } 1281 }
1282 1282
1283 // Read caller's PC from the previous frame. 1283 // Read caller's PC from the previous frame.
1284 output_offset -= kPCOnStackSize; 1284 output_offset -= kPCOnStackSize;
1285 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 1285 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1286 output_frame->SetCallerPc(output_offset, callers_pc); 1286 output_frame->SetCallerPc(output_offset, callers_pc);
1287 if (trace_scope_ != NULL) { 1287 if (trace_scope_ != NULL) {
1288 PrintF(trace_scope_->file(), 1288 PrintF(trace_scope_->file(),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 output_offset -= kPointerSize; 1379 output_offset -= kPointerSize;
1380 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); 1380 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1381 output_frame->SetFrameSlot(output_offset, value); 1381 output_frame->SetFrameSlot(output_offset, value);
1382 if (trace_scope_ != NULL) { 1382 if (trace_scope_ != NULL) {
1383 PrintF(trace_scope_->file(), 1383 PrintF(trace_scope_->file(),
1384 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1384 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1385 V8PRIxPTR " ; allocated receiver\n", 1385 V8PRIxPTR " ; allocated receiver\n",
1386 top_address + output_offset, output_offset, value); 1386 top_address + output_offset, output_offset, value);
1387 } 1387 }
1388 1388
1389 ASSERT(0 == output_offset); 1389 CHECK_EQ(0, output_offset);
1390 1390
1391 intptr_t pc = reinterpret_cast<intptr_t>( 1391 intptr_t pc = reinterpret_cast<intptr_t>(
1392 construct_stub->instruction_start() + 1392 construct_stub->instruction_start() +
1393 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 1393 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1394 output_frame->SetPc(pc); 1394 output_frame->SetPc(pc);
1395 if (FLAG_enable_ool_constant_pool) { 1395 if (FLAG_enable_ool_constant_pool) {
1396 intptr_t constant_pool_value = 1396 intptr_t constant_pool_value =
1397 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); 1397 reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1398 output_frame->SetConstantPool(constant_pool_value); 1398 output_frame->SetConstantPool(constant_pool_value);
1399 } 1399 }
(...skipping 25 matching lines...) Expand all
1425 (is_setter_stub_frame ? 1 : 0); 1425 (is_setter_stub_frame ? 1 : 0);
1426 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; 1426 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
1427 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1427 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1428 1428
1429 // Allocate and store the output frame description. 1429 // Allocate and store the output frame description.
1430 FrameDescription* output_frame = 1430 FrameDescription* output_frame =
1431 new(output_frame_size) FrameDescription(output_frame_size, accessor); 1431 new(output_frame_size) FrameDescription(output_frame_size, accessor);
1432 output_frame->SetFrameType(StackFrame::INTERNAL); 1432 output_frame->SetFrameType(StackFrame::INTERNAL);
1433 1433
1434 // A frame for an accessor stub can not be the topmost or bottommost one. 1434 // A frame for an accessor stub can not be the topmost or bottommost one.
1435 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 1435 CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1436 ASSERT(output_[frame_index] == NULL); 1436 CHECK_EQ(output_[frame_index], NULL);
1437 output_[frame_index] = output_frame; 1437 output_[frame_index] = output_frame;
1438 1438
1439 // The top address of the frame is computed from the previous frame's top and 1439 // The top address of the frame is computed from the previous frame's top and
1440 // this frame's size. 1440 // this frame's size.
1441 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1441 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1442 output_frame->SetTop(top_address); 1442 output_frame->SetTop(top_address);
1443 1443
1444 unsigned output_offset = output_frame_size; 1444 unsigned output_offset = output_frame_size;
1445 1445
1446 // Read caller's PC from the previous frame. 1446 // Read caller's PC from the previous frame.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 value = reinterpret_cast<intptr_t>(accessor_stub); 1510 value = reinterpret_cast<intptr_t>(accessor_stub);
1511 output_frame->SetFrameSlot(output_offset, value); 1511 output_frame->SetFrameSlot(output_offset, value);
1512 if (trace_scope_ != NULL) { 1512 if (trace_scope_ != NULL) {
1513 PrintF(trace_scope_->file(), 1513 PrintF(trace_scope_->file(),
1514 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 1514 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
1515 " ; code object\n", 1515 " ; code object\n",
1516 top_address + output_offset, output_offset, value); 1516 top_address + output_offset, output_offset, value);
1517 } 1517 }
1518 1518
1519 // Skip receiver. 1519 // Skip receiver.
1520 Translation::Opcode opcode = 1520 DoTranslateSkip(iterator);
1521 static_cast<Translation::Opcode>(iterator->Next());
1522 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
1523 1521
1524 if (is_setter_stub_frame) { 1522 if (is_setter_stub_frame) {
1525 // The implicit return value was part of the artificial setter stub 1523 // The implicit return value was part of the artificial setter stub
1526 // environment. 1524 // environment.
1527 output_offset -= kPointerSize; 1525 output_offset -= kPointerSize;
1528 DoTranslateCommand(iterator, frame_index, output_offset); 1526 DoTranslateCommand(iterator, frame_index, output_offset);
1529 } 1527 }
1530 1528
1531 ASSERT(0 == output_offset); 1529 CHECK_EQ(output_offset, 0);
1532 1530
1533 Smi* offset = is_setter_stub_frame ? 1531 Smi* offset = is_setter_stub_frame ?
1534 isolate_->heap()->setter_stub_deopt_pc_offset() : 1532 isolate_->heap()->setter_stub_deopt_pc_offset() :
1535 isolate_->heap()->getter_stub_deopt_pc_offset(); 1533 isolate_->heap()->getter_stub_deopt_pc_offset();
1536 intptr_t pc = reinterpret_cast<intptr_t>( 1534 intptr_t pc = reinterpret_cast<intptr_t>(
1537 accessor_stub->instruction_start() + offset->value()); 1535 accessor_stub->instruction_start() + offset->value());
1538 output_frame->SetPc(pc); 1536 output_frame->SetPc(pc);
1539 if (FLAG_enable_ool_constant_pool) { 1537 if (FLAG_enable_ool_constant_pool) {
1540 intptr_t constant_pool_value = 1538 intptr_t constant_pool_value =
1541 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); 1539 reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
(...skipping 29 matching lines...) Expand all
1571 // and spilled to stack | .... | 1569 // and spilled to stack | .... |
1572 // +-------------------------+ 1570 // +-------------------------+
1573 // | caller stack param n | 1571 // | caller stack param n |
1574 // +-------------------------+<-spreg 1572 // +-------------------------+<-spreg
1575 // reg = number of parameters 1573 // reg = number of parameters
1576 // reg = failure handler address 1574 // reg = failure handler address
1577 // reg = saved frame 1575 // reg = saved frame
1578 // reg = JSFunction context 1576 // reg = JSFunction context
1579 // 1577 //
1580 1578
1581 ASSERT(compiled_code_->is_crankshafted() && 1579 CHECK(compiled_code_->is_crankshafted() &&
1582 compiled_code_->kind() != Code::OPTIMIZED_FUNCTION); 1580 compiled_code_->kind() != Code::OPTIMIZED_FUNCTION);
1583 int major_key = compiled_code_->major_key(); 1581 int major_key = compiled_code_->major_key();
1584 CodeStubInterfaceDescriptor* descriptor = 1582 CodeStubInterfaceDescriptor* descriptor =
1585 isolate_->code_stub_interface_descriptor(major_key); 1583 isolate_->code_stub_interface_descriptor(major_key);
1586 1584
1587 // The output frame must have room for all pushed register parameters 1585 // The output frame must have room for all pushed register parameters
1588 // and the standard stack frame slots. Include space for an argument 1586 // and the standard stack frame slots. Include space for an argument
1589 // object to the callee and optionally the space to pass the argument 1587 // object to the callee and optionally the space to pass the argument
1590 // object to the stub failure handler. 1588 // object to the stub failure handler.
1591 ASSERT(descriptor->register_param_count_ >= 0); 1589 CHECK_GE(descriptor->register_param_count_, 0);
1592 int height_in_bytes = kPointerSize * descriptor->register_param_count_ + 1590 int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
1593 sizeof(Arguments) + kPointerSize; 1591 sizeof(Arguments) + kPointerSize;
1594 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; 1592 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
1595 int input_frame_size = input_->GetFrameSize(); 1593 int input_frame_size = input_->GetFrameSize();
1596 int output_frame_size = height_in_bytes + fixed_frame_size; 1594 int output_frame_size = height_in_bytes + fixed_frame_size;
1597 if (trace_scope_ != NULL) { 1595 if (trace_scope_ != NULL) {
1598 PrintF(trace_scope_->file(), 1596 PrintF(trace_scope_->file(),
1599 " translating %s => StubFailureTrampolineStub, height=%d\n", 1597 " translating %s => StubFailureTrampolineStub, height=%d\n",
1600 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), 1598 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false),
1601 height_in_bytes); 1599 height_in_bytes);
1602 } 1600 }
1603 1601
1604 // The stub failure trampoline is a single frame. 1602 // The stub failure trampoline is a single frame.
1605 FrameDescription* output_frame = 1603 FrameDescription* output_frame =
1606 new(output_frame_size) FrameDescription(output_frame_size, NULL); 1604 new(output_frame_size) FrameDescription(output_frame_size, NULL);
1607 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); 1605 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1608 ASSERT(frame_index == 0); 1606 CHECK_EQ(frame_index, 0);
1609 output_[frame_index] = output_frame; 1607 output_[frame_index] = output_frame;
1610 1608
1611 // The top address for the output frame can be computed from the input 1609 // The top address for the output frame can be computed from the input
1612 // frame pointer and the output frame's height. Subtract space for the 1610 // frame pointer and the output frame's height. Subtract space for the
1613 // context and function slots. 1611 // context and function slots.
1614 Register fp_reg = StubFailureTrampolineFrame::fp_register(); 1612 Register fp_reg = StubFailureTrampolineFrame::fp_register();
1615 intptr_t top_address = input_->GetRegister(fp_reg.code()) - 1613 intptr_t top_address = input_->GetRegister(fp_reg.code()) -
1616 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes; 1614 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes;
1617 output_frame->SetTop(top_address); 1615 output_frame->SetTop(top_address);
1618 1616
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 } 1654 }
1657 } 1655 }
1658 1656
1659 // The context can be gotten from the input frame. 1657 // The context can be gotten from the input frame.
1660 Register context_reg = StubFailureTrampolineFrame::context_register(); 1658 Register context_reg = StubFailureTrampolineFrame::context_register();
1661 input_frame_offset -= kPointerSize; 1659 input_frame_offset -= kPointerSize;
1662 value = input_->GetFrameSlot(input_frame_offset); 1660 value = input_->GetFrameSlot(input_frame_offset);
1663 output_frame->SetRegister(context_reg.code(), value); 1661 output_frame->SetRegister(context_reg.code(), value);
1664 output_frame_offset -= kPointerSize; 1662 output_frame_offset -= kPointerSize;
1665 output_frame->SetFrameSlot(output_frame_offset, value); 1663 output_frame->SetFrameSlot(output_frame_offset, value);
1666 ASSERT(reinterpret_cast<Object*>(value)->IsContext()); 1664 CHECK(reinterpret_cast<Object*>(value)->IsContext());
1667 if (trace_scope_ != NULL) { 1665 if (trace_scope_ != NULL) {
1668 PrintF(trace_scope_->file(), 1666 PrintF(trace_scope_->file(),
1669 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1667 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1670 V8PRIxPTR " ; context\n", 1668 V8PRIxPTR " ; context\n",
1671 top_address + output_frame_offset, output_frame_offset, value); 1669 top_address + output_frame_offset, output_frame_offset, value);
1672 } 1670 }
1673 1671
1674 // A marker value is used in place of the function. 1672 // A marker value is used in place of the function.
1675 output_frame_offset -= kPointerSize; 1673 output_frame_offset -= kPointerSize;
1676 value = reinterpret_cast<intptr_t>( 1674 value = reinterpret_cast<intptr_t>(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 int arguments_length_offset = -1; 1732 int arguments_length_offset = -1;
1735 for (int i = 0; i < descriptor->register_param_count_; ++i) { 1733 for (int i = 0; i < descriptor->register_param_count_; ++i) {
1736 output_frame_offset -= kPointerSize; 1734 output_frame_offset -= kPointerSize;
1737 DoTranslateCommand(iterator, 0, output_frame_offset); 1735 DoTranslateCommand(iterator, 0, output_frame_offset);
1738 1736
1739 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) { 1737 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) {
1740 arguments_length_offset = output_frame_offset; 1738 arguments_length_offset = output_frame_offset;
1741 } 1739 }
1742 } 1740 }
1743 1741
1744 ASSERT(0 == output_frame_offset); 1742 CHECK_EQ(output_frame_offset, 0);
1745 1743
1746 if (!arg_count_known) { 1744 if (!arg_count_known) {
1747 ASSERT(arguments_length_offset >= 0); 1745 CHECK_GE(arguments_length_offset, 0);
1748 // We know it's a smi because 1) the code stub guarantees the stack 1746 // We know it's a smi because 1) the code stub guarantees the stack
1749 // parameter count is in smi range, and 2) the DoTranslateCommand in the 1747 // parameter count is in smi range, and 2) the DoTranslateCommand in the
1750 // parameter loop above translated that to a tagged value. 1748 // parameter loop above translated that to a tagged value.
1751 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( 1749 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
1752 output_frame->GetFrameSlot(arguments_length_offset)); 1750 output_frame->GetFrameSlot(arguments_length_offset));
1753 caller_arg_count = smi_caller_arg_count->value(); 1751 caller_arg_count = smi_caller_arg_count->value();
1754 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); 1752 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
1755 if (trace_scope_ != NULL) { 1753 if (trace_scope_ != NULL) {
1756 PrintF(trace_scope_->file(), 1754 PrintF(trace_scope_->file(),
1757 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1755 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
(...skipping 17 matching lines...) Expand all
1775 CopyDoubleRegisters(output_frame); 1773 CopyDoubleRegisters(output_frame);
1776 1774
1777 // Fill registers containing handler and number of parameters. 1775 // Fill registers containing handler and number of parameters.
1778 SetPlatformCompiledStubRegisters(output_frame, descriptor); 1776 SetPlatformCompiledStubRegisters(output_frame, descriptor);
1779 1777
1780 // Compute this frame's PC, state, and continuation. 1778 // Compute this frame's PC, state, and continuation.
1781 Code* trampoline = NULL; 1779 Code* trampoline = NULL;
1782 StubFunctionMode function_mode = descriptor->function_mode_; 1780 StubFunctionMode function_mode = descriptor->function_mode_;
1783 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline, 1781 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
1784 isolate_); 1782 isolate_);
1785 ASSERT(trampoline != NULL); 1783 ASSERT_NE(trampoline, NULL);
1786 output_frame->SetPc(reinterpret_cast<intptr_t>( 1784 output_frame->SetPc(reinterpret_cast<intptr_t>(
1787 trampoline->instruction_start())); 1785 trampoline->instruction_start()));
1788 if (FLAG_enable_ool_constant_pool) { 1786 if (FLAG_enable_ool_constant_pool) {
1789 Register constant_pool_reg = 1787 Register constant_pool_reg =
1790 StubFailureTrampolineFrame::constant_pool_pointer_register(); 1788 StubFailureTrampolineFrame::constant_pool_pointer_register();
1791 intptr_t constant_pool_value = 1789 intptr_t constant_pool_value =
1792 reinterpret_cast<intptr_t>(trampoline->constant_pool()); 1790 reinterpret_cast<intptr_t>(trampoline->constant_pool());
1793 output_frame->SetConstantPool(constant_pool_value); 1791 output_frame->SetConstantPool(constant_pool_value);
1794 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); 1792 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1795 } 1793 }
(...skipping 25 matching lines...) Expand all
1821 for (int i = 0; i < length; ++i) { 1819 for (int i = 0; i < length; ++i) {
1822 MaterializeNextValue(); 1820 MaterializeNextValue();
1823 } 1821 }
1824 } else if (desc.is_arguments()) { 1822 } else if (desc.is_arguments()) {
1825 // Construct an arguments object and copy the parameters to a newly 1823 // Construct an arguments object and copy the parameters to a newly
1826 // allocated arguments object backing store. 1824 // allocated arguments object backing store.
1827 Handle<JSFunction> function = ArgumentsObjectFunction(object_index); 1825 Handle<JSFunction> function = ArgumentsObjectFunction(object_index);
1828 Handle<JSObject> arguments = 1826 Handle<JSObject> arguments =
1829 isolate_->factory()->NewArgumentsObject(function, length); 1827 isolate_->factory()->NewArgumentsObject(function, length);
1830 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); 1828 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
1831 ASSERT(array->length() == length); 1829 ASSERT_EQ(array->length(), length);
1832 arguments->set_elements(*array); 1830 arguments->set_elements(*array);
1833 materialized_objects_->Add(arguments); 1831 materialized_objects_->Add(arguments);
1834 for (int i = 0; i < length; ++i) { 1832 for (int i = 0; i < length; ++i) {
1835 Handle<Object> value = MaterializeNextValue(); 1833 Handle<Object> value = MaterializeNextValue();
1836 array->set(i, *value); 1834 array->set(i, *value);
1837 } 1835 }
1838 } else { 1836 } else {
1839 // Dispatch on the instance type of the object to be materialized. 1837 // Dispatch on the instance type of the object to be materialized.
1840 // We also need to make sure that the representation of all fields 1838 // We also need to make sure that the representation of all fields
1841 // in the given object are general enough to hold a tagged value. 1839 // in the given object are general enough to hold a tagged value.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 Handle<Object> elements = MaterializeNextValue(); 1885 Handle<Object> elements = MaterializeNextValue();
1888 Handle<Object> length = MaterializeNextValue(); 1886 Handle<Object> length = MaterializeNextValue();
1889 object->set_properties(FixedArray::cast(*properties)); 1887 object->set_properties(FixedArray::cast(*properties));
1890 object->set_elements(FixedArrayBase::cast(*elements)); 1888 object->set_elements(FixedArrayBase::cast(*elements));
1891 object->set_length(*length); 1889 object->set_length(*length);
1892 break; 1890 break;
1893 } 1891 }
1894 default: 1892 default:
1895 PrintF(stderr, 1893 PrintF(stderr,
1896 "[couldn't handle instance type %d]\n", map->instance_type()); 1894 "[couldn't handle instance type %d]\n", map->instance_type());
1897 UNREACHABLE(); 1895 FATAL("Unsupported instance type");
1898 } 1896 }
1899 } 1897 }
1900 1898
1901 return materialized_objects_->at(object_index); 1899 return materialized_objects_->at(object_index);
1902 } 1900 }
1903 1901
1904 1902
1905 Handle<Object> Deoptimizer::MaterializeNextValue() { 1903 Handle<Object> Deoptimizer::MaterializeNextValue() {
1906 int value_index = materialization_value_index_++; 1904 int value_index = materialization_value_index_++;
1907 Handle<Object> value = materialized_values_->at(value_index); 1905 Handle<Object> value = materialized_values_->at(value_index);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 1979
1982 while (materialization_object_index_ < deferred_objects_.length()) { 1980 while (materialization_object_index_ < deferred_objects_.length()) {
1983 int object_index = materialization_object_index_; 1981 int object_index = materialization_object_index_;
1984 ObjectMaterializationDescriptor descriptor = 1982 ObjectMaterializationDescriptor descriptor =
1985 deferred_objects_.at(object_index); 1983 deferred_objects_.at(object_index);
1986 1984
1987 // Find a previously materialized object by de-duplication or 1985 // Find a previously materialized object by de-duplication or
1988 // materialize a new instance of the object if necessary. Store 1986 // materialize a new instance of the object if necessary. Store
1989 // the materialized object into the frame slot. 1987 // the materialized object into the frame slot.
1990 Handle<Object> object = MaterializeNextHeapObject(); 1988 Handle<Object> object = MaterializeNextHeapObject();
1991 Memory::Object_at(descriptor.slot_address()) = *object; 1989 if (descriptor.slot_address() != NULL) {
1990 Memory::Object_at(descriptor.slot_address()) = *object;
1991 }
1992 if (trace_scope_ != NULL) { 1992 if (trace_scope_ != NULL) {
1993 if (descriptor.is_arguments()) { 1993 if (descriptor.is_arguments()) {
1994 PrintF(trace_scope_->file(), 1994 PrintF(trace_scope_->file(),
1995 "Materialized %sarguments object of length %d for %p: ", 1995 "Materialized %sarguments object of length %d for %p: ",
1996 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", 1996 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "",
1997 Handle<JSObject>::cast(object)->elements()->length(), 1997 Handle<JSObject>::cast(object)->elements()->length(),
1998 reinterpret_cast<void*>(descriptor.slot_address())); 1998 reinterpret_cast<void*>(descriptor.slot_address()));
1999 } else { 1999 } else {
2000 PrintF(trace_scope_->file(), 2000 PrintF(trace_scope_->file(),
2001 "Materialized captured object of size %d for %p: ", 2001 "Materialized captured object of size %d for %p: ",
2002 Handle<HeapObject>::cast(object)->Size(), 2002 Handle<HeapObject>::cast(object)->Size(),
2003 reinterpret_cast<void*>(descriptor.slot_address())); 2003 reinterpret_cast<void*>(descriptor.slot_address()));
2004 } 2004 }
2005 object->ShortPrint(trace_scope_->file()); 2005 object->ShortPrint(trace_scope_->file());
2006 PrintF(trace_scope_->file(), "\n"); 2006 PrintF(trace_scope_->file(), "\n");
2007 } 2007 }
2008 } 2008 }
2009 2009
2010 ASSERT(materialization_object_index_ == materialized_objects_->length()); 2010 CHECK_EQ(materialization_object_index_, materialized_objects_->length());
2011 ASSERT(materialization_value_index_ == materialized_values_->length()); 2011 CHECK_EQ(materialization_value_index_, materialized_values_->length());
2012 } 2012 }
2013 2013
2014 if (prev_materialized_count_ > 0) { 2014 if (prev_materialized_count_ > 0) {
2015 materialized_store->Remove(stack_fp_); 2015 materialized_store->Remove(stack_fp_);
2016 } 2016 }
2017 } 2017 }
2018 2018
2019 2019
2020 #ifdef ENABLE_DEBUGGER_SUPPORT 2020 #ifdef ENABLE_DEBUGGER_SUPPORT
2021 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( 2021 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
2022 Address parameters_top, 2022 Address parameters_top,
2023 uint32_t parameters_size, 2023 uint32_t parameters_size,
2024 Address expressions_top, 2024 Address expressions_top,
2025 uint32_t expressions_size, 2025 uint32_t expressions_size,
2026 DeoptimizedFrameInfo* info) { 2026 DeoptimizedFrameInfo* info) {
2027 ASSERT_EQ(DEBUGGER, bailout_type_); 2027 CHECK_EQ(DEBUGGER, bailout_type_);
2028 Address parameters_bottom = parameters_top + parameters_size; 2028 Address parameters_bottom = parameters_top + parameters_size;
2029 Address expressions_bottom = expressions_top + expressions_size; 2029 Address expressions_bottom = expressions_top + expressions_size;
2030 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 2030 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
2031 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; 2031 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i];
2032 2032
2033 // Check of the heap number to materialize actually belong to the frame 2033 // Check of the heap number to materialize actually belong to the frame
2034 // being extracted. 2034 // being extracted.
2035 Address slot = d.destination(); 2035 Address slot = d.destination();
2036 if (parameters_top <= slot && slot < parameters_bottom) { 2036 if (parameters_top <= slot && slot < parameters_bottom) {
2037 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 2037 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 2075
2076 static const char* TraceValueType(bool is_smi) { 2076 static const char* TraceValueType(bool is_smi) {
2077 if (is_smi) { 2077 if (is_smi) {
2078 return "smi"; 2078 return "smi";
2079 } 2079 }
2080 2080
2081 return "heap number"; 2081 return "heap number";
2082 } 2082 }
2083 2083
2084 2084
2085 void Deoptimizer::DoTranslateSkip(TranslationIterator* iterator) {
2086 Translation::Opcode opcode =
2087 static_cast<Translation::Opcode>(iterator->Next());
2088
2089 switch (opcode) {
2090 case Translation::BEGIN:
2091 case Translation::JS_FRAME:
2092 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2093 case Translation::CONSTRUCT_STUB_FRAME:
2094 case Translation::GETTER_STUB_FRAME:
2095 case Translation::SETTER_STUB_FRAME:
2096 case Translation::COMPILED_STUB_FRAME: {
2097 FATAL("Unexpected frame start translation opcode");
2098 return;
2099 }
2100
2101 case Translation::REGISTER:
2102 case Translation::INT32_REGISTER:
2103 case Translation::UINT32_REGISTER:
2104 case Translation::DOUBLE_REGISTER:
2105 case Translation::STACK_SLOT:
2106 case Translation::INT32_STACK_SLOT:
2107 case Translation::UINT32_STACK_SLOT:
2108 case Translation::DOUBLE_STACK_SLOT:
2109 case Translation::LITERAL: {
2110 // The value is not part of any materialized object, so we can ignore it.
2111 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
2112 return;
2113 }
2114
2115 case Translation::DUPLICATED_OBJECT: {
2116 int object_index = iterator->Next();
2117 if (trace_scope_ != NULL) {
2118 PrintF(trace_scope_->file(), " skipping object ");
2119 PrintF(trace_scope_->file(),
2120 " ; duplicate of object #%d\n", object_index);
2121 }
2122 AddObjectDuplication(0, object_index);
2123 return;
2124 }
2125
2126 case Translation::ARGUMENTS_OBJECT:
2127 case Translation::CAPTURED_OBJECT: {
2128 int length = iterator->Next();
2129 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2130 if (trace_scope_ != NULL) {
2131 PrintF(trace_scope_->file(), " skipping object ");
2132 PrintF(trace_scope_->file(),
2133 " ; object (length = %d, is_args = %d)\n", length, is_args);
2134 }
2135
2136 AddObjectStart(0, length, is_args);
2137
2138 // We save the object values on the side and materialize the actual
2139 // object after the deoptimized frame is built.
2140 int object_index = deferred_objects_.length() - 1;
2141 for (int i = 0; i < length; i++) {
2142 DoTranslateObject(iterator, object_index, i);
2143 }
2144 return;
2145 }
2146 }
2147
2148 FATAL("Unexpected translation opcode");
2149 }
2150
2151
2085 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, 2152 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
2086 int object_index, 2153 int object_index,
2087 int field_index) { 2154 int field_index) {
2088 disasm::NameConverter converter; 2155 disasm::NameConverter converter;
2089 Address object_slot = deferred_objects_[object_index].slot_address(); 2156 Address object_slot = deferred_objects_[object_index].slot_address();
2090 2157
2091 Translation::Opcode opcode = 2158 Translation::Opcode opcode =
2092 static_cast<Translation::Opcode>(iterator->Next()); 2159 static_cast<Translation::Opcode>(iterator->Next());
2093 2160
2094 switch (opcode) { 2161 switch (opcode) {
2095 case Translation::BEGIN: 2162 case Translation::BEGIN:
2096 case Translation::JS_FRAME: 2163 case Translation::JS_FRAME:
2097 case Translation::ARGUMENTS_ADAPTOR_FRAME: 2164 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2098 case Translation::CONSTRUCT_STUB_FRAME: 2165 case Translation::CONSTRUCT_STUB_FRAME:
2099 case Translation::GETTER_STUB_FRAME: 2166 case Translation::GETTER_STUB_FRAME:
2100 case Translation::SETTER_STUB_FRAME: 2167 case Translation::SETTER_STUB_FRAME:
2101 case Translation::COMPILED_STUB_FRAME: 2168 case Translation::COMPILED_STUB_FRAME:
2102 UNREACHABLE(); 2169 FATAL("Unexpected frame start translation opcode");
2103 return; 2170 return;
2104 2171
2105 case Translation::REGISTER: { 2172 case Translation::REGISTER: {
2106 int input_reg = iterator->Next(); 2173 int input_reg = iterator->Next();
2107 intptr_t input_value = input_->GetRegister(input_reg); 2174 intptr_t input_value = input_->GetRegister(input_reg);
2108 if (trace_scope_ != NULL) { 2175 if (trace_scope_ != NULL) {
2109 PrintF(trace_scope_->file(), 2176 PrintF(trace_scope_->file(),
2110 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2177 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2111 reinterpret_cast<intptr_t>(object_slot), 2178 reinterpret_cast<intptr_t>(object_slot),
2112 field_index); 2179 field_index);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
2332 AddObjectTaggedValue(value); 2399 AddObjectTaggedValue(value);
2333 // We save the object values on the side and materialize the actual 2400 // We save the object values on the side and materialize the actual
2334 // object after the deoptimized frame is built. 2401 // object after the deoptimized frame is built.
2335 int object_index = deferred_objects_.length() - 1; 2402 int object_index = deferred_objects_.length() - 1;
2336 for (int i = 0; i < length; i++) { 2403 for (int i = 0; i < length; i++) {
2337 DoTranslateObject(iterator, object_index, i); 2404 DoTranslateObject(iterator, object_index, i);
2338 } 2405 }
2339 return; 2406 return;
2340 } 2407 }
2341 } 2408 }
2409
2410 FATAL("Unexpected translation opcode");
2342 } 2411 }
2343 2412
2344 2413
2345 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 2414 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
2346 int frame_index, 2415 int frame_index,
2347 unsigned output_offset) { 2416 unsigned output_offset) {
2348 disasm::NameConverter converter; 2417 disasm::NameConverter converter;
2349 // A GC-safe temporary placeholder that we can put in the output frame. 2418 // A GC-safe temporary placeholder that we can put in the output frame.
2350 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 2419 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
2351 2420
2352 Translation::Opcode opcode = 2421 Translation::Opcode opcode =
2353 static_cast<Translation::Opcode>(iterator->Next()); 2422 static_cast<Translation::Opcode>(iterator->Next());
2354 2423
2355 switch (opcode) { 2424 switch (opcode) {
2356 case Translation::BEGIN: 2425 case Translation::BEGIN:
2357 case Translation::JS_FRAME: 2426 case Translation::JS_FRAME:
2358 case Translation::ARGUMENTS_ADAPTOR_FRAME: 2427 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2359 case Translation::CONSTRUCT_STUB_FRAME: 2428 case Translation::CONSTRUCT_STUB_FRAME:
2360 case Translation::GETTER_STUB_FRAME: 2429 case Translation::GETTER_STUB_FRAME:
2361 case Translation::SETTER_STUB_FRAME: 2430 case Translation::SETTER_STUB_FRAME:
2362 case Translation::COMPILED_STUB_FRAME: 2431 case Translation::COMPILED_STUB_FRAME:
2363 UNREACHABLE(); 2432 FATAL("Unexpected translation opcode");
2364 return; 2433 return;
2365 2434
2366 case Translation::REGISTER: { 2435 case Translation::REGISTER: {
2367 int input_reg = iterator->Next(); 2436 int input_reg = iterator->Next();
2368 intptr_t input_value = input_->GetRegister(input_reg); 2437 intptr_t input_value = input_->GetRegister(input_reg);
2369 if (trace_scope_ != NULL) { 2438 if (trace_scope_ != NULL) {
2370 PrintF( 2439 PrintF(
2371 trace_scope_->file(), 2440 trace_scope_->file(),
2372 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", 2441 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
2373 output_[frame_index]->GetTop() + output_offset, 2442 output_[frame_index]->GetTop() + output_offset,
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 // pointer, function, context, and all the incoming arguments. 2717 // pointer, function, context, and all the incoming arguments.
2649 return ComputeIncomingArgumentSize(function) + 2718 return ComputeIncomingArgumentSize(function) +
2650 StandardFrameConstants::kFixedFrameSize; 2719 StandardFrameConstants::kFixedFrameSize;
2651 } 2720 }
2652 2721
2653 2722
2654 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { 2723 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
2655 // The incoming arguments is the values for formal parameters and 2724 // The incoming arguments is the values for formal parameters and
2656 // the receiver. Every slot contains a pointer. 2725 // the receiver. Every slot contains a pointer.
2657 if (function->IsSmi()) { 2726 if (function->IsSmi()) {
2658 ASSERT(Smi::cast(function) == Smi::FromInt(StackFrame::STUB)); 2727 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
2659 return 0; 2728 return 0;
2660 } 2729 }
2661 unsigned arguments = function->shared()->formal_parameter_count() + 1; 2730 unsigned arguments = function->shared()->formal_parameter_count() + 1;
2662 return arguments * kPointerSize; 2731 return arguments * kPointerSize;
2663 } 2732 }
2664 2733
2665 2734
2666 unsigned Deoptimizer::ComputeOutgoingArgumentSize() const { 2735 unsigned Deoptimizer::ComputeOutgoingArgumentSize() const {
2667 DeoptimizationInputData* data = DeoptimizationInputData::cast( 2736 DeoptimizationInputData* data = DeoptimizationInputData::cast(
2668 compiled_code_->deoptimization_data()); 2737 compiled_code_->deoptimization_data());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 } 2782 }
2714 2783
2715 2784
2716 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, 2785 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
2717 BailoutType type, 2786 BailoutType type,
2718 int max_entry_id) { 2787 int max_entry_id) {
2719 // We cannot run this if the serializer is enabled because this will 2788 // We cannot run this if the serializer is enabled because this will
2720 // cause us to emit relocation information for the external 2789 // cause us to emit relocation information for the external
2721 // references. This is fine because the deoptimizer's code section 2790 // references. This is fine because the deoptimizer's code section
2722 // isn't meant to be serialized at all. 2791 // isn't meant to be serialized at all.
2723 ASSERT(type == EAGER || type == SOFT || type == LAZY); 2792 CHECK(type == EAGER || type == SOFT || type == LAZY);
2724 DeoptimizerData* data = isolate->deoptimizer_data(); 2793 DeoptimizerData* data = isolate->deoptimizer_data();
2725 int entry_count = data->deopt_entry_code_entries_[type]; 2794 int entry_count = data->deopt_entry_code_entries_[type];
2726 if (max_entry_id < entry_count) return; 2795 if (max_entry_id < entry_count) return;
2727 entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries); 2796 entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2728 while (max_entry_id >= entry_count) entry_count *= 2; 2797 while (max_entry_id >= entry_count) entry_count *= 2;
2729 ASSERT(entry_count <= Deoptimizer::kMaxNumberOfEntries); 2798 CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2730 2799
2731 MacroAssembler masm(isolate, NULL, 16 * KB); 2800 MacroAssembler masm(isolate, NULL, 16 * KB);
2732 masm.set_emit_debug_code(false); 2801 masm.set_emit_debug_code(false);
2733 GenerateDeoptimizationEntries(&masm, entry_count, type); 2802 GenerateDeoptimizationEntries(&masm, entry_count, type);
2734 CodeDesc desc; 2803 CodeDesc desc;
2735 masm.GetCode(&desc); 2804 masm.GetCode(&desc);
2736 ASSERT(!RelocInfo::RequiresRelocation(desc)); 2805 ASSERT(!RelocInfo::RequiresRelocation(desc));
2737 2806
2738 MemoryChunk* chunk = data->deopt_entry_code_[type]; 2807 MemoryChunk* chunk = data->deopt_entry_code_[type];
2739 ASSERT(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >= 2808 CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
2740 desc.instr_size); 2809 desc.instr_size);
2741 chunk->CommitArea(desc.instr_size); 2810 chunk->CommitArea(desc.instr_size);
2742 CopyBytes(chunk->area_start(), desc.buffer, 2811 CopyBytes(chunk->area_start(), desc.buffer,
2743 static_cast<size_t>(desc.instr_size)); 2812 static_cast<size_t>(desc.instr_size));
2744 CPU::FlushICache(chunk->area_start(), desc.instr_size); 2813 CPU::FlushICache(chunk->area_start(), desc.instr_size);
2745 2814
2746 data->deopt_entry_code_entries_[type] = entry_count; 2815 data->deopt_entry_code_entries_[type] = entry_count;
2747 } 2816 }
2748 2817
2749 2818
2750 FrameDescription::FrameDescription(uint32_t frame_size, 2819 FrameDescription::FrameDescription(uint32_t frame_size,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 case StackFrame::JAVA_SCRIPT: 2866 case StackFrame::JAVA_SCRIPT:
2798 return function_->shared()->formal_parameter_count(); 2867 return function_->shared()->formal_parameter_count();
2799 case StackFrame::ARGUMENTS_ADAPTOR: { 2868 case StackFrame::ARGUMENTS_ADAPTOR: {
2800 // Last slot contains number of incomming arguments as a smi. 2869 // Last slot contains number of incomming arguments as a smi.
2801 // Can't use GetExpression(0) because it would cause infinite recursion. 2870 // Can't use GetExpression(0) because it would cause infinite recursion.
2802 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value(); 2871 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
2803 } 2872 }
2804 case StackFrame::STUB: 2873 case StackFrame::STUB:
2805 return -1; // Minus receiver. 2874 return -1; // Minus receiver.
2806 default: 2875 default:
2807 UNREACHABLE(); 2876 FATAL("Unexpected stack frame type");
2808 return 0; 2877 return 0;
2809 } 2878 }
2810 } 2879 }
2811 2880
2812 2881
2813 Object* FrameDescription::GetParameter(int index) { 2882 Object* FrameDescription::GetParameter(int index) {
2814 ASSERT(index >= 0); 2883 CHECK_GE(index, 0);
2815 ASSERT(index < ComputeParametersCount()); 2884 CHECK_LT(index, ComputeParametersCount());
2816 // The slot indexes for incoming arguments are negative. 2885 // The slot indexes for incoming arguments are negative.
2817 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount()); 2886 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
2818 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 2887 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2819 } 2888 }
2820 2889
2821 2890
2822 unsigned FrameDescription::GetExpressionCount() { 2891 unsigned FrameDescription::GetExpressionCount() {
2823 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_); 2892 CHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
2824 unsigned size = GetFrameSize() - ComputeFixedSize(); 2893 unsigned size = GetFrameSize() - ComputeFixedSize();
2825 return size / kPointerSize; 2894 return size / kPointerSize;
2826 } 2895 }
2827 2896
2828 2897
2829 Object* FrameDescription::GetExpression(int index) { 2898 Object* FrameDescription::GetExpression(int index) {
2830 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_); 2899 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
2831 unsigned offset = GetOffsetFromSlotIndex(index); 2900 unsigned offset = GetOffsetFromSlotIndex(index);
2832 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 2901 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2833 } 2902 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
3015 case LITERAL: 3084 case LITERAL:
3016 case COMPILED_STUB_FRAME: 3085 case COMPILED_STUB_FRAME:
3017 return 1; 3086 return 1;
3018 case BEGIN: 3087 case BEGIN:
3019 case ARGUMENTS_ADAPTOR_FRAME: 3088 case ARGUMENTS_ADAPTOR_FRAME:
3020 case CONSTRUCT_STUB_FRAME: 3089 case CONSTRUCT_STUB_FRAME:
3021 return 2; 3090 return 2;
3022 case JS_FRAME: 3091 case JS_FRAME:
3023 return 3; 3092 return 3;
3024 } 3093 }
3025 UNREACHABLE(); 3094 FATAL("Unexpected translation type");
3026 return -1; 3095 return -1;
3027 } 3096 }
3028 3097
3029 3098
3030 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 3099 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
3031 3100
3032 const char* Translation::StringFor(Opcode opcode) { 3101 const char* Translation::StringFor(Opcode opcode) {
3033 #define TRANSLATION_OPCODE_CASE(item) case item: return #item; 3102 #define TRANSLATION_OPCODE_CASE(item) case item: return #item;
3034 switch (opcode) { 3103 switch (opcode) {
3035 TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE) 3104 TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3125 int formal_parameter_count) 3194 int formal_parameter_count)
3126 : current_slot_(0), args_length_(-1), first_slot_index_(-1) { 3195 : current_slot_(0), args_length_(-1), first_slot_index_(-1) {
3127 DisallowHeapAllocation no_gc; 3196 DisallowHeapAllocation no_gc;
3128 3197
3129 int deopt_index = Safepoint::kNoDeoptimizationIndex; 3198 int deopt_index = Safepoint::kNoDeoptimizationIndex;
3130 DeoptimizationInputData* data = 3199 DeoptimizationInputData* data =
3131 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); 3200 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
3132 TranslationIterator it(data->TranslationByteArray(), 3201 TranslationIterator it(data->TranslationByteArray(),
3133 data->TranslationIndex(deopt_index)->value()); 3202 data->TranslationIndex(deopt_index)->value());
3134 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 3203 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
3135 ASSERT(opcode == Translation::BEGIN); 3204 CHECK_EQ(opcode, Translation::BEGIN);
3136 it.Next(); // Drop frame count. 3205 it.Next(); // Drop frame count.
3137 3206
3138 stack_frame_id_ = frame->fp(); 3207 stack_frame_id_ = frame->fp();
3139 3208
3140 int jsframe_count = it.Next(); 3209 int jsframe_count = it.Next();
3141 USE(jsframe_count); 3210 CHECK_GT(jsframe_count, inlined_jsframe_index);
3142 ASSERT(jsframe_count > inlined_jsframe_index);
3143 int jsframes_to_skip = inlined_jsframe_index; 3211 int jsframes_to_skip = inlined_jsframe_index;
3144 int number_of_slots = -1; // Number of slots inside our frame (yet unknown) 3212 int number_of_slots = -1; // Number of slots inside our frame (yet unknown)
3145 bool should_deopt = false; 3213 bool should_deopt = false;
3146 while (number_of_slots != 0) { 3214 while (number_of_slots != 0) {
3147 opcode = static_cast<Translation::Opcode>(it.Next()); 3215 opcode = static_cast<Translation::Opcode>(it.Next());
3148 bool processed = false; 3216 bool processed = false;
3149 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) { 3217 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
3150 if (jsframes_to_skip == 0) { 3218 if (jsframes_to_skip == 0) {
3151 ASSERT(Translation::NumberOfOperandsFor(opcode) == 2); 3219 CHECK_EQ(Translation::NumberOfOperandsFor(opcode), 2);
3152 3220
3153 it.Skip(1); // literal id 3221 it.Skip(1); // literal id
3154 int height = it.Next(); 3222 int height = it.Next();
3155 3223
3156 // Skip the translation command for the receiver. 3224 // Skip the translation command for the receiver.
3157 it.Skip(Translation::NumberOfOperandsFor( 3225 it.Skip(Translation::NumberOfOperandsFor(
3158 static_cast<Translation::Opcode>(it.Next()))); 3226 static_cast<Translation::Opcode>(it.Next())));
3159 3227
3160 // We reached the arguments adaptor frame corresponding to the 3228 // We reached the arguments adaptor frame corresponding to the
3161 // inlined function in question. Number of arguments is height - 1. 3229 // inlined function in question. Number of arguments is height - 1.
(...skipping 26 matching lines...) Expand all
3188 opcode != Translation::GETTER_STUB_FRAME && 3256 opcode != Translation::GETTER_STUB_FRAME &&
3189 opcode != Translation::SETTER_STUB_FRAME && 3257 opcode != Translation::SETTER_STUB_FRAME &&
3190 opcode != Translation::COMPILED_STUB_FRAME) { 3258 opcode != Translation::COMPILED_STUB_FRAME) {
3191 slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame)); 3259 slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame));
3192 3260
3193 if (first_slot_index_ >= 0) { 3261 if (first_slot_index_ >= 0) {
3194 // We have found the beginning of our frame -> make sure we count 3262 // We have found the beginning of our frame -> make sure we count
3195 // the nested slots of captured objects 3263 // the nested slots of captured objects
3196 number_of_slots--; 3264 number_of_slots--;
3197 SlotRef& slot = slot_refs_.last(); 3265 SlotRef& slot = slot_refs_.last();
3198 ASSERT(slot.Representation() != SlotRef::ARGUMENTS_OBJECT); 3266 CHECK_NE(slot.Representation(), SlotRef::ARGUMENTS_OBJECT);
3199 number_of_slots += slot.GetChildrenCount(); 3267 number_of_slots += slot.GetChildrenCount();
3200 if (slot.Representation() == SlotRef::DEFERRED_OBJECT || 3268 if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
3201 slot.Representation() == SlotRef::DUPLICATE_OBJECT) { 3269 slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
3202 should_deopt = true; 3270 should_deopt = true;
3203 } 3271 }
3204 } 3272 }
3205 3273
3206 processed = true; 3274 processed = true;
3207 } 3275 }
3208 if (!processed) { 3276 if (!processed) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3262 previously_materialized_objects_ = materialized_store->Get(stack_frame_id_); 3330 previously_materialized_objects_ = materialized_store->Get(stack_frame_id_);
3263 prev_materialized_count_ = previously_materialized_objects_.is_null() 3331 prev_materialized_count_ = previously_materialized_objects_.is_null()
3264 ? 0 : previously_materialized_objects_->length(); 3332 ? 0 : previously_materialized_objects_->length();
3265 3333
3266 // Skip any materialized objects of the inlined "parent" frames. 3334 // Skip any materialized objects of the inlined "parent" frames.
3267 // (Note that we still need to materialize them because they might be 3335 // (Note that we still need to materialize them because they might be
3268 // referred to as duplicated objects.) 3336 // referred to as duplicated objects.)
3269 while (current_slot_ < first_slot_index_) { 3337 while (current_slot_ < first_slot_index_) {
3270 GetNext(isolate, 0); 3338 GetNext(isolate, 0);
3271 } 3339 }
3272 ASSERT(current_slot_ == first_slot_index_); 3340 CHECK_EQ(current_slot_, first_slot_index_);
3273 } 3341 }
3274 3342
3275 3343
3276 Handle<Object> SlotRefValueBuilder::GetPreviouslyMaterialized( 3344 Handle<Object> SlotRefValueBuilder::GetPreviouslyMaterialized(
3277 Isolate* isolate, int length) { 3345 Isolate* isolate, int length) {
3278 int object_index = materialized_objects_.length(); 3346 int object_index = materialized_objects_.length();
3279 Handle<Object> return_value = Handle<Object>( 3347 Handle<Object> return_value = Handle<Object>(
3280 previously_materialized_objects_->get(object_index), isolate); 3348 previously_materialized_objects_->get(object_index), isolate);
3281 materialized_objects_.Add(return_value); 3349 materialized_objects_.Add(return_value);
3282 3350
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3324 materialized_objects_.Add(isolate->factory()->undefined_value()); 3392 materialized_objects_.Add(isolate->factory()->undefined_value());
3325 int length = slot.GetChildrenCount(); 3393 int length = slot.GetChildrenCount();
3326 for (int i = 0; i < length; ++i) { 3394 for (int i = 0; i < length; ++i) {
3327 // We don't need the argument, just ignore it 3395 // We don't need the argument, just ignore it
3328 GetNext(isolate, lvl + 1); 3396 GetNext(isolate, lvl + 1);
3329 } 3397 }
3330 return isolate->factory()->undefined_value(); 3398 return isolate->factory()->undefined_value();
3331 } 3399 }
3332 case SlotRef::DEFERRED_OBJECT: { 3400 case SlotRef::DEFERRED_OBJECT: {
3333 int length = slot.GetChildrenCount(); 3401 int length = slot.GetChildrenCount();
3334 ASSERT(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL || 3402 CHECK(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL ||
3335 slot_refs_[current_slot_].Representation() == SlotRef::TAGGED); 3403 slot_refs_[current_slot_].Representation() == SlotRef::TAGGED);
3336 3404
3337 int object_index = materialized_objects_.length(); 3405 int object_index = materialized_objects_.length();
3338 if (object_index < prev_materialized_count_) { 3406 if (object_index < prev_materialized_count_) {
3339 return GetPreviouslyMaterialized(isolate, length); 3407 return GetPreviouslyMaterialized(isolate, length);
3340 } 3408 }
3341 3409
3342 Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate); 3410 Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate);
3343 Handle<Map> map = Map::GeneralizeAllFieldRepresentations( 3411 Handle<Map> map = Map::GeneralizeAllFieldRepresentations(
3344 Handle<Map>::cast(map_object), Representation::Tagged()); 3412 Handle<Map>::cast(map_object), Representation::Tagged());
3345 current_slot_++; 3413 current_slot_++;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3386 object->set_length(*length); 3454 object->set_length(*length);
3387 return object; 3455 return object;
3388 } 3456 }
3389 default: 3457 default:
3390 PrintF(stderr, 3458 PrintF(stderr,
3391 "[couldn't handle instance type %d]\n", map->instance_type()); 3459 "[couldn't handle instance type %d]\n", map->instance_type());
3392 UNREACHABLE(); 3460 UNREACHABLE();
3393 break; 3461 break;
3394 } 3462 }
3395 UNREACHABLE(); 3463 UNREACHABLE();
3464 break;
3396 } 3465 }
3397 3466
3398 case SlotRef::DUPLICATE_OBJECT: { 3467 case SlotRef::DUPLICATE_OBJECT: {
3399 int object_index = slot.DuplicateObjectId(); 3468 int object_index = slot.DuplicateObjectId();
3400 Handle<Object> object = materialized_objects_[object_index]; 3469 Handle<Object> object = materialized_objects_[object_index];
3401 materialized_objects_.Add(object); 3470 materialized_objects_.Add(object);
3402 return object; 3471 return object;
3403 } 3472 }
3404 default: 3473 default:
3405 UNREACHABLE(); 3474 UNREACHABLE();
3406 break; 3475 break;
3407 } 3476 }
3408 3477
3409 FATAL("We should never get here - unexpected deopt slot kind."); 3478 FATAL("We should never get here - unexpected deopt slot kind.");
3410 return Handle<Object>::null(); 3479 return Handle<Object>::null();
3411 } 3480 }
3412 3481
3413 3482
3414 void SlotRefValueBuilder::Finish(Isolate* isolate) { 3483 void SlotRefValueBuilder::Finish(Isolate* isolate) {
3415 // We should have processed all the slots 3484 // We should have processed all the slots
3416 ASSERT(slot_refs_.length() == current_slot_); 3485 CHECK_EQ(slot_refs_.length(), current_slot_);
3417 3486
3418 if (materialized_objects_.length() > prev_materialized_count_) { 3487 if (materialized_objects_.length() > prev_materialized_count_) {
3419 // We have materialized some new objects, so we have to store them 3488 // We have materialized some new objects, so we have to store them
3420 // to prevent duplicate materialization 3489 // to prevent duplicate materialization
3421 Handle<FixedArray> array = isolate->factory()->NewFixedArray( 3490 Handle<FixedArray> array = isolate->factory()->NewFixedArray(
3422 materialized_objects_.length()); 3491 materialized_objects_.length());
3423 for (int i = 0; i < materialized_objects_.length(); i++) { 3492 for (int i = 0; i < materialized_objects_.length(); i++) {
3424 array->set(i, *(materialized_objects_.at(i))); 3493 array->set(i, *(materialized_objects_.at(i)));
3425 } 3494 }
3426 isolate->materialized_object_store()->Set(stack_frame_id_, array); 3495 isolate->materialized_object_store()->Set(stack_frame_id_, array);
3427 } 3496 }
3428 } 3497 }
3429 3498
3430 3499
3431 Handle<FixedArray> MaterializedObjectStore::Get(Address fp) { 3500 Handle<FixedArray> MaterializedObjectStore::Get(Address fp) {
3432 int index = StackIdToIndex(fp); 3501 int index = StackIdToIndex(fp);
3433 if (index == -1) { 3502 if (index == -1) {
3434 return Handle<FixedArray>::null(); 3503 return Handle<FixedArray>::null();
3435 } 3504 }
3436 Handle<FixedArray> array = GetStackEntries(); 3505 Handle<FixedArray> array = GetStackEntries();
3437 ASSERT(array->length() > index); 3506 CHECK_GT(array->length(), index);
3438 return Handle<FixedArray>::cast(Handle<Object>(array->get(index), 3507 return Handle<FixedArray>::cast(Handle<Object>(array->get(index),
3439 isolate())); 3508 isolate()));
3440 } 3509 }
3441 3510
3442 3511
3443 void MaterializedObjectStore::Set(Address fp, 3512 void MaterializedObjectStore::Set(Address fp,
3444 Handle<FixedArray> materialized_objects) { 3513 Handle<FixedArray> materialized_objects) {
3445 int index = StackIdToIndex(fp); 3514 int index = StackIdToIndex(fp);
3446 if (index == -1) { 3515 if (index == -1) {
3447 index = frame_fps_.length(); 3516 index = frame_fps_.length();
3448 frame_fps_.Add(fp); 3517 frame_fps_.Add(fp);
3449 } 3518 }
3450 3519
3451 Handle<FixedArray> array = EnsureStackEntries(index + 1); 3520 Handle<FixedArray> array = EnsureStackEntries(index + 1);
3452 array->set(index, *materialized_objects); 3521 array->set(index, *materialized_objects);
3453 } 3522 }
3454 3523
3455 3524
3456 void MaterializedObjectStore::Remove(Address fp) { 3525 void MaterializedObjectStore::Remove(Address fp) {
3457 int index = StackIdToIndex(fp); 3526 int index = StackIdToIndex(fp);
3458 ASSERT(index >= 0); 3527 CHECK_GE(index, 0);
3459 3528
3460 frame_fps_.Remove(index); 3529 frame_fps_.Remove(index);
3461 Handle<FixedArray> array = GetStackEntries(); 3530 Handle<FixedArray> array = GetStackEntries();
3462 ASSERT(array->length() > index); 3531 CHECK_LT(index, array->length());
3463 for (int i = index; i < frame_fps_.length(); i++) { 3532 for (int i = index; i < frame_fps_.length(); i++) {
3464 array->set(i, array->get(i + 1)); 3533 array->set(i, array->get(i + 1));
3465 } 3534 }
3466 array->set(frame_fps_.length(), isolate()->heap()->undefined_value()); 3535 array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
3467 } 3536 }
3468 3537
3469 3538
3470 int MaterializedObjectStore::StackIdToIndex(Address fp) { 3539 int MaterializedObjectStore::StackIdToIndex(Address fp) {
3471 for (int i = 0; i < frame_fps_.length(); i++) { 3540 for (int i = 0; i < frame_fps_.length(); i++) {
3472 if (frame_fps_[i] == fp) { 3541 if (frame_fps_[i] == fp) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3520 Address pc = reinterpret_cast<Address>(output_frame->GetPc()); 3589 Address pc = reinterpret_cast<Address>(output_frame->GetPc());
3521 Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc)); 3590 Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc));
3522 source_position_ = code->SourcePosition(pc); 3591 source_position_ = code->SourcePosition(pc);
3523 3592
3524 for (int i = 0; i < expression_count_; i++) { 3593 for (int i = 0; i < expression_count_; i++) {
3525 SetExpression(i, output_frame->GetExpression(i)); 3594 SetExpression(i, output_frame->GetExpression(i));
3526 } 3595 }
3527 3596
3528 if (has_arguments_adaptor) { 3597 if (has_arguments_adaptor) {
3529 output_frame = deoptimizer->output_[frame_index - 1]; 3598 output_frame = deoptimizer->output_[frame_index - 1];
3530 ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR); 3599 CHECK_EQ(output_frame->GetFrameType(), StackFrame::ARGUMENTS_ADAPTOR);
3531 } 3600 }
3532 3601
3533 parameters_count_ = output_frame->ComputeParametersCount(); 3602 parameters_count_ = output_frame->ComputeParametersCount();
3534 parameters_ = new Object*[parameters_count_]; 3603 parameters_ = new Object*[parameters_count_];
3535 for (int i = 0; i < parameters_count_; i++) { 3604 for (int i = 0; i < parameters_count_; i++) {
3536 SetParameter(i, output_frame->GetParameter(i)); 3605 SetParameter(i, output_frame->GetParameter(i));
3537 } 3606 }
3538 } 3607 }
3539 3608
3540 3609
3541 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() { 3610 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
3542 delete[] expression_stack_; 3611 delete[] expression_stack_;
3543 delete[] parameters_; 3612 delete[] parameters_;
3544 } 3613 }
3545 3614
3546 3615
3547 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 3616 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
3548 v->VisitPointer(BitCast<Object**>(&function_)); 3617 v->VisitPointer(BitCast<Object**>(&function_));
3549 v->VisitPointers(parameters_, parameters_ + parameters_count_); 3618 v->VisitPointers(parameters_, parameters_ + parameters_count_);
3550 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 3619 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
3551 } 3620 }
3552 3621
3553 #endif // ENABLE_DEBUGGER_SUPPORT 3622 #endif // ENABLE_DEBUGGER_SUPPORT
3554 3623
3555 } } // namespace v8::internal 3624 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698