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

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: Fix comment, rename Created 6 years, 7 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
« no previous file with comments | « src/deoptimizer.h ('k') | test/mjsunit/regress/regress-359441.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 80 }
81 81
82 82
83 Code* Deoptimizer::FindDeoptimizingCode(Address addr) { 83 Code* Deoptimizer::FindDeoptimizingCode(Address addr) {
84 if (function_->IsHeapObject()) { 84 if (function_->IsHeapObject()) {
85 // Search all deoptimizing code in the native context of the function. 85 // Search all deoptimizing code in the native context of the function.
86 Context* native_context = function_->context()->native_context(); 86 Context* native_context = function_->context()->native_context();
87 Object* element = native_context->DeoptimizedCodeListHead(); 87 Object* element = native_context->DeoptimizedCodeListHead();
88 while (!element->IsUndefined()) { 88 while (!element->IsUndefined()) {
89 Code* code = Code::cast(element); 89 Code* code = Code::cast(element);
90 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 90 CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
91 if (code->contains(addr)) return code; 91 if (code->contains(addr)) return code;
92 element = code->next_code_link(); 92 element = code->next_code_link();
93 } 93 }
94 } 94 }
95 return NULL; 95 return NULL;
96 } 96 }
97 97
98 98
99 // We rely on this function not causing a GC. It is called from generated code 99 // We rely on this function not causing a GC. It is called from generated code
100 // without having a real stack frame in place. 100 // without having a real stack frame in place.
101 Deoptimizer* Deoptimizer::New(JSFunction* function, 101 Deoptimizer* Deoptimizer::New(JSFunction* function,
102 BailoutType type, 102 BailoutType type,
103 unsigned bailout_id, 103 unsigned bailout_id,
104 Address from, 104 Address from,
105 int fp_to_sp_delta, 105 int fp_to_sp_delta,
106 Isolate* isolate) { 106 Isolate* isolate) {
107 Deoptimizer* deoptimizer = new Deoptimizer(isolate, 107 Deoptimizer* deoptimizer = new Deoptimizer(isolate,
108 function, 108 function,
109 type, 109 type,
110 bailout_id, 110 bailout_id,
111 from, 111 from,
112 fp_to_sp_delta, 112 fp_to_sp_delta,
113 NULL); 113 NULL);
114 ASSERT(isolate->deoptimizer_data()->current_ == NULL); 114 CHECK(isolate->deoptimizer_data()->current_ == NULL);
115 isolate->deoptimizer_data()->current_ = deoptimizer; 115 isolate->deoptimizer_data()->current_ = deoptimizer;
116 return deoptimizer; 116 return deoptimizer;
117 } 117 }
118 118
119 119
120 // No larger than 2K on all platforms 120 // No larger than 2K on all platforms
121 static const int kDeoptTableMaxEpilogueCodeSize = 2 * KB; 121 static const int kDeoptTableMaxEpilogueCodeSize = 2 * KB;
122 122
123 123
124 size_t Deoptimizer::GetMaxDeoptTableSize() { 124 size_t Deoptimizer::GetMaxDeoptTableSize() {
125 int entries_size = 125 int entries_size =
126 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_; 126 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
127 int commit_page_size = static_cast<int>(OS::CommitPageSize()); 127 int commit_page_size = static_cast<int>(OS::CommitPageSize());
128 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) / 128 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
129 commit_page_size) + 1; 129 commit_page_size) + 1;
130 return static_cast<size_t>(commit_page_size * page_count); 130 return static_cast<size_t>(commit_page_size * page_count);
131 } 131 }
132 132
133 133
134 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { 134 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
135 Deoptimizer* result = isolate->deoptimizer_data()->current_; 135 Deoptimizer* result = isolate->deoptimizer_data()->current_;
136 ASSERT(result != NULL); 136 CHECK_NE(result, NULL);
137 result->DeleteFrameDescriptions(); 137 result->DeleteFrameDescriptions();
138 isolate->deoptimizer_data()->current_ = NULL; 138 isolate->deoptimizer_data()->current_ = NULL;
139 return result; 139 return result;
140 } 140 }
141 141
142 142
143 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) { 143 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
144 if (jsframe_index == 0) return 0; 144 if (jsframe_index == 0) return 0;
145 145
146 int frame_index = 0; 146 int frame_index = 0;
147 while (jsframe_index >= 0) { 147 while (jsframe_index >= 0) {
148 FrameDescription* frame = output_[frame_index]; 148 FrameDescription* frame = output_[frame_index];
149 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) { 149 if (frame->GetFrameType() == StackFrame::JAVA_SCRIPT) {
150 jsframe_index--; 150 jsframe_index--;
151 } 151 }
152 frame_index++; 152 frame_index++;
153 } 153 }
154 154
155 return frame_index - 1; 155 return frame_index - 1;
156 } 156 }
157 157
158 158
159 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( 159 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
160 JavaScriptFrame* frame, 160 JavaScriptFrame* frame,
161 int jsframe_index, 161 int jsframe_index,
162 Isolate* isolate) { 162 Isolate* isolate) {
163 ASSERT(frame->is_optimized()); 163 CHECK(frame->is_optimized());
164 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL); 164 CHECK(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
165 165
166 // Get the function and code from the frame. 166 // Get the function and code from the frame.
167 JSFunction* function = frame->function(); 167 JSFunction* function = frame->function();
168 Code* code = frame->LookupCode(); 168 Code* code = frame->LookupCode();
169 169
170 // Locate the deoptimization point in the code. As we are at a call the 170 // Locate the deoptimization point in the code. As we are at a call the
171 // return address must be at a place in the code with deoptimization support. 171 // return address must be at a place in the code with deoptimization support.
172 SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc()); 172 SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
173 int deoptimization_index = safepoint_entry.deoptimization_index(); 173 int deoptimization_index = safepoint_entry.deoptimization_index();
174 ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex); 174 CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex);
175 175
176 // Always use the actual stack slots when calculating the fp to sp 176 // Always use the actual stack slots when calculating the fp to sp
177 // delta adding two for the function and context. 177 // delta adding two for the function and context.
178 unsigned stack_slots = code->stack_slots(); 178 unsigned stack_slots = code->stack_slots();
179 unsigned fp_to_sp_delta = (stack_slots * kPointerSize) + 179 unsigned fp_to_sp_delta = (stack_slots * kPointerSize) +
180 StandardFrameConstants::kFixedFrameSizeFromFp; 180 StandardFrameConstants::kFixedFrameSizeFromFp;
181 181
182 Deoptimizer* deoptimizer = new Deoptimizer(isolate, 182 Deoptimizer* deoptimizer = new Deoptimizer(isolate,
183 function, 183 function,
184 Deoptimizer::DEBUGGER, 184 Deoptimizer::DEBUGGER,
185 deoptimization_index, 185 deoptimization_index,
186 frame->pc(), 186 frame->pc(),
187 fp_to_sp_delta, 187 fp_to_sp_delta,
188 code); 188 code);
189 Address tos = frame->fp() - fp_to_sp_delta; 189 Address tos = frame->fp() - fp_to_sp_delta;
190 deoptimizer->FillInputFrame(tos, frame); 190 deoptimizer->FillInputFrame(tos, frame);
191 191
192 // Calculate the output frames. 192 // Calculate the output frames.
193 Deoptimizer::ComputeOutputFrames(deoptimizer); 193 Deoptimizer::ComputeOutputFrames(deoptimizer);
194 194
195 // Create the GC safe output frame information and register it for GC 195 // Create the GC safe output frame information and register it for GC
196 // handling. 196 // handling.
197 ASSERT_LT(jsframe_index, deoptimizer->jsframe_count()); 197 CHECK_LT(jsframe_index, deoptimizer->jsframe_count());
198 198
199 // Convert JS frame index into frame index. 199 // Convert JS frame index into frame index.
200 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index); 200 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
201 201
202 bool has_arguments_adaptor = 202 bool has_arguments_adaptor =
203 frame_index > 0 && 203 frame_index > 0 &&
204 deoptimizer->output_[frame_index - 1]->GetFrameType() == 204 deoptimizer->output_[frame_index - 1]->GetFrameType() ==
205 StackFrame::ARGUMENTS_ADAPTOR; 205 StackFrame::ARGUMENTS_ADAPTOR;
206 206
207 int construct_offset = has_arguments_adaptor ? 2 : 1; 207 int construct_offset = has_arguments_adaptor ? 2 : 1;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 239
240 // Finished using the deoptimizer instance. 240 // Finished using the deoptimizer instance.
241 delete deoptimizer; 241 delete deoptimizer;
242 242
243 return info; 243 return info;
244 } 244 }
245 245
246 246
247 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 247 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
248 Isolate* isolate) { 248 Isolate* isolate) {
249 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info); 249 CHECK_EQ(isolate->deoptimizer_data()->deoptimized_frame_info_, info);
250 delete info; 250 delete info;
251 isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL; 251 isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
252 } 252 }
253 253
254 254
255 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, 255 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
256 int count, 256 int count,
257 BailoutType type) { 257 BailoutType type) {
258 TableEntryGenerator generator(masm, type, count); 258 TableEntryGenerator generator(masm, type, count);
259 generator.Generate(); 259 generator.Generate();
260 } 260 }
261 261
262 262
263 void Deoptimizer::VisitAllOptimizedFunctionsForContext( 263 void Deoptimizer::VisitAllOptimizedFunctionsForContext(
264 Context* context, OptimizedFunctionVisitor* visitor) { 264 Context* context, OptimizedFunctionVisitor* visitor) {
265 DisallowHeapAllocation no_allocation; 265 DisallowHeapAllocation no_allocation;
266 266
267 ASSERT(context->IsNativeContext()); 267 CHECK(context->IsNativeContext());
268 268
269 visitor->EnterContext(context); 269 visitor->EnterContext(context);
270 270
271 // Visit the list of optimized functions, removing elements that 271 // Visit the list of optimized functions, removing elements that
272 // no longer refer to optimized code. 272 // no longer refer to optimized code.
273 JSFunction* prev = NULL; 273 JSFunction* prev = NULL;
274 Object* element = context->OptimizedFunctionsListHead(); 274 Object* element = context->OptimizedFunctionsListHead();
275 while (!element->IsUndefined()) { 275 while (!element->IsUndefined()) {
276 JSFunction* function = JSFunction::cast(element); 276 JSFunction* function = JSFunction::cast(element);
277 Object* next = function->next_function_link(); 277 Object* next = function->next_function_link();
278 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION || 278 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
279 (visitor->VisitFunction(function), 279 (visitor->VisitFunction(function),
280 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) { 280 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
281 // The function no longer refers to optimized code, or the visitor 281 // The function no longer refers to optimized code, or the visitor
282 // changed the code to which it refers to no longer be optimized code. 282 // changed the code to which it refers to no longer be optimized code.
283 // Remove the function from this list. 283 // Remove the function from this list.
284 if (prev != NULL) { 284 if (prev != NULL) {
285 prev->set_next_function_link(next); 285 prev->set_next_function_link(next);
286 } else { 286 } else {
287 context->SetOptimizedFunctionsListHead(next); 287 context->SetOptimizedFunctionsListHead(next);
288 } 288 }
289 // The visitor should not alter the link directly. 289 // The visitor should not alter the link directly.
290 ASSERT(function->next_function_link() == next); 290 CHECK_EQ(function->next_function_link(), next);
291 // Set the next function link to undefined to indicate it is no longer 291 // Set the next function link to undefined to indicate it is no longer
292 // in the optimized functions list. 292 // in the optimized functions list.
293 function->set_next_function_link(context->GetHeap()->undefined_value()); 293 function->set_next_function_link(context->GetHeap()->undefined_value());
294 } else { 294 } else {
295 // The visitor should not alter the link directly. 295 // The visitor should not alter the link directly.
296 ASSERT(function->next_function_link() == next); 296 CHECK_EQ(function->next_function_link(), next);
297 // preserve this element. 297 // preserve this element.
298 prev = function; 298 prev = function;
299 } 299 }
300 element = next; 300 element = next;
301 } 301 }
302 302
303 visitor->LeaveContext(context); 303 visitor->LeaveContext(context);
304 } 304 }
305 305
306 306
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // Move marked code from the optimized code list to the deoptimized 388 // Move marked code from the optimized code list to the deoptimized
389 // code list, collecting them into a ZoneList. 389 // code list, collecting them into a ZoneList.
390 Zone zone(isolate); 390 Zone zone(isolate);
391 ZoneList<Code*> codes(10, &zone); 391 ZoneList<Code*> codes(10, &zone);
392 392
393 // Walk over all optimized code objects in this native context. 393 // Walk over all optimized code objects in this native context.
394 Code* prev = NULL; 394 Code* prev = NULL;
395 Object* element = context->OptimizedCodeListHead(); 395 Object* element = context->OptimizedCodeListHead();
396 while (!element->IsUndefined()) { 396 while (!element->IsUndefined()) {
397 Code* code = Code::cast(element); 397 Code* code = Code::cast(element);
398 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 398 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
399 Object* next = code->next_code_link(); 399 Object* next = code->next_code_link();
400 if (code->marked_for_deoptimization()) { 400 if (code->marked_for_deoptimization()) {
401 // Put the code into the list for later patching. 401 // Put the code into the list for later patching.
402 codes.Add(code, &zone); 402 codes.Add(code, &zone);
403 403
404 if (prev != NULL) { 404 if (prev != NULL) {
405 // Skip this code in the optimized code list. 405 // Skip this code in the optimized code list.
406 prev->set_next_code_link(next); 406 prev->set_next_code_link(next);
407 } else { 407 } else {
408 // There was no previous node, the next node is the new head. 408 // There was no previous node, the next node is the new head.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 476
477 477
478 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) { 478 void Deoptimizer::DeoptimizeGlobalObject(JSObject* object) {
479 if (FLAG_trace_deopt) { 479 if (FLAG_trace_deopt) {
480 CodeTracer::Scope scope(object->GetHeap()->isolate()->GetCodeTracer()); 480 CodeTracer::Scope scope(object->GetHeap()->isolate()->GetCodeTracer());
481 PrintF(scope.file(), "[deoptimize global object @ 0x%08" V8PRIxPTR "]\n", 481 PrintF(scope.file(), "[deoptimize global object @ 0x%08" V8PRIxPTR "]\n",
482 reinterpret_cast<intptr_t>(object)); 482 reinterpret_cast<intptr_t>(object));
483 } 483 }
484 if (object->IsJSGlobalProxy()) { 484 if (object->IsJSGlobalProxy()) {
485 Object* proto = object->GetPrototype(); 485 Object* proto = object->GetPrototype();
486 ASSERT(proto->IsJSGlobalObject()); 486 CHECK(proto->IsJSGlobalObject());
487 Context* native_context = GlobalObject::cast(proto)->native_context(); 487 Context* native_context = GlobalObject::cast(proto)->native_context();
488 MarkAllCodeForContext(native_context); 488 MarkAllCodeForContext(native_context);
489 DeoptimizeMarkedCodeForContext(native_context); 489 DeoptimizeMarkedCodeForContext(native_context);
490 } else if (object->IsGlobalObject()) { 490 } else if (object->IsGlobalObject()) {
491 Context* native_context = GlobalObject::cast(object)->native_context(); 491 Context* native_context = GlobalObject::cast(object)->native_context();
492 MarkAllCodeForContext(native_context); 492 MarkAllCodeForContext(native_context);
493 DeoptimizeMarkedCodeForContext(native_context); 493 DeoptimizeMarkedCodeForContext(native_context);
494 } 494 }
495 } 495 }
496 496
497 497
498 void Deoptimizer::MarkAllCodeForContext(Context* context) { 498 void Deoptimizer::MarkAllCodeForContext(Context* context) {
499 Object* element = context->OptimizedCodeListHead(); 499 Object* element = context->OptimizedCodeListHead();
500 while (!element->IsUndefined()) { 500 while (!element->IsUndefined()) {
501 Code* code = Code::cast(element); 501 Code* code = Code::cast(element);
502 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 502 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
503 code->set_marked_for_deoptimization(true); 503 code->set_marked_for_deoptimization(true);
504 element = code->next_code_link(); 504 element = code->next_code_link();
505 } 505 }
506 } 506 }
507 507
508 508
509 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { 509 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
510 Code* code = function->code(); 510 Code* code = function->code();
511 if (code->kind() == Code::OPTIMIZED_FUNCTION) { 511 if (code->kind() == Code::OPTIMIZED_FUNCTION) {
512 // Mark the code for deoptimization and unlink any functions that also 512 // Mark the code for deoptimization and unlink any functions that also
(...skipping 14 matching lines...) Expand all
527 StackFrame::Type frame_type) { 527 StackFrame::Type frame_type) {
528 switch (deopt_type) { 528 switch (deopt_type) {
529 case EAGER: 529 case EAGER:
530 case SOFT: 530 case SOFT:
531 case LAZY: 531 case LAZY:
532 case DEBUGGER: 532 case DEBUGGER:
533 return (frame_type == StackFrame::STUB) 533 return (frame_type == StackFrame::STUB)
534 ? FLAG_trace_stub_failures 534 ? FLAG_trace_stub_failures
535 : FLAG_trace_deopt; 535 : FLAG_trace_deopt;
536 } 536 }
537 UNREACHABLE(); 537 FATAL("Unsupported deopt type");
538 return false; 538 return false;
539 } 539 }
540 540
541 541
542 const char* Deoptimizer::MessageFor(BailoutType type) { 542 const char* Deoptimizer::MessageFor(BailoutType type) {
543 switch (type) { 543 switch (type) {
544 case EAGER: return "eager"; 544 case EAGER: return "eager";
545 case SOFT: return "soft"; 545 case SOFT: return "soft";
546 case LAZY: return "lazy"; 546 case LAZY: return "lazy";
547 case DEBUGGER: return "debugger"; 547 case DEBUGGER: return "debugger";
548 } 548 }
549 UNREACHABLE(); 549 FATAL("Unsupported deopt type");
550 return NULL; 550 return NULL;
551 } 551 }
552 552
553 553
554 Deoptimizer::Deoptimizer(Isolate* isolate, 554 Deoptimizer::Deoptimizer(Isolate* isolate,
555 JSFunction* function, 555 JSFunction* function,
556 BailoutType type, 556 BailoutType type,
557 unsigned bailout_id, 557 unsigned bailout_id,
558 Address from, 558 Address from,
559 int fp_to_sp_delta, 559 int fp_to_sp_delta,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 case Deoptimizer::LAZY: { 629 case Deoptimizer::LAZY: {
630 Code* compiled_code = FindDeoptimizingCode(from_); 630 Code* compiled_code = FindDeoptimizingCode(from_);
631 return (compiled_code == NULL) 631 return (compiled_code == NULL)
632 ? static_cast<Code*>(isolate_->FindCodeObject(from_)) 632 ? static_cast<Code*>(isolate_->FindCodeObject(from_))
633 : compiled_code; 633 : compiled_code;
634 } 634 }
635 case Deoptimizer::DEBUGGER: 635 case Deoptimizer::DEBUGGER:
636 ASSERT(optimized_code->contains(from_)); 636 ASSERT(optimized_code->contains(from_));
637 return optimized_code; 637 return optimized_code;
638 } 638 }
639 UNREACHABLE(); 639 FATAL("Could not find code for optimized function");
640 return NULL; 640 return NULL;
641 } 641 }
642 642
643 643
644 void Deoptimizer::PrintFunctionName() { 644 void Deoptimizer::PrintFunctionName() {
645 if (function_->IsJSFunction()) { 645 if (function_->IsJSFunction()) {
646 function_->PrintName(trace_scope_->file()); 646 function_->PrintName(trace_scope_->file());
647 } else { 647 } else {
648 PrintF(trace_scope_->file(), 648 PrintF(trace_scope_->file(),
649 "%s", Code::Kind2String(compiled_code_->kind())); 649 "%s", Code::Kind2String(compiled_code_->kind()));
(...skipping 22 matching lines...) Expand all
672 delete disallow_heap_allocation_; 672 delete disallow_heap_allocation_;
673 disallow_heap_allocation_ = NULL; 673 disallow_heap_allocation_ = NULL;
674 #endif // DEBUG 674 #endif // DEBUG
675 } 675 }
676 676
677 677
678 Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate, 678 Address Deoptimizer::GetDeoptimizationEntry(Isolate* isolate,
679 int id, 679 int id,
680 BailoutType type, 680 BailoutType type,
681 GetEntryMode mode) { 681 GetEntryMode mode) {
682 ASSERT(id >= 0); 682 CHECK_GE(id, 0);
683 if (id >= kMaxNumberOfEntries) return NULL; 683 if (id >= kMaxNumberOfEntries) return NULL;
684 if (mode == ENSURE_ENTRY_CODE) { 684 if (mode == ENSURE_ENTRY_CODE) {
685 EnsureCodeForDeoptimizationEntry(isolate, type, id); 685 EnsureCodeForDeoptimizationEntry(isolate, type, id);
686 } else { 686 } else {
687 ASSERT(mode == CALCULATE_ENTRY_ADDRESS); 687 CHECK_EQ(mode, CALCULATE_ENTRY_ADDRESS);
688 } 688 }
689 DeoptimizerData* data = isolate->deoptimizer_data(); 689 DeoptimizerData* data = isolate->deoptimizer_data();
690 ASSERT(type < kBailoutTypesWithCodeEntry); 690 CHECK_LT(type, kBailoutTypesWithCodeEntry);
691 MemoryChunk* base = data->deopt_entry_code_[type]; 691 MemoryChunk* base = data->deopt_entry_code_[type];
692 return base->area_start() + (id * table_entry_size_); 692 return base->area_start() + (id * table_entry_size_);
693 } 693 }
694 694
695 695
696 int Deoptimizer::GetDeoptimizationId(Isolate* isolate, 696 int Deoptimizer::GetDeoptimizationId(Isolate* isolate,
697 Address addr, 697 Address addr,
698 BailoutType type) { 698 BailoutType type) {
699 DeoptimizerData* data = isolate->deoptimizer_data(); 699 DeoptimizerData* data = isolate->deoptimizer_data();
700 MemoryChunk* base = data->deopt_entry_code_[type]; 700 MemoryChunk* base = data->deopt_entry_code_[type];
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 case Translation::INT32_REGISTER: 843 case Translation::INT32_REGISTER:
844 case Translation::UINT32_REGISTER: 844 case Translation::UINT32_REGISTER:
845 case Translation::DOUBLE_REGISTER: 845 case Translation::DOUBLE_REGISTER:
846 case Translation::STACK_SLOT: 846 case Translation::STACK_SLOT:
847 case Translation::INT32_STACK_SLOT: 847 case Translation::INT32_STACK_SLOT:
848 case Translation::UINT32_STACK_SLOT: 848 case Translation::UINT32_STACK_SLOT:
849 case Translation::DOUBLE_STACK_SLOT: 849 case Translation::DOUBLE_STACK_SLOT:
850 case Translation::LITERAL: 850 case Translation::LITERAL:
851 case Translation::ARGUMENTS_OBJECT: 851 case Translation::ARGUMENTS_OBJECT:
852 default: 852 default:
853 UNREACHABLE(); 853 FATAL("Unsupported translation");
854 break; 854 break;
855 } 855 }
856 } 856 }
857 857
858 // Print some helpful diagnostic information. 858 // Print some helpful diagnostic information.
859 if (trace_scope_ != NULL) { 859 if (trace_scope_ != NULL) {
860 double ms = timer.Elapsed().InMillisecondsF(); 860 double ms = timer.Elapsed().InMillisecondsF();
861 int index = output_count_ - 1; // Index of the topmost frame. 861 int index = output_count_ - 1; // Index of the topmost frame.
862 JSFunction* function = output_[index]->GetFunction(); 862 JSFunction* function = output_[index]->GetFunction();
863 PrintF(trace_scope_->file(), 863 PrintF(trace_scope_->file(),
(...skipping 18 matching lines...) Expand all
882 882
883 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 883 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
884 int frame_index) { 884 int frame_index) {
885 BailoutId node_id = BailoutId(iterator->Next()); 885 BailoutId node_id = BailoutId(iterator->Next());
886 JSFunction* function; 886 JSFunction* function;
887 if (frame_index != 0) { 887 if (frame_index != 0) {
888 function = JSFunction::cast(ComputeLiteral(iterator->Next())); 888 function = JSFunction::cast(ComputeLiteral(iterator->Next()));
889 } else { 889 } else {
890 int closure_id = iterator->Next(); 890 int closure_id = iterator->Next();
891 USE(closure_id); 891 USE(closure_id);
892 ASSERT_EQ(Translation::kSelfLiteralId, closure_id); 892 CHECK_EQ(Translation::kSelfLiteralId, closure_id);
893 function = function_; 893 function = function_;
894 } 894 }
895 unsigned height = iterator->Next(); 895 unsigned height = iterator->Next();
896 unsigned height_in_bytes = height * kPointerSize; 896 unsigned height_in_bytes = height * kPointerSize;
897 if (trace_scope_ != NULL) { 897 if (trace_scope_ != NULL) {
898 PrintF(trace_scope_->file(), " translating "); 898 PrintF(trace_scope_->file(), " translating ");
899 function->PrintName(trace_scope_->file()); 899 function->PrintName(trace_scope_->file());
900 PrintF(trace_scope_->file(), 900 PrintF(trace_scope_->file(),
901 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes); 901 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
902 } 902 }
903 903
904 // The 'fixed' part of the frame consists of the incoming parameters and 904 // The 'fixed' part of the frame consists of the incoming parameters and
905 // the part described by JavaScriptFrameConstants. 905 // the part described by JavaScriptFrameConstants.
906 unsigned fixed_frame_size = ComputeFixedSize(function); 906 unsigned fixed_frame_size = ComputeFixedSize(function);
907 unsigned input_frame_size = input_->GetFrameSize(); 907 unsigned input_frame_size = input_->GetFrameSize();
908 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 908 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
909 909
910 // Allocate and store the output frame description. 910 // Allocate and store the output frame description.
911 FrameDescription* output_frame = 911 FrameDescription* output_frame =
912 new(output_frame_size) FrameDescription(output_frame_size, function); 912 new(output_frame_size) FrameDescription(output_frame_size, function);
913 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT); 913 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
914 914
915 bool is_bottommost = (0 == frame_index); 915 bool is_bottommost = (0 == frame_index);
916 bool is_topmost = (output_count_ - 1 == frame_index); 916 bool is_topmost = (output_count_ - 1 == frame_index);
917 ASSERT(frame_index >= 0 && frame_index < output_count_); 917 CHECK(frame_index >= 0 && frame_index < output_count_);
918 ASSERT(output_[frame_index] == NULL); 918 CHECK_EQ(output_[frame_index], NULL);
919 output_[frame_index] = output_frame; 919 output_[frame_index] = output_frame;
920 920
921 // The top address for the bottommost output frame can be computed from 921 // The top address for the bottommost output frame can be computed from
922 // the input frame pointer and the output frame's height. For all 922 // the input frame pointer and the output frame's height. For all
923 // subsequent output frames, it can be computed from the previous one's 923 // subsequent output frames, it can be computed from the previous one's
924 // top address and the current frame's size. 924 // top address and the current frame's size.
925 Register fp_reg = JavaScriptFrame::fp_register(); 925 Register fp_reg = JavaScriptFrame::fp_register();
926 intptr_t top_address; 926 intptr_t top_address;
927 if (is_bottommost) { 927 if (is_bottommost) {
928 // Determine whether the input frame contains alignment padding. 928 // Determine whether the input frame contains alignment padding.
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1052 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1053 V8PRIxPTR "; function\n", 1053 V8PRIxPTR "; function\n",
1054 top_address + output_offset, output_offset, value); 1054 top_address + output_offset, output_offset, value);
1055 } 1055 }
1056 1056
1057 // Translate the rest of the frame. 1057 // Translate the rest of the frame.
1058 for (unsigned i = 0; i < height; ++i) { 1058 for (unsigned i = 0; i < height; ++i) {
1059 output_offset -= kPointerSize; 1059 output_offset -= kPointerSize;
1060 DoTranslateCommand(iterator, frame_index, output_offset); 1060 DoTranslateCommand(iterator, frame_index, output_offset);
1061 } 1061 }
1062 ASSERT(0 == output_offset); 1062 CHECK_EQ(0, output_offset);
1063 1063
1064 // Compute this frame's PC, state, and continuation. 1064 // Compute this frame's PC, state, and continuation.
1065 Code* non_optimized_code = function->shared()->code(); 1065 Code* non_optimized_code = function->shared()->code();
1066 FixedArray* raw_data = non_optimized_code->deoptimization_data(); 1066 FixedArray* raw_data = non_optimized_code->deoptimization_data();
1067 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data); 1067 DeoptimizationOutputData* data = DeoptimizationOutputData::cast(raw_data);
1068 Address start = non_optimized_code->instruction_start(); 1068 Address start = non_optimized_code->instruction_start();
1069 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared()); 1069 unsigned pc_and_state = GetOutputInfo(data, node_id, function->shared());
1070 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state); 1070 unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
1071 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset); 1071 intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
1072 output_frame->SetPc(pc_value); 1072 output_frame->SetPc(pc_value);
(...skipping 16 matching lines...) Expand all
1089 1089
1090 // Set the continuation for the topmost frame. 1090 // Set the continuation for the topmost frame.
1091 if (is_topmost && bailout_type_ != DEBUGGER) { 1091 if (is_topmost && bailout_type_ != DEBUGGER) {
1092 Builtins* builtins = isolate_->builtins(); 1092 Builtins* builtins = isolate_->builtins();
1093 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized); 1093 Code* continuation = builtins->builtin(Builtins::kNotifyDeoptimized);
1094 if (bailout_type_ == LAZY) { 1094 if (bailout_type_ == LAZY) {
1095 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized); 1095 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1096 } else if (bailout_type_ == SOFT) { 1096 } else if (bailout_type_ == SOFT) {
1097 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized); 1097 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1098 } else { 1098 } else {
1099 ASSERT(bailout_type_ == EAGER); 1099 CHECK_EQ(bailout_type_, EAGER);
1100 } 1100 }
1101 output_frame->SetContinuation( 1101 output_frame->SetContinuation(
1102 reinterpret_cast<intptr_t>(continuation->entry())); 1102 reinterpret_cast<intptr_t>(continuation->entry()));
1103 } 1103 }
1104 } 1104 }
1105 1105
1106 1106
1107 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 1107 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
1108 int frame_index) { 1108 int frame_index) {
1109 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 1109 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
1110 unsigned height = iterator->Next(); 1110 unsigned height = iterator->Next();
1111 unsigned height_in_bytes = height * kPointerSize; 1111 unsigned height_in_bytes = height * kPointerSize;
1112 if (trace_scope_ != NULL) { 1112 if (trace_scope_ != NULL) {
1113 PrintF(trace_scope_->file(), 1113 PrintF(trace_scope_->file(),
1114 " translating arguments adaptor => height=%d\n", height_in_bytes); 1114 " translating arguments adaptor => height=%d\n", height_in_bytes);
1115 } 1115 }
1116 1116
1117 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; 1117 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
1118 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1118 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1119 1119
1120 // Allocate and store the output frame description. 1120 // Allocate and store the output frame description.
1121 FrameDescription* output_frame = 1121 FrameDescription* output_frame =
1122 new(output_frame_size) FrameDescription(output_frame_size, function); 1122 new(output_frame_size) FrameDescription(output_frame_size, function);
1123 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); 1123 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
1124 1124
1125 // Arguments adaptor can not be topmost or bottommost. 1125 // Arguments adaptor can not be topmost or bottommost.
1126 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 1126 CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1127 ASSERT(output_[frame_index] == NULL); 1127 CHECK(output_[frame_index] == NULL);
1128 output_[frame_index] = output_frame; 1128 output_[frame_index] = output_frame;
1129 1129
1130 // The top address of the frame is computed from the previous 1130 // The top address of the frame is computed from the previous
1131 // frame's top and this frame's size. 1131 // frame's top and this frame's size.
1132 intptr_t top_address; 1132 intptr_t top_address;
1133 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1133 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1134 output_frame->SetTop(top_address); 1134 output_frame->SetTop(top_address);
1135 1135
1136 // Compute the incoming parameter translation. 1136 // Compute the incoming parameter translation.
1137 int parameter_count = height; 1137 int parameter_count = height;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 int parameter_count = height; 1263 int parameter_count = height;
1264 unsigned output_offset = output_frame_size; 1264 unsigned output_offset = output_frame_size;
1265 for (int i = 0; i < parameter_count; ++i) { 1265 for (int i = 0; i < parameter_count; ++i) {
1266 output_offset -= kPointerSize; 1266 output_offset -= kPointerSize;
1267 int deferred_object_index = deferred_objects_.length(); 1267 int deferred_object_index = deferred_objects_.length();
1268 DoTranslateCommand(iterator, frame_index, output_offset); 1268 DoTranslateCommand(iterator, frame_index, output_offset);
1269 // The allocated receiver of a construct stub frame is passed as the 1269 // The allocated receiver of a construct stub frame is passed as the
1270 // receiver parameter through the translation. It might be encoding 1270 // receiver parameter through the translation. It might be encoding
1271 // a captured object, patch the slot address for a captured object. 1271 // a captured object, patch the slot address for a captured object.
1272 if (i == 0 && deferred_objects_.length() > deferred_object_index) { 1272 if (i == 0 && deferred_objects_.length() > deferred_object_index) {
1273 ASSERT(!deferred_objects_[deferred_object_index].is_arguments()); 1273 CHECK(!deferred_objects_[deferred_object_index].is_arguments());
1274 deferred_objects_[deferred_object_index].patch_slot_address(top_address); 1274 deferred_objects_[deferred_object_index].patch_slot_address(top_address);
1275 } 1275 }
1276 } 1276 }
1277 1277
1278 // Read caller's PC from the previous frame. 1278 // Read caller's PC from the previous frame.
1279 output_offset -= kPCOnStackSize; 1279 output_offset -= kPCOnStackSize;
1280 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 1280 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
1281 output_frame->SetCallerPc(output_offset, callers_pc); 1281 output_frame->SetCallerPc(output_offset, callers_pc);
1282 if (trace_scope_ != NULL) { 1282 if (trace_scope_ != NULL) {
1283 PrintF(trace_scope_->file(), 1283 PrintF(trace_scope_->file(),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 output_offset -= kPointerSize; 1374 output_offset -= kPointerSize;
1375 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); 1375 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1376 output_frame->SetFrameSlot(output_offset, value); 1376 output_frame->SetFrameSlot(output_offset, value);
1377 if (trace_scope_ != NULL) { 1377 if (trace_scope_ != NULL) {
1378 PrintF(trace_scope_->file(), 1378 PrintF(trace_scope_->file(),
1379 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1379 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1380 V8PRIxPTR " ; allocated receiver\n", 1380 V8PRIxPTR " ; allocated receiver\n",
1381 top_address + output_offset, output_offset, value); 1381 top_address + output_offset, output_offset, value);
1382 } 1382 }
1383 1383
1384 ASSERT(0 == output_offset); 1384 CHECK_EQ(0, output_offset);
1385 1385
1386 intptr_t pc = reinterpret_cast<intptr_t>( 1386 intptr_t pc = reinterpret_cast<intptr_t>(
1387 construct_stub->instruction_start() + 1387 construct_stub->instruction_start() +
1388 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 1388 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
1389 output_frame->SetPc(pc); 1389 output_frame->SetPc(pc);
1390 if (FLAG_enable_ool_constant_pool) { 1390 if (FLAG_enable_ool_constant_pool) {
1391 intptr_t constant_pool_value = 1391 intptr_t constant_pool_value =
1392 reinterpret_cast<intptr_t>(construct_stub->constant_pool()); 1392 reinterpret_cast<intptr_t>(construct_stub->constant_pool());
1393 output_frame->SetConstantPool(constant_pool_value); 1393 output_frame->SetConstantPool(constant_pool_value);
1394 } 1394 }
(...skipping 25 matching lines...) Expand all
1420 (is_setter_stub_frame ? 1 : 0); 1420 (is_setter_stub_frame ? 1 : 0);
1421 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; 1421 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize;
1422 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 1422 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1423 1423
1424 // Allocate and store the output frame description. 1424 // Allocate and store the output frame description.
1425 FrameDescription* output_frame = 1425 FrameDescription* output_frame =
1426 new(output_frame_size) FrameDescription(output_frame_size, accessor); 1426 new(output_frame_size) FrameDescription(output_frame_size, accessor);
1427 output_frame->SetFrameType(StackFrame::INTERNAL); 1427 output_frame->SetFrameType(StackFrame::INTERNAL);
1428 1428
1429 // A frame for an accessor stub can not be the topmost or bottommost one. 1429 // A frame for an accessor stub can not be the topmost or bottommost one.
1430 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 1430 CHECK(frame_index > 0 && frame_index < output_count_ - 1);
1431 ASSERT(output_[frame_index] == NULL); 1431 CHECK_EQ(output_[frame_index], NULL);
1432 output_[frame_index] = output_frame; 1432 output_[frame_index] = output_frame;
1433 1433
1434 // The top address of the frame is computed from the previous frame's top and 1434 // The top address of the frame is computed from the previous frame's top and
1435 // this frame's size. 1435 // this frame's size.
1436 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 1436 intptr_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
1437 output_frame->SetTop(top_address); 1437 output_frame->SetTop(top_address);
1438 1438
1439 unsigned output_offset = output_frame_size; 1439 unsigned output_offset = output_frame_size;
1440 1440
1441 // Read caller's PC from the previous frame. 1441 // Read caller's PC from the previous frame.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1505 value = reinterpret_cast<intptr_t>(accessor_stub); 1505 value = reinterpret_cast<intptr_t>(accessor_stub);
1506 output_frame->SetFrameSlot(output_offset, value); 1506 output_frame->SetFrameSlot(output_offset, value);
1507 if (trace_scope_ != NULL) { 1507 if (trace_scope_ != NULL) {
1508 PrintF(trace_scope_->file(), 1508 PrintF(trace_scope_->file(),
1509 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR 1509 " 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
1510 " ; code object\n", 1510 " ; code object\n",
1511 top_address + output_offset, output_offset, value); 1511 top_address + output_offset, output_offset, value);
1512 } 1512 }
1513 1513
1514 // Skip receiver. 1514 // Skip receiver.
1515 Translation::Opcode opcode = 1515 DoTranslateObjectAndSkip(iterator);
1516 static_cast<Translation::Opcode>(iterator->Next());
1517 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
1518 1516
1519 if (is_setter_stub_frame) { 1517 if (is_setter_stub_frame) {
1520 // The implicit return value was part of the artificial setter stub 1518 // The implicit return value was part of the artificial setter stub
1521 // environment. 1519 // environment.
1522 output_offset -= kPointerSize; 1520 output_offset -= kPointerSize;
1523 DoTranslateCommand(iterator, frame_index, output_offset); 1521 DoTranslateCommand(iterator, frame_index, output_offset);
1524 } 1522 }
1525 1523
1526 ASSERT(0 == output_offset); 1524 CHECK_EQ(output_offset, 0);
1527 1525
1528 Smi* offset = is_setter_stub_frame ? 1526 Smi* offset = is_setter_stub_frame ?
1529 isolate_->heap()->setter_stub_deopt_pc_offset() : 1527 isolate_->heap()->setter_stub_deopt_pc_offset() :
1530 isolate_->heap()->getter_stub_deopt_pc_offset(); 1528 isolate_->heap()->getter_stub_deopt_pc_offset();
1531 intptr_t pc = reinterpret_cast<intptr_t>( 1529 intptr_t pc = reinterpret_cast<intptr_t>(
1532 accessor_stub->instruction_start() + offset->value()); 1530 accessor_stub->instruction_start() + offset->value());
1533 output_frame->SetPc(pc); 1531 output_frame->SetPc(pc);
1534 if (FLAG_enable_ool_constant_pool) { 1532 if (FLAG_enable_ool_constant_pool) {
1535 intptr_t constant_pool_value = 1533 intptr_t constant_pool_value =
1536 reinterpret_cast<intptr_t>(accessor_stub->constant_pool()); 1534 reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
(...skipping 29 matching lines...) Expand all
1566 // and spilled to stack | .... | 1564 // and spilled to stack | .... |
1567 // +-------------------------+ 1565 // +-------------------------+
1568 // | caller stack param n | 1566 // | caller stack param n |
1569 // +-------------------------+<-spreg 1567 // +-------------------------+<-spreg
1570 // reg = number of parameters 1568 // reg = number of parameters
1571 // reg = failure handler address 1569 // reg = failure handler address
1572 // reg = saved frame 1570 // reg = saved frame
1573 // reg = JSFunction context 1571 // reg = JSFunction context
1574 // 1572 //
1575 1573
1576 ASSERT(compiled_code_->is_crankshafted() && 1574 CHECK(compiled_code_->is_crankshafted() &&
1577 compiled_code_->kind() != Code::OPTIMIZED_FUNCTION); 1575 compiled_code_->kind() != Code::OPTIMIZED_FUNCTION);
1578 int major_key = compiled_code_->major_key(); 1576 int major_key = compiled_code_->major_key();
1579 CodeStubInterfaceDescriptor* descriptor = 1577 CodeStubInterfaceDescriptor* descriptor =
1580 isolate_->code_stub_interface_descriptor(major_key); 1578 isolate_->code_stub_interface_descriptor(major_key);
1581 1579
1582 // The output frame must have room for all pushed register parameters 1580 // The output frame must have room for all pushed register parameters
1583 // and the standard stack frame slots. Include space for an argument 1581 // and the standard stack frame slots. Include space for an argument
1584 // object to the callee and optionally the space to pass the argument 1582 // object to the callee and optionally the space to pass the argument
1585 // object to the stub failure handler. 1583 // object to the stub failure handler.
1586 ASSERT(descriptor->register_param_count_ >= 0); 1584 CHECK_GE(descriptor->register_param_count_, 0);
1587 int height_in_bytes = kPointerSize * descriptor->register_param_count_ + 1585 int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
1588 sizeof(Arguments) + kPointerSize; 1586 sizeof(Arguments) + kPointerSize;
1589 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; 1587 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize;
1590 int input_frame_size = input_->GetFrameSize(); 1588 int input_frame_size = input_->GetFrameSize();
1591 int output_frame_size = height_in_bytes + fixed_frame_size; 1589 int output_frame_size = height_in_bytes + fixed_frame_size;
1592 if (trace_scope_ != NULL) { 1590 if (trace_scope_ != NULL) {
1593 PrintF(trace_scope_->file(), 1591 PrintF(trace_scope_->file(),
1594 " translating %s => StubFailureTrampolineStub, height=%d\n", 1592 " translating %s => StubFailureTrampolineStub, height=%d\n",
1595 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), 1593 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false),
1596 height_in_bytes); 1594 height_in_bytes);
1597 } 1595 }
1598 1596
1599 // The stub failure trampoline is a single frame. 1597 // The stub failure trampoline is a single frame.
1600 FrameDescription* output_frame = 1598 FrameDescription* output_frame =
1601 new(output_frame_size) FrameDescription(output_frame_size, NULL); 1599 new(output_frame_size) FrameDescription(output_frame_size, NULL);
1602 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); 1600 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1603 ASSERT(frame_index == 0); 1601 CHECK_EQ(frame_index, 0);
1604 output_[frame_index] = output_frame; 1602 output_[frame_index] = output_frame;
1605 1603
1606 // The top address for the output frame can be computed from the input 1604 // The top address for the output frame can be computed from the input
1607 // frame pointer and the output frame's height. Subtract space for the 1605 // frame pointer and the output frame's height. Subtract space for the
1608 // context and function slots. 1606 // context and function slots.
1609 Register fp_reg = StubFailureTrampolineFrame::fp_register(); 1607 Register fp_reg = StubFailureTrampolineFrame::fp_register();
1610 intptr_t top_address = input_->GetRegister(fp_reg.code()) - 1608 intptr_t top_address = input_->GetRegister(fp_reg.code()) -
1611 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes; 1609 StandardFrameConstants::kFixedFrameSizeFromFp - height_in_bytes;
1612 output_frame->SetTop(top_address); 1610 output_frame->SetTop(top_address);
1613 1611
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 } 1649 }
1652 } 1650 }
1653 1651
1654 // The context can be gotten from the input frame. 1652 // The context can be gotten from the input frame.
1655 Register context_reg = StubFailureTrampolineFrame::context_register(); 1653 Register context_reg = StubFailureTrampolineFrame::context_register();
1656 input_frame_offset -= kPointerSize; 1654 input_frame_offset -= kPointerSize;
1657 value = input_->GetFrameSlot(input_frame_offset); 1655 value = input_->GetFrameSlot(input_frame_offset);
1658 output_frame->SetRegister(context_reg.code(), value); 1656 output_frame->SetRegister(context_reg.code(), value);
1659 output_frame_offset -= kPointerSize; 1657 output_frame_offset -= kPointerSize;
1660 output_frame->SetFrameSlot(output_frame_offset, value); 1658 output_frame->SetFrameSlot(output_frame_offset, value);
1661 ASSERT(reinterpret_cast<Object*>(value)->IsContext()); 1659 CHECK(reinterpret_cast<Object*>(value)->IsContext());
1662 if (trace_scope_ != NULL) { 1660 if (trace_scope_ != NULL) {
1663 PrintF(trace_scope_->file(), 1661 PrintF(trace_scope_->file(),
1664 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1662 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1665 V8PRIxPTR " ; context\n", 1663 V8PRIxPTR " ; context\n",
1666 top_address + output_frame_offset, output_frame_offset, value); 1664 top_address + output_frame_offset, output_frame_offset, value);
1667 } 1665 }
1668 1666
1669 // A marker value is used in place of the function. 1667 // A marker value is used in place of the function.
1670 output_frame_offset -= kPointerSize; 1668 output_frame_offset -= kPointerSize;
1671 value = reinterpret_cast<intptr_t>( 1669 value = reinterpret_cast<intptr_t>(
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 int arguments_length_offset = -1; 1727 int arguments_length_offset = -1;
1730 for (int i = 0; i < descriptor->register_param_count_; ++i) { 1728 for (int i = 0; i < descriptor->register_param_count_; ++i) {
1731 output_frame_offset -= kPointerSize; 1729 output_frame_offset -= kPointerSize;
1732 DoTranslateCommand(iterator, 0, output_frame_offset); 1730 DoTranslateCommand(iterator, 0, output_frame_offset);
1733 1731
1734 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) { 1732 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) {
1735 arguments_length_offset = output_frame_offset; 1733 arguments_length_offset = output_frame_offset;
1736 } 1734 }
1737 } 1735 }
1738 1736
1739 ASSERT(0 == output_frame_offset); 1737 CHECK_EQ(output_frame_offset, 0);
1740 1738
1741 if (!arg_count_known) { 1739 if (!arg_count_known) {
1742 ASSERT(arguments_length_offset >= 0); 1740 CHECK_GE(arguments_length_offset, 0);
1743 // We know it's a smi because 1) the code stub guarantees the stack 1741 // We know it's a smi because 1) the code stub guarantees the stack
1744 // parameter count is in smi range, and 2) the DoTranslateCommand in the 1742 // parameter count is in smi range, and 2) the DoTranslateCommand in the
1745 // parameter loop above translated that to a tagged value. 1743 // parameter loop above translated that to a tagged value.
1746 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( 1744 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>(
1747 output_frame->GetFrameSlot(arguments_length_offset)); 1745 output_frame->GetFrameSlot(arguments_length_offset));
1748 caller_arg_count = smi_caller_arg_count->value(); 1746 caller_arg_count = smi_caller_arg_count->value();
1749 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); 1747 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
1750 if (trace_scope_ != NULL) { 1748 if (trace_scope_ != NULL) {
1751 PrintF(trace_scope_->file(), 1749 PrintF(trace_scope_->file(),
1752 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 1750 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 for (int i = 0; i < length; ++i) { 1814 for (int i = 0; i < length; ++i) {
1817 MaterializeNextValue(); 1815 MaterializeNextValue();
1818 } 1816 }
1819 } else if (desc.is_arguments()) { 1817 } else if (desc.is_arguments()) {
1820 // Construct an arguments object and copy the parameters to a newly 1818 // Construct an arguments object and copy the parameters to a newly
1821 // allocated arguments object backing store. 1819 // allocated arguments object backing store.
1822 Handle<JSFunction> function = ArgumentsObjectFunction(object_index); 1820 Handle<JSFunction> function = ArgumentsObjectFunction(object_index);
1823 Handle<JSObject> arguments = 1821 Handle<JSObject> arguments =
1824 isolate_->factory()->NewArgumentsObject(function, length); 1822 isolate_->factory()->NewArgumentsObject(function, length);
1825 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length); 1823 Handle<FixedArray> array = isolate_->factory()->NewFixedArray(length);
1826 ASSERT(array->length() == length); 1824 ASSERT_EQ(array->length(), length);
1827 arguments->set_elements(*array); 1825 arguments->set_elements(*array);
1828 materialized_objects_->Add(arguments); 1826 materialized_objects_->Add(arguments);
1829 for (int i = 0; i < length; ++i) { 1827 for (int i = 0; i < length; ++i) {
1830 Handle<Object> value = MaterializeNextValue(); 1828 Handle<Object> value = MaterializeNextValue();
1831 array->set(i, *value); 1829 array->set(i, *value);
1832 } 1830 }
1833 } else { 1831 } else {
1834 // Dispatch on the instance type of the object to be materialized. 1832 // Dispatch on the instance type of the object to be materialized.
1835 // We also need to make sure that the representation of all fields 1833 // We also need to make sure that the representation of all fields
1836 // in the given object are general enough to hold a tagged value. 1834 // in the given object are general enough to hold a tagged value.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 Handle<Object> elements = MaterializeNextValue(); 1880 Handle<Object> elements = MaterializeNextValue();
1883 Handle<Object> length = MaterializeNextValue(); 1881 Handle<Object> length = MaterializeNextValue();
1884 object->set_properties(FixedArray::cast(*properties)); 1882 object->set_properties(FixedArray::cast(*properties));
1885 object->set_elements(FixedArrayBase::cast(*elements)); 1883 object->set_elements(FixedArrayBase::cast(*elements));
1886 object->set_length(*length); 1884 object->set_length(*length);
1887 break; 1885 break;
1888 } 1886 }
1889 default: 1887 default:
1890 PrintF(stderr, 1888 PrintF(stderr,
1891 "[couldn't handle instance type %d]\n", map->instance_type()); 1889 "[couldn't handle instance type %d]\n", map->instance_type());
1892 UNREACHABLE(); 1890 FATAL("Unsupported instance type");
1893 } 1891 }
1894 } 1892 }
1895 1893
1896 return materialized_objects_->at(object_index); 1894 return materialized_objects_->at(object_index);
1897 } 1895 }
1898 1896
1899 1897
1900 Handle<Object> Deoptimizer::MaterializeNextValue() { 1898 Handle<Object> Deoptimizer::MaterializeNextValue() {
1901 int value_index = materialization_value_index_++; 1899 int value_index = materialization_value_index_++;
1902 Handle<Object> value = materialized_values_->at(value_index); 1900 Handle<Object> value = materialized_values_->at(value_index);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 1974
1977 while (materialization_object_index_ < deferred_objects_.length()) { 1975 while (materialization_object_index_ < deferred_objects_.length()) {
1978 int object_index = materialization_object_index_; 1976 int object_index = materialization_object_index_;
1979 ObjectMaterializationDescriptor descriptor = 1977 ObjectMaterializationDescriptor descriptor =
1980 deferred_objects_.at(object_index); 1978 deferred_objects_.at(object_index);
1981 1979
1982 // Find a previously materialized object by de-duplication or 1980 // Find a previously materialized object by de-duplication or
1983 // materialize a new instance of the object if necessary. Store 1981 // materialize a new instance of the object if necessary. Store
1984 // the materialized object into the frame slot. 1982 // the materialized object into the frame slot.
1985 Handle<Object> object = MaterializeNextHeapObject(); 1983 Handle<Object> object = MaterializeNextHeapObject();
1986 Memory::Object_at(descriptor.slot_address()) = *object; 1984 if (descriptor.slot_address() != NULL) {
1985 Memory::Object_at(descriptor.slot_address()) = *object;
1986 }
1987 if (trace_scope_ != NULL) { 1987 if (trace_scope_ != NULL) {
1988 if (descriptor.is_arguments()) { 1988 if (descriptor.is_arguments()) {
1989 PrintF(trace_scope_->file(), 1989 PrintF(trace_scope_->file(),
1990 "Materialized %sarguments object of length %d for %p: ", 1990 "Materialized %sarguments object of length %d for %p: ",
1991 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "", 1991 ArgumentsObjectIsAdapted(object_index) ? "(adapted) " : "",
1992 Handle<JSObject>::cast(object)->elements()->length(), 1992 Handle<JSObject>::cast(object)->elements()->length(),
1993 reinterpret_cast<void*>(descriptor.slot_address())); 1993 reinterpret_cast<void*>(descriptor.slot_address()));
1994 } else { 1994 } else {
1995 PrintF(trace_scope_->file(), 1995 PrintF(trace_scope_->file(),
1996 "Materialized captured object of size %d for %p: ", 1996 "Materialized captured object of size %d for %p: ",
1997 Handle<HeapObject>::cast(object)->Size(), 1997 Handle<HeapObject>::cast(object)->Size(),
1998 reinterpret_cast<void*>(descriptor.slot_address())); 1998 reinterpret_cast<void*>(descriptor.slot_address()));
1999 } 1999 }
2000 object->ShortPrint(trace_scope_->file()); 2000 object->ShortPrint(trace_scope_->file());
2001 PrintF(trace_scope_->file(), "\n"); 2001 PrintF(trace_scope_->file(), "\n");
2002 } 2002 }
2003 } 2003 }
2004 2004
2005 ASSERT(materialization_object_index_ == materialized_objects_->length()); 2005 CHECK_EQ(materialization_object_index_, materialized_objects_->length());
2006 ASSERT(materialization_value_index_ == materialized_values_->length()); 2006 CHECK_EQ(materialization_value_index_, materialized_values_->length());
2007 } 2007 }
2008 2008
2009 if (prev_materialized_count_ > 0) { 2009 if (prev_materialized_count_ > 0) {
2010 materialized_store->Remove(stack_fp_); 2010 materialized_store->Remove(stack_fp_);
2011 } 2011 }
2012 } 2012 }
2013 2013
2014 2014
2015 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( 2015 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
2016 Address parameters_top, 2016 Address parameters_top,
2017 uint32_t parameters_size, 2017 uint32_t parameters_size,
2018 Address expressions_top, 2018 Address expressions_top,
2019 uint32_t expressions_size, 2019 uint32_t expressions_size,
2020 DeoptimizedFrameInfo* info) { 2020 DeoptimizedFrameInfo* info) {
2021 ASSERT_EQ(DEBUGGER, bailout_type_); 2021 CHECK_EQ(DEBUGGER, bailout_type_);
2022 Address parameters_bottom = parameters_top + parameters_size; 2022 Address parameters_bottom = parameters_top + parameters_size;
2023 Address expressions_bottom = expressions_top + expressions_size; 2023 Address expressions_bottom = expressions_top + expressions_size;
2024 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 2024 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
2025 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i]; 2025 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i];
2026 2026
2027 // Check of the heap number to materialize actually belong to the frame 2027 // Check of the heap number to materialize actually belong to the frame
2028 // being extracted. 2028 // being extracted.
2029 Address slot = d.destination(); 2029 Address slot = d.destination();
2030 if (parameters_top <= slot && slot < parameters_bottom) { 2030 if (parameters_top <= slot && slot < parameters_bottom) {
2031 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 2031 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 2068
2069 static const char* TraceValueType(bool is_smi) { 2069 static const char* TraceValueType(bool is_smi) {
2070 if (is_smi) { 2070 if (is_smi) {
2071 return "smi"; 2071 return "smi";
2072 } 2072 }
2073 2073
2074 return "heap number"; 2074 return "heap number";
2075 } 2075 }
2076 2076
2077 2077
2078 void Deoptimizer::DoTranslateObjectAndSkip(TranslationIterator* iterator) {
2079 Translation::Opcode opcode =
2080 static_cast<Translation::Opcode>(iterator->Next());
2081
2082 switch (opcode) {
2083 case Translation::BEGIN:
2084 case Translation::JS_FRAME:
2085 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2086 case Translation::CONSTRUCT_STUB_FRAME:
2087 case Translation::GETTER_STUB_FRAME:
2088 case Translation::SETTER_STUB_FRAME:
2089 case Translation::COMPILED_STUB_FRAME: {
2090 FATAL("Unexpected frame start translation opcode");
2091 return;
2092 }
2093
2094 case Translation::REGISTER:
2095 case Translation::INT32_REGISTER:
2096 case Translation::UINT32_REGISTER:
2097 case Translation::DOUBLE_REGISTER:
2098 case Translation::STACK_SLOT:
2099 case Translation::INT32_STACK_SLOT:
2100 case Translation::UINT32_STACK_SLOT:
2101 case Translation::DOUBLE_STACK_SLOT:
2102 case Translation::LITERAL: {
2103 // The value is not part of any materialized object, so we can ignore it.
2104 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
2105 return;
2106 }
2107
2108 case Translation::DUPLICATED_OBJECT: {
2109 int object_index = iterator->Next();
2110 if (trace_scope_ != NULL) {
2111 PrintF(trace_scope_->file(), " skipping object ");
2112 PrintF(trace_scope_->file(),
2113 " ; duplicate of object #%d\n", object_index);
2114 }
2115 AddObjectDuplication(0, object_index);
2116 return;
2117 }
2118
2119 case Translation::ARGUMENTS_OBJECT:
2120 case Translation::CAPTURED_OBJECT: {
2121 int length = iterator->Next();
2122 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2123 if (trace_scope_ != NULL) {
2124 PrintF(trace_scope_->file(), " skipping object ");
2125 PrintF(trace_scope_->file(),
2126 " ; object (length = %d, is_args = %d)\n", length, is_args);
2127 }
2128
2129 AddObjectStart(0, length, is_args);
2130
2131 // We save the object values on the side and materialize the actual
2132 // object after the deoptimized frame is built.
2133 int object_index = deferred_objects_.length() - 1;
2134 for (int i = 0; i < length; i++) {
2135 DoTranslateObject(iterator, object_index, i);
2136 }
2137 return;
2138 }
2139 }
2140
2141 FATAL("Unexpected translation opcode");
2142 }
2143
2144
2078 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, 2145 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
2079 int object_index, 2146 int object_index,
2080 int field_index) { 2147 int field_index) {
2081 disasm::NameConverter converter; 2148 disasm::NameConverter converter;
2082 Address object_slot = deferred_objects_[object_index].slot_address(); 2149 Address object_slot = deferred_objects_[object_index].slot_address();
2083 2150
2084 Translation::Opcode opcode = 2151 Translation::Opcode opcode =
2085 static_cast<Translation::Opcode>(iterator->Next()); 2152 static_cast<Translation::Opcode>(iterator->Next());
2086 2153
2087 switch (opcode) { 2154 switch (opcode) {
2088 case Translation::BEGIN: 2155 case Translation::BEGIN:
2089 case Translation::JS_FRAME: 2156 case Translation::JS_FRAME:
2090 case Translation::ARGUMENTS_ADAPTOR_FRAME: 2157 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2091 case Translation::CONSTRUCT_STUB_FRAME: 2158 case Translation::CONSTRUCT_STUB_FRAME:
2092 case Translation::GETTER_STUB_FRAME: 2159 case Translation::GETTER_STUB_FRAME:
2093 case Translation::SETTER_STUB_FRAME: 2160 case Translation::SETTER_STUB_FRAME:
2094 case Translation::COMPILED_STUB_FRAME: 2161 case Translation::COMPILED_STUB_FRAME:
2095 UNREACHABLE(); 2162 FATAL("Unexpected frame start translation opcode");
2096 return; 2163 return;
2097 2164
2098 case Translation::REGISTER: { 2165 case Translation::REGISTER: {
2099 int input_reg = iterator->Next(); 2166 int input_reg = iterator->Next();
2100 intptr_t input_value = input_->GetRegister(input_reg); 2167 intptr_t input_value = input_->GetRegister(input_reg);
2101 if (trace_scope_ != NULL) { 2168 if (trace_scope_ != NULL) {
2102 PrintF(trace_scope_->file(), 2169 PrintF(trace_scope_->file(),
2103 " object @0x%08" V8PRIxPTR ": [field #%d] <- ", 2170 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2104 reinterpret_cast<intptr_t>(object_slot), 2171 reinterpret_cast<intptr_t>(object_slot),
2105 field_index); 2172 field_index);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 AddObjectTaggedValue(value); 2392 AddObjectTaggedValue(value);
2326 // We save the object values on the side and materialize the actual 2393 // We save the object values on the side and materialize the actual
2327 // object after the deoptimized frame is built. 2394 // object after the deoptimized frame is built.
2328 int object_index = deferred_objects_.length() - 1; 2395 int object_index = deferred_objects_.length() - 1;
2329 for (int i = 0; i < length; i++) { 2396 for (int i = 0; i < length; i++) {
2330 DoTranslateObject(iterator, object_index, i); 2397 DoTranslateObject(iterator, object_index, i);
2331 } 2398 }
2332 return; 2399 return;
2333 } 2400 }
2334 } 2401 }
2402
2403 FATAL("Unexpected translation opcode");
2335 } 2404 }
2336 2405
2337 2406
2338 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 2407 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
2339 int frame_index, 2408 int frame_index,
2340 unsigned output_offset) { 2409 unsigned output_offset) {
2341 disasm::NameConverter converter; 2410 disasm::NameConverter converter;
2342 // A GC-safe temporary placeholder that we can put in the output frame. 2411 // A GC-safe temporary placeholder that we can put in the output frame.
2343 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 2412 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
2344 2413
2345 Translation::Opcode opcode = 2414 Translation::Opcode opcode =
2346 static_cast<Translation::Opcode>(iterator->Next()); 2415 static_cast<Translation::Opcode>(iterator->Next());
2347 2416
2348 switch (opcode) { 2417 switch (opcode) {
2349 case Translation::BEGIN: 2418 case Translation::BEGIN:
2350 case Translation::JS_FRAME: 2419 case Translation::JS_FRAME:
2351 case Translation::ARGUMENTS_ADAPTOR_FRAME: 2420 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2352 case Translation::CONSTRUCT_STUB_FRAME: 2421 case Translation::CONSTRUCT_STUB_FRAME:
2353 case Translation::GETTER_STUB_FRAME: 2422 case Translation::GETTER_STUB_FRAME:
2354 case Translation::SETTER_STUB_FRAME: 2423 case Translation::SETTER_STUB_FRAME:
2355 case Translation::COMPILED_STUB_FRAME: 2424 case Translation::COMPILED_STUB_FRAME:
2356 UNREACHABLE(); 2425 FATAL("Unexpected translation opcode");
2357 return; 2426 return;
2358 2427
2359 case Translation::REGISTER: { 2428 case Translation::REGISTER: {
2360 int input_reg = iterator->Next(); 2429 int input_reg = iterator->Next();
2361 intptr_t input_value = input_->GetRegister(input_reg); 2430 intptr_t input_value = input_->GetRegister(input_reg);
2362 if (trace_scope_ != NULL) { 2431 if (trace_scope_ != NULL) {
2363 PrintF( 2432 PrintF(
2364 trace_scope_->file(), 2433 trace_scope_->file(),
2365 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", 2434 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
2366 output_[frame_index]->GetTop() + output_offset, 2435 output_[frame_index]->GetTop() + output_offset,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 // pointer, function, context, and all the incoming arguments. 2708 // pointer, function, context, and all the incoming arguments.
2640 return ComputeIncomingArgumentSize(function) + 2709 return ComputeIncomingArgumentSize(function) +
2641 StandardFrameConstants::kFixedFrameSize; 2710 StandardFrameConstants::kFixedFrameSize;
2642 } 2711 }
2643 2712
2644 2713
2645 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { 2714 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
2646 // The incoming arguments is the values for formal parameters and 2715 // The incoming arguments is the values for formal parameters and
2647 // the receiver. Every slot contains a pointer. 2716 // the receiver. Every slot contains a pointer.
2648 if (function->IsSmi()) { 2717 if (function->IsSmi()) {
2649 ASSERT(Smi::cast(function) == Smi::FromInt(StackFrame::STUB)); 2718 CHECK_EQ(Smi::cast(function), Smi::FromInt(StackFrame::STUB));
2650 return 0; 2719 return 0;
2651 } 2720 }
2652 unsigned arguments = function->shared()->formal_parameter_count() + 1; 2721 unsigned arguments = function->shared()->formal_parameter_count() + 1;
2653 return arguments * kPointerSize; 2722 return arguments * kPointerSize;
2654 } 2723 }
2655 2724
2656 2725
2657 unsigned Deoptimizer::ComputeOutgoingArgumentSize() const { 2726 unsigned Deoptimizer::ComputeOutgoingArgumentSize() const {
2658 DeoptimizationInputData* data = DeoptimizationInputData::cast( 2727 DeoptimizationInputData* data = DeoptimizationInputData::cast(
2659 compiled_code_->deoptimization_data()); 2728 compiled_code_->deoptimization_data());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 } 2773 }
2705 2774
2706 2775
2707 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate, 2776 void Deoptimizer::EnsureCodeForDeoptimizationEntry(Isolate* isolate,
2708 BailoutType type, 2777 BailoutType type,
2709 int max_entry_id) { 2778 int max_entry_id) {
2710 // We cannot run this if the serializer is enabled because this will 2779 // We cannot run this if the serializer is enabled because this will
2711 // cause us to emit relocation information for the external 2780 // cause us to emit relocation information for the external
2712 // references. This is fine because the deoptimizer's code section 2781 // references. This is fine because the deoptimizer's code section
2713 // isn't meant to be serialized at all. 2782 // isn't meant to be serialized at all.
2714 ASSERT(type == EAGER || type == SOFT || type == LAZY); 2783 CHECK(type == EAGER || type == SOFT || type == LAZY);
2715 DeoptimizerData* data = isolate->deoptimizer_data(); 2784 DeoptimizerData* data = isolate->deoptimizer_data();
2716 int entry_count = data->deopt_entry_code_entries_[type]; 2785 int entry_count = data->deopt_entry_code_entries_[type];
2717 if (max_entry_id < entry_count) return; 2786 if (max_entry_id < entry_count) return;
2718 entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries); 2787 entry_count = Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2719 while (max_entry_id >= entry_count) entry_count *= 2; 2788 while (max_entry_id >= entry_count) entry_count *= 2;
2720 ASSERT(entry_count <= Deoptimizer::kMaxNumberOfEntries); 2789 CHECK(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2721 2790
2722 MacroAssembler masm(isolate, NULL, 16 * KB); 2791 MacroAssembler masm(isolate, NULL, 16 * KB);
2723 masm.set_emit_debug_code(false); 2792 masm.set_emit_debug_code(false);
2724 GenerateDeoptimizationEntries(&masm, entry_count, type); 2793 GenerateDeoptimizationEntries(&masm, entry_count, type);
2725 CodeDesc desc; 2794 CodeDesc desc;
2726 masm.GetCode(&desc); 2795 masm.GetCode(&desc);
2727 ASSERT(!RelocInfo::RequiresRelocation(desc)); 2796 ASSERT(!RelocInfo::RequiresRelocation(desc));
2728 2797
2729 MemoryChunk* chunk = data->deopt_entry_code_[type]; 2798 MemoryChunk* chunk = data->deopt_entry_code_[type];
2730 ASSERT(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >= 2799 CHECK(static_cast<int>(Deoptimizer::GetMaxDeoptTableSize()) >=
2731 desc.instr_size); 2800 desc.instr_size);
2732 chunk->CommitArea(desc.instr_size); 2801 chunk->CommitArea(desc.instr_size);
2733 CopyBytes(chunk->area_start(), desc.buffer, 2802 CopyBytes(chunk->area_start(), desc.buffer,
2734 static_cast<size_t>(desc.instr_size)); 2803 static_cast<size_t>(desc.instr_size));
2735 CPU::FlushICache(chunk->area_start(), desc.instr_size); 2804 CPU::FlushICache(chunk->area_start(), desc.instr_size);
2736 2805
2737 data->deopt_entry_code_entries_[type] = entry_count; 2806 data->deopt_entry_code_entries_[type] = entry_count;
2738 } 2807 }
2739 2808
2740 2809
2741 FrameDescription::FrameDescription(uint32_t frame_size, 2810 FrameDescription::FrameDescription(uint32_t frame_size,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 case StackFrame::JAVA_SCRIPT: 2857 case StackFrame::JAVA_SCRIPT:
2789 return function_->shared()->formal_parameter_count(); 2858 return function_->shared()->formal_parameter_count();
2790 case StackFrame::ARGUMENTS_ADAPTOR: { 2859 case StackFrame::ARGUMENTS_ADAPTOR: {
2791 // Last slot contains number of incomming arguments as a smi. 2860 // Last slot contains number of incomming arguments as a smi.
2792 // Can't use GetExpression(0) because it would cause infinite recursion. 2861 // Can't use GetExpression(0) because it would cause infinite recursion.
2793 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value(); 2862 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
2794 } 2863 }
2795 case StackFrame::STUB: 2864 case StackFrame::STUB:
2796 return -1; // Minus receiver. 2865 return -1; // Minus receiver.
2797 default: 2866 default:
2798 UNREACHABLE(); 2867 FATAL("Unexpected stack frame type");
2799 return 0; 2868 return 0;
2800 } 2869 }
2801 } 2870 }
2802 2871
2803 2872
2804 Object* FrameDescription::GetParameter(int index) { 2873 Object* FrameDescription::GetParameter(int index) {
2805 ASSERT(index >= 0); 2874 CHECK_GE(index, 0);
2806 ASSERT(index < ComputeParametersCount()); 2875 CHECK_LT(index, ComputeParametersCount());
2807 // The slot indexes for incoming arguments are negative. 2876 // The slot indexes for incoming arguments are negative.
2808 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount()); 2877 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
2809 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 2878 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2810 } 2879 }
2811 2880
2812 2881
2813 unsigned FrameDescription::GetExpressionCount() { 2882 unsigned FrameDescription::GetExpressionCount() {
2814 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_); 2883 CHECK_EQ(StackFrame::JAVA_SCRIPT, type_);
2815 unsigned size = GetFrameSize() - ComputeFixedSize(); 2884 unsigned size = GetFrameSize() - ComputeFixedSize();
2816 return size / kPointerSize; 2885 return size / kPointerSize;
2817 } 2886 }
2818 2887
2819 2888
2820 Object* FrameDescription::GetExpression(int index) { 2889 Object* FrameDescription::GetExpression(int index) {
2821 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_); 2890 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
2822 unsigned offset = GetOffsetFromSlotIndex(index); 2891 unsigned offset = GetOffsetFromSlotIndex(index);
2823 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 2892 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
2824 } 2893 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
3006 case LITERAL: 3075 case LITERAL:
3007 case COMPILED_STUB_FRAME: 3076 case COMPILED_STUB_FRAME:
3008 return 1; 3077 return 1;
3009 case BEGIN: 3078 case BEGIN:
3010 case ARGUMENTS_ADAPTOR_FRAME: 3079 case ARGUMENTS_ADAPTOR_FRAME:
3011 case CONSTRUCT_STUB_FRAME: 3080 case CONSTRUCT_STUB_FRAME:
3012 return 2; 3081 return 2;
3013 case JS_FRAME: 3082 case JS_FRAME:
3014 return 3; 3083 return 3;
3015 } 3084 }
3016 UNREACHABLE(); 3085 FATAL("Unexpected translation type");
3017 return -1; 3086 return -1;
3018 } 3087 }
3019 3088
3020 3089
3021 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 3090 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
3022 3091
3023 const char* Translation::StringFor(Opcode opcode) { 3092 const char* Translation::StringFor(Opcode opcode) {
3024 #define TRANSLATION_OPCODE_CASE(item) case item: return #item; 3093 #define TRANSLATION_OPCODE_CASE(item) case item: return #item;
3025 switch (opcode) { 3094 switch (opcode) {
3026 TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE) 3095 TRANSLATION_OPCODE_LIST(TRANSLATION_OPCODE_CASE)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 int formal_parameter_count) 3185 int formal_parameter_count)
3117 : current_slot_(0), args_length_(-1), first_slot_index_(-1) { 3186 : current_slot_(0), args_length_(-1), first_slot_index_(-1) {
3118 DisallowHeapAllocation no_gc; 3187 DisallowHeapAllocation no_gc;
3119 3188
3120 int deopt_index = Safepoint::kNoDeoptimizationIndex; 3189 int deopt_index = Safepoint::kNoDeoptimizationIndex;
3121 DeoptimizationInputData* data = 3190 DeoptimizationInputData* data =
3122 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); 3191 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
3123 TranslationIterator it(data->TranslationByteArray(), 3192 TranslationIterator it(data->TranslationByteArray(),
3124 data->TranslationIndex(deopt_index)->value()); 3193 data->TranslationIndex(deopt_index)->value());
3125 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 3194 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
3126 ASSERT(opcode == Translation::BEGIN); 3195 CHECK_EQ(opcode, Translation::BEGIN);
3127 it.Next(); // Drop frame count. 3196 it.Next(); // Drop frame count.
3128 3197
3129 stack_frame_id_ = frame->fp(); 3198 stack_frame_id_ = frame->fp();
3130 3199
3131 int jsframe_count = it.Next(); 3200 int jsframe_count = it.Next();
3132 USE(jsframe_count); 3201 CHECK_GT(jsframe_count, inlined_jsframe_index);
3133 ASSERT(jsframe_count > inlined_jsframe_index);
3134 int jsframes_to_skip = inlined_jsframe_index; 3202 int jsframes_to_skip = inlined_jsframe_index;
3135 int number_of_slots = -1; // Number of slots inside our frame (yet unknown) 3203 int number_of_slots = -1; // Number of slots inside our frame (yet unknown)
3136 bool should_deopt = false; 3204 bool should_deopt = false;
3137 while (number_of_slots != 0) { 3205 while (number_of_slots != 0) {
3138 opcode = static_cast<Translation::Opcode>(it.Next()); 3206 opcode = static_cast<Translation::Opcode>(it.Next());
3139 bool processed = false; 3207 bool processed = false;
3140 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) { 3208 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
3141 if (jsframes_to_skip == 0) { 3209 if (jsframes_to_skip == 0) {
3142 ASSERT(Translation::NumberOfOperandsFor(opcode) == 2); 3210 CHECK_EQ(Translation::NumberOfOperandsFor(opcode), 2);
3143 3211
3144 it.Skip(1); // literal id 3212 it.Skip(1); // literal id
3145 int height = it.Next(); 3213 int height = it.Next();
3146 3214
3147 // Skip the translation command for the receiver. 3215 // Skip the translation command for the receiver.
3148 it.Skip(Translation::NumberOfOperandsFor( 3216 it.Skip(Translation::NumberOfOperandsFor(
3149 static_cast<Translation::Opcode>(it.Next()))); 3217 static_cast<Translation::Opcode>(it.Next())));
3150 3218
3151 // We reached the arguments adaptor frame corresponding to the 3219 // We reached the arguments adaptor frame corresponding to the
3152 // inlined function in question. Number of arguments is height - 1. 3220 // inlined function in question. Number of arguments is height - 1.
(...skipping 26 matching lines...) Expand all
3179 opcode != Translation::GETTER_STUB_FRAME && 3247 opcode != Translation::GETTER_STUB_FRAME &&
3180 opcode != Translation::SETTER_STUB_FRAME && 3248 opcode != Translation::SETTER_STUB_FRAME &&
3181 opcode != Translation::COMPILED_STUB_FRAME) { 3249 opcode != Translation::COMPILED_STUB_FRAME) {
3182 slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame)); 3250 slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame));
3183 3251
3184 if (first_slot_index_ >= 0) { 3252 if (first_slot_index_ >= 0) {
3185 // We have found the beginning of our frame -> make sure we count 3253 // We have found the beginning of our frame -> make sure we count
3186 // the nested slots of captured objects 3254 // the nested slots of captured objects
3187 number_of_slots--; 3255 number_of_slots--;
3188 SlotRef& slot = slot_refs_.last(); 3256 SlotRef& slot = slot_refs_.last();
3189 ASSERT(slot.Representation() != SlotRef::ARGUMENTS_OBJECT); 3257 CHECK_NE(slot.Representation(), SlotRef::ARGUMENTS_OBJECT);
3190 number_of_slots += slot.GetChildrenCount(); 3258 number_of_slots += slot.GetChildrenCount();
3191 if (slot.Representation() == SlotRef::DEFERRED_OBJECT || 3259 if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
3192 slot.Representation() == SlotRef::DUPLICATE_OBJECT) { 3260 slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
3193 should_deopt = true; 3261 should_deopt = true;
3194 } 3262 }
3195 } 3263 }
3196 3264
3197 processed = true; 3265 processed = true;
3198 } 3266 }
3199 if (!processed) { 3267 if (!processed) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3253 previously_materialized_objects_ = materialized_store->Get(stack_frame_id_); 3321 previously_materialized_objects_ = materialized_store->Get(stack_frame_id_);
3254 prev_materialized_count_ = previously_materialized_objects_.is_null() 3322 prev_materialized_count_ = previously_materialized_objects_.is_null()
3255 ? 0 : previously_materialized_objects_->length(); 3323 ? 0 : previously_materialized_objects_->length();
3256 3324
3257 // Skip any materialized objects of the inlined "parent" frames. 3325 // Skip any materialized objects of the inlined "parent" frames.
3258 // (Note that we still need to materialize them because they might be 3326 // (Note that we still need to materialize them because they might be
3259 // referred to as duplicated objects.) 3327 // referred to as duplicated objects.)
3260 while (current_slot_ < first_slot_index_) { 3328 while (current_slot_ < first_slot_index_) {
3261 GetNext(isolate, 0); 3329 GetNext(isolate, 0);
3262 } 3330 }
3263 ASSERT(current_slot_ == first_slot_index_); 3331 CHECK_EQ(current_slot_, first_slot_index_);
3264 } 3332 }
3265 3333
3266 3334
3267 Handle<Object> SlotRefValueBuilder::GetPreviouslyMaterialized( 3335 Handle<Object> SlotRefValueBuilder::GetPreviouslyMaterialized(
3268 Isolate* isolate, int length) { 3336 Isolate* isolate, int length) {
3269 int object_index = materialized_objects_.length(); 3337 int object_index = materialized_objects_.length();
3270 Handle<Object> return_value = Handle<Object>( 3338 Handle<Object> return_value = Handle<Object>(
3271 previously_materialized_objects_->get(object_index), isolate); 3339 previously_materialized_objects_->get(object_index), isolate);
3272 materialized_objects_.Add(return_value); 3340 materialized_objects_.Add(return_value);
3273 3341
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3315 materialized_objects_.Add(isolate->factory()->undefined_value()); 3383 materialized_objects_.Add(isolate->factory()->undefined_value());
3316 int length = slot.GetChildrenCount(); 3384 int length = slot.GetChildrenCount();
3317 for (int i = 0; i < length; ++i) { 3385 for (int i = 0; i < length; ++i) {
3318 // We don't need the argument, just ignore it 3386 // We don't need the argument, just ignore it
3319 GetNext(isolate, lvl + 1); 3387 GetNext(isolate, lvl + 1);
3320 } 3388 }
3321 return isolate->factory()->undefined_value(); 3389 return isolate->factory()->undefined_value();
3322 } 3390 }
3323 case SlotRef::DEFERRED_OBJECT: { 3391 case SlotRef::DEFERRED_OBJECT: {
3324 int length = slot.GetChildrenCount(); 3392 int length = slot.GetChildrenCount();
3325 ASSERT(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL || 3393 CHECK(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL ||
3326 slot_refs_[current_slot_].Representation() == SlotRef::TAGGED); 3394 slot_refs_[current_slot_].Representation() == SlotRef::TAGGED);
3327 3395
3328 int object_index = materialized_objects_.length(); 3396 int object_index = materialized_objects_.length();
3329 if (object_index < prev_materialized_count_) { 3397 if (object_index < prev_materialized_count_) {
3330 return GetPreviouslyMaterialized(isolate, length); 3398 return GetPreviouslyMaterialized(isolate, length);
3331 } 3399 }
3332 3400
3333 Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate); 3401 Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate);
3334 Handle<Map> map = Map::GeneralizeAllFieldRepresentations( 3402 Handle<Map> map = Map::GeneralizeAllFieldRepresentations(
3335 Handle<Map>::cast(map_object)); 3403 Handle<Map>::cast(map_object));
3336 current_slot_++; 3404 current_slot_++;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3377 object->set_length(*length); 3445 object->set_length(*length);
3378 return object; 3446 return object;
3379 } 3447 }
3380 default: 3448 default:
3381 PrintF(stderr, 3449 PrintF(stderr,
3382 "[couldn't handle instance type %d]\n", map->instance_type()); 3450 "[couldn't handle instance type %d]\n", map->instance_type());
3383 UNREACHABLE(); 3451 UNREACHABLE();
3384 break; 3452 break;
3385 } 3453 }
3386 UNREACHABLE(); 3454 UNREACHABLE();
3455 break;
3387 } 3456 }
3388 3457
3389 case SlotRef::DUPLICATE_OBJECT: { 3458 case SlotRef::DUPLICATE_OBJECT: {
3390 int object_index = slot.DuplicateObjectId(); 3459 int object_index = slot.DuplicateObjectId();
3391 Handle<Object> object = materialized_objects_[object_index]; 3460 Handle<Object> object = materialized_objects_[object_index];
3392 materialized_objects_.Add(object); 3461 materialized_objects_.Add(object);
3393 return object; 3462 return object;
3394 } 3463 }
3395 default: 3464 default:
3396 UNREACHABLE(); 3465 UNREACHABLE();
3397 break; 3466 break;
3398 } 3467 }
3399 3468
3400 FATAL("We should never get here - unexpected deopt slot kind."); 3469 FATAL("We should never get here - unexpected deopt slot kind.");
3401 return Handle<Object>::null(); 3470 return Handle<Object>::null();
3402 } 3471 }
3403 3472
3404 3473
3405 void SlotRefValueBuilder::Finish(Isolate* isolate) { 3474 void SlotRefValueBuilder::Finish(Isolate* isolate) {
3406 // We should have processed all the slots 3475 // We should have processed all the slots
3407 ASSERT(slot_refs_.length() == current_slot_); 3476 CHECK_EQ(slot_refs_.length(), current_slot_);
3408 3477
3409 if (materialized_objects_.length() > prev_materialized_count_) { 3478 if (materialized_objects_.length() > prev_materialized_count_) {
3410 // We have materialized some new objects, so we have to store them 3479 // We have materialized some new objects, so we have to store them
3411 // to prevent duplicate materialization 3480 // to prevent duplicate materialization
3412 Handle<FixedArray> array = isolate->factory()->NewFixedArray( 3481 Handle<FixedArray> array = isolate->factory()->NewFixedArray(
3413 materialized_objects_.length()); 3482 materialized_objects_.length());
3414 for (int i = 0; i < materialized_objects_.length(); i++) { 3483 for (int i = 0; i < materialized_objects_.length(); i++) {
3415 array->set(i, *(materialized_objects_.at(i))); 3484 array->set(i, *(materialized_objects_.at(i)));
3416 } 3485 }
3417 isolate->materialized_object_store()->Set(stack_frame_id_, array); 3486 isolate->materialized_object_store()->Set(stack_frame_id_, array);
3418 } 3487 }
3419 } 3488 }
3420 3489
3421 3490
3422 Handle<FixedArray> MaterializedObjectStore::Get(Address fp) { 3491 Handle<FixedArray> MaterializedObjectStore::Get(Address fp) {
3423 int index = StackIdToIndex(fp); 3492 int index = StackIdToIndex(fp);
3424 if (index == -1) { 3493 if (index == -1) {
3425 return Handle<FixedArray>::null(); 3494 return Handle<FixedArray>::null();
3426 } 3495 }
3427 Handle<FixedArray> array = GetStackEntries(); 3496 Handle<FixedArray> array = GetStackEntries();
3428 ASSERT(array->length() > index); 3497 CHECK_GT(array->length(), index);
3429 return Handle<FixedArray>::cast(Handle<Object>(array->get(index), 3498 return Handle<FixedArray>::cast(Handle<Object>(array->get(index),
3430 isolate())); 3499 isolate()));
3431 } 3500 }
3432 3501
3433 3502
3434 void MaterializedObjectStore::Set(Address fp, 3503 void MaterializedObjectStore::Set(Address fp,
3435 Handle<FixedArray> materialized_objects) { 3504 Handle<FixedArray> materialized_objects) {
3436 int index = StackIdToIndex(fp); 3505 int index = StackIdToIndex(fp);
3437 if (index == -1) { 3506 if (index == -1) {
3438 index = frame_fps_.length(); 3507 index = frame_fps_.length();
3439 frame_fps_.Add(fp); 3508 frame_fps_.Add(fp);
3440 } 3509 }
3441 3510
3442 Handle<FixedArray> array = EnsureStackEntries(index + 1); 3511 Handle<FixedArray> array = EnsureStackEntries(index + 1);
3443 array->set(index, *materialized_objects); 3512 array->set(index, *materialized_objects);
3444 } 3513 }
3445 3514
3446 3515
3447 void MaterializedObjectStore::Remove(Address fp) { 3516 void MaterializedObjectStore::Remove(Address fp) {
3448 int index = StackIdToIndex(fp); 3517 int index = StackIdToIndex(fp);
3449 ASSERT(index >= 0); 3518 CHECK_GE(index, 0);
3450 3519
3451 frame_fps_.Remove(index); 3520 frame_fps_.Remove(index);
3452 Handle<FixedArray> array = GetStackEntries(); 3521 Handle<FixedArray> array = GetStackEntries();
3453 ASSERT(array->length() > index); 3522 CHECK_LT(index, array->length());
3454 for (int i = index; i < frame_fps_.length(); i++) { 3523 for (int i = index; i < frame_fps_.length(); i++) {
3455 array->set(i, array->get(i + 1)); 3524 array->set(i, array->get(i + 1));
3456 } 3525 }
3457 array->set(frame_fps_.length(), isolate()->heap()->undefined_value()); 3526 array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
3458 } 3527 }
3459 3528
3460 3529
3461 int MaterializedObjectStore::StackIdToIndex(Address fp) { 3530 int MaterializedObjectStore::StackIdToIndex(Address fp) {
3462 for (int i = 0; i < frame_fps_.length(); i++) { 3531 for (int i = 0; i < frame_fps_.length(); i++) {
3463 if (frame_fps_[i] == fp) { 3532 if (frame_fps_[i] == fp) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3510 Address pc = reinterpret_cast<Address>(output_frame->GetPc()); 3579 Address pc = reinterpret_cast<Address>(output_frame->GetPc());
3511 Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc)); 3580 Code* code = Code::cast(deoptimizer->isolate()->FindCodeObject(pc));
3512 source_position_ = code->SourcePosition(pc); 3581 source_position_ = code->SourcePosition(pc);
3513 3582
3514 for (int i = 0; i < expression_count_; i++) { 3583 for (int i = 0; i < expression_count_; i++) {
3515 SetExpression(i, output_frame->GetExpression(i)); 3584 SetExpression(i, output_frame->GetExpression(i));
3516 } 3585 }
3517 3586
3518 if (has_arguments_adaptor) { 3587 if (has_arguments_adaptor) {
3519 output_frame = deoptimizer->output_[frame_index - 1]; 3588 output_frame = deoptimizer->output_[frame_index - 1];
3520 ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR); 3589 CHECK_EQ(output_frame->GetFrameType(), StackFrame::ARGUMENTS_ADAPTOR);
3521 } 3590 }
3522 3591
3523 parameters_count_ = output_frame->ComputeParametersCount(); 3592 parameters_count_ = output_frame->ComputeParametersCount();
3524 parameters_ = new Object*[parameters_count_]; 3593 parameters_ = new Object*[parameters_count_];
3525 for (int i = 0; i < parameters_count_; i++) { 3594 for (int i = 0; i < parameters_count_; i++) {
3526 SetParameter(i, output_frame->GetParameter(i)); 3595 SetParameter(i, output_frame->GetParameter(i));
3527 } 3596 }
3528 } 3597 }
3529 3598
3530 3599
3531 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() { 3600 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
3532 delete[] expression_stack_; 3601 delete[] expression_stack_;
3533 delete[] parameters_; 3602 delete[] parameters_;
3534 } 3603 }
3535 3604
3536 3605
3537 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 3606 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
3538 v->VisitPointer(BitCast<Object**>(&function_)); 3607 v->VisitPointer(BitCast<Object**>(&function_));
3539 v->VisitPointers(parameters_, parameters_ + parameters_count_); 3608 v->VisitPointers(parameters_, parameters_ + parameters_count_);
3540 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 3609 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
3541 } 3610 }
3542 3611
3543 } } // namespace v8::internal 3612 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | test/mjsunit/regress/regress-359441.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698