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

Side by Side Diff: src/deoptimizer.cc

Issue 9265004: Support inlining at call-sites with mismatched number of arguments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: finished implementation, extended tests, ported to x64&arm Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2012 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
11 // with the distribution. 11 // with the distribution.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 97
98 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { 98 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
99 ASSERT(isolate == Isolate::Current()); 99 ASSERT(isolate == Isolate::Current());
100 Deoptimizer* result = isolate->deoptimizer_data()->current_; 100 Deoptimizer* result = isolate->deoptimizer_data()->current_;
101 ASSERT(result != NULL); 101 ASSERT(result != NULL);
102 result->DeleteFrameDescriptions(); 102 result->DeleteFrameDescriptions();
103 isolate->deoptimizer_data()->current_ = NULL; 103 isolate->deoptimizer_data()->current_ = NULL;
104 return result; 104 return result;
105 } 105 }
106 106
107
108 int Deoptimizer::ConvertJSFrameIndexToFrameIndex(int jsframe_index) {
109 if (jsframe_index == 0) return 0;
110
111 int frame_index = 0;
112 while (jsframe_index >= 0) {
113 FrameDescription* frame = output_[frame_index];
114 if (frame->GetType() == StackFrame::JAVA_SCRIPT) {
115 jsframe_index--;
116 }
117 frame_index++;
118 }
119
120 return frame_index - 1;
121 }
122
123
107 #ifdef ENABLE_DEBUGGER_SUPPORT 124 #ifdef ENABLE_DEBUGGER_SUPPORT
108 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame( 125 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
109 JavaScriptFrame* frame, 126 JavaScriptFrame* frame,
110 int frame_index, 127 int jsframe_index,
111 Isolate* isolate) { 128 Isolate* isolate) {
112 ASSERT(isolate == Isolate::Current()); 129 ASSERT(isolate == Isolate::Current());
113 ASSERT(frame->is_optimized()); 130 ASSERT(frame->is_optimized());
114 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL); 131 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
115 132
116 // Get the function and code from the frame. 133 // Get the function and code from the frame.
117 JSFunction* function = JSFunction::cast(frame->function()); 134 JSFunction* function = JSFunction::cast(frame->function());
118 Code* code = frame->LookupCode(); 135 Code* code = frame->LookupCode();
119 136
120 // Locate the deoptimization point in the code. As we are at a call the 137 // Locate the deoptimization point in the code. As we are at a call the
(...skipping 15 matching lines...) Expand all
136 fp_to_sp_delta, 153 fp_to_sp_delta,
137 code); 154 code);
138 Address tos = frame->fp() - fp_to_sp_delta; 155 Address tos = frame->fp() - fp_to_sp_delta;
139 deoptimizer->FillInputFrame(tos, frame); 156 deoptimizer->FillInputFrame(tos, frame);
140 157
141 // Calculate the output frames. 158 // Calculate the output frames.
142 Deoptimizer::ComputeOutputFrames(deoptimizer); 159 Deoptimizer::ComputeOutputFrames(deoptimizer);
143 160
144 // Create the GC safe output frame information and register it for GC 161 // Create the GC safe output frame information and register it for GC
145 // handling. 162 // handling.
146 ASSERT_LT(frame_index, deoptimizer->output_count()); 163 ASSERT_LT(jsframe_index, deoptimizer->jsframe_count());
164
165 // Convert JS frame index into frame index.
166 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index);
167
168 bool has_arguments_adaptor =
169 frame_index > 0 &&
170 deoptimizer->output_[frame_index - 1]->GetType() ==
171 StackFrame::ARGUMENTS_ADAPTOR;
172
147 DeoptimizedFrameInfo* info = 173 DeoptimizedFrameInfo* info =
148 new DeoptimizedFrameInfo(deoptimizer, frame_index); 174 new DeoptimizedFrameInfo(deoptimizer, frame_index, has_arguments_adaptor);
149 isolate->deoptimizer_data()->deoptimized_frame_info_ = info; 175 isolate->deoptimizer_data()->deoptimized_frame_info_ = info;
150 176
151 // Get the "simulated" top and size for the requested frame. 177 // Get the "simulated" top and size for the requested frame.
152 Address top = 178 FrameDescription* parameters_frame =
153 reinterpret_cast<Address>(deoptimizer->output_[frame_index]->GetTop()); 179 deoptimizer->output_[
154 uint32_t size = deoptimizer->output_[frame_index]->GetFrameSize(); 180 has_arguments_adaptor ? (frame_index - 1) : frame_index];
181
182 uint32_t parameters_size = (info->parameters_count() + 1) * kPointerSize;
183 Address parameters_top = reinterpret_cast<Address>(
184 parameters_frame->GetTop() + (parameters_frame->GetFrameSize() -
185 parameters_size));
186
187 uint32_t expressions_size = info->expression_count() * kPointerSize;
188 Address expressions_top = reinterpret_cast<Address>(
189 deoptimizer->output_[frame_index]->GetTop());
155 190
156 // Done with the GC-unsafe frame descriptions. This re-enables allocation. 191 // Done with the GC-unsafe frame descriptions. This re-enables allocation.
157 deoptimizer->DeleteFrameDescriptions(); 192 deoptimizer->DeleteFrameDescriptions();
158 193
159 // Allocate a heap number for the doubles belonging to this frame. 194 // Allocate a heap number for the doubles belonging to this frame.
160 deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame( 195 deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
161 top, size, info); 196 parameters_top, parameters_size, expressions_top, expressions_size, info);
162 197
163 // Finished using the deoptimizer instance. 198 // Finished using the deoptimizer instance.
164 delete deoptimizer; 199 delete deoptimizer;
165 200
166 return info; 201 return info;
167 } 202 }
168 203
169 204
170 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info, 205 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
171 Isolate* isolate) { 206 Isolate* isolate) {
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 int fp_to_sp_delta, 341 int fp_to_sp_delta,
307 Code* optimized_code) 342 Code* optimized_code)
308 : isolate_(isolate), 343 : isolate_(isolate),
309 function_(function), 344 function_(function),
310 bailout_id_(bailout_id), 345 bailout_id_(bailout_id),
311 bailout_type_(type), 346 bailout_type_(type),
312 from_(from), 347 from_(from),
313 fp_to_sp_delta_(fp_to_sp_delta), 348 fp_to_sp_delta_(fp_to_sp_delta),
314 input_(NULL), 349 input_(NULL),
315 output_count_(0), 350 output_count_(0),
351 jsframe_count_(0),
316 output_(NULL), 352 output_(NULL),
317 frame_alignment_marker_(isolate->heap()->frame_alignment_marker()), 353 frame_alignment_marker_(isolate->heap()->frame_alignment_marker()),
318 has_alignment_padding_(0), 354 has_alignment_padding_(0),
319 deferred_heap_numbers_(0) { 355 deferred_heap_numbers_(0) {
320 if (FLAG_trace_deopt && type != OSR) { 356 if (FLAG_trace_deopt && type != OSR) {
321 if (type == DEBUGGER) { 357 if (type == DEBUGGER) {
322 PrintF("**** DEOPT FOR DEBUGGER: "); 358 PrintF("**** DEOPT FOR DEBUGGER: ");
323 } else { 359 } else {
324 PrintF("**** DEOPT: "); 360 PrintF("**** DEOPT: ");
325 } 361 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 } else if (type == DEBUGGER) { 409 } else if (type == DEBUGGER) {
374 optimized_code_ = optimized_code; 410 optimized_code_ = optimized_code;
375 ASSERT(optimized_code_->contains(from)); 411 ASSERT(optimized_code_->contains(from));
376 } 412 }
377 ASSERT(HEAP->allow_allocation(false)); 413 ASSERT(HEAP->allow_allocation(false));
378 unsigned size = ComputeInputFrameSize(); 414 unsigned size = ComputeInputFrameSize();
379 input_ = new(size) FrameDescription(size, function); 415 input_ = new(size) FrameDescription(size, function);
380 #ifdef DEBUG 416 #ifdef DEBUG
381 input_->SetKind(Code::OPTIMIZED_FUNCTION); 417 input_->SetKind(Code::OPTIMIZED_FUNCTION);
382 #endif 418 #endif
419 input_->SetType(StackFrame::JAVA_SCRIPT);
383 } 420 }
384 421
385 422
386 Deoptimizer::~Deoptimizer() { 423 Deoptimizer::~Deoptimizer() {
387 ASSERT(input_ == NULL && output_ == NULL); 424 ASSERT(input_ == NULL && output_ == NULL);
388 } 425 }
389 426
390 427
391 void Deoptimizer::DeleteFrameDescriptions() { 428 void Deoptimizer::DeleteFrameDescriptions() {
392 delete input_; 429 delete input_;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 545
509 // Do the input frame to output frame(s) translation. 546 // Do the input frame to output frame(s) translation.
510 TranslationIterator iterator(translations, translation_index); 547 TranslationIterator iterator(translations, translation_index);
511 Translation::Opcode opcode = 548 Translation::Opcode opcode =
512 static_cast<Translation::Opcode>(iterator.Next()); 549 static_cast<Translation::Opcode>(iterator.Next());
513 ASSERT(Translation::BEGIN == opcode); 550 ASSERT(Translation::BEGIN == opcode);
514 USE(opcode); 551 USE(opcode);
515 // Read the number of output frames and allocate an array for their 552 // Read the number of output frames and allocate an array for their
516 // descriptions. 553 // descriptions.
517 int count = iterator.Next(); 554 int count = iterator.Next();
555 iterator.Next(); // Drop JS frames count.
518 ASSERT(output_ == NULL); 556 ASSERT(output_ == NULL);
519 output_ = new FrameDescription*[count]; 557 output_ = new FrameDescription*[count];
520 for (int i = 0; i < count; ++i) { 558 for (int i = 0; i < count; ++i) {
521 output_[i] = NULL; 559 output_[i] = NULL;
522 } 560 }
523 output_count_ = count; 561 output_count_ = count;
524 562
525 // Translate each output frame. 563 // Translate each output frame.
526 for (int i = 0; i < count; ++i) { 564 for (int i = 0; i < count; ++i) {
527 DoComputeFrame(&iterator, i); 565 // Read the ast node id, function, and frame height for this output frame.
566 Translation::Opcode opcode =
567 static_cast<Translation::Opcode>(iterator.Next());
568 switch (opcode) {
569 case Translation::JS_FRAME:
570 DoComputeJSFrame(&iterator, i);
571 jsframe_count_++;
572 break;
573 case Translation::ARGUMENTS_ADAPTOR_FRAME:
574 DoComputeArgumentsAdaptorFrame(&iterator, i);
575 break;
576 default:
577 UNREACHABLE();
578 break;
579 }
528 } 580 }
529 581
530 // Print some helpful diagnostic information. 582 // Print some helpful diagnostic information.
531 if (FLAG_trace_deopt) { 583 if (FLAG_trace_deopt) {
532 double ms = static_cast<double>(OS::Ticks() - start) / 1000; 584 double ms = static_cast<double>(OS::Ticks() - start) / 1000;
533 int index = output_count_ - 1; // Index of the topmost frame. 585 int index = output_count_ - 1; // Index of the topmost frame.
534 JSFunction* function = output_[index]->GetFunction(); 586 JSFunction* function = output_[index]->GetFunction();
535 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ", 587 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
536 reinterpret_cast<intptr_t>(function)); 588 reinterpret_cast<intptr_t>(function));
537 function->PrintName(); 589 function->PrintName();
(...skipping 20 matching lines...) Expand all
558 d.slot_address()); 610 d.slot_address());
559 } 611 }
560 612
561 Memory::Object_at(d.slot_address()) = *num; 613 Memory::Object_at(d.slot_address()) = *num;
562 } 614 }
563 } 615 }
564 616
565 617
566 #ifdef ENABLE_DEBUGGER_SUPPORT 618 #ifdef ENABLE_DEBUGGER_SUPPORT
567 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame( 619 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
568 Address top, uint32_t size, DeoptimizedFrameInfo* info) { 620 Address parameters_top,
621 uint32_t parameters_size,
622 Address expressions_top,
623 uint32_t expressions_size,
624 DeoptimizedFrameInfo* info) {
569 ASSERT_EQ(DEBUGGER, bailout_type_); 625 ASSERT_EQ(DEBUGGER, bailout_type_);
626 Address parameters_bot = parameters_top + parameters_size;
Kevin Millikin (Chromium) 2012/01/24 00:08:54 _bottom reads better.
627 Address expressions_bot = expressions_top + expressions_size;
570 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 628 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
571 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; 629 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
572 630
573 // Check of the heap number to materialize actually belong to the frame 631 // Check of the heap number to materialize actually belong to the frame
574 // being extracted. 632 // being extracted.
575 Address slot = d.slot_address(); 633 Address slot = d.slot_address();
576 if (top <= slot && slot < top + size) { 634 if (parameters_top <= slot && slot < parameters_bot) {
577 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 635 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
578 // Calculate the index with the botton of the expression stack 636
579 // at index 0, and the fixed part (including incoming arguments) 637 int index = (info->parameters_count() - 1) -
580 // at negative indexes. 638 (slot - parameters_top) / kPointerSize;
581 int index = static_cast<int>( 639
582 info->expression_count_ - (slot - top) / kPointerSize - 1);
583 if (FLAG_trace_deopt) { 640 if (FLAG_trace_deopt) {
584 PrintF("Materializing a new heap number %p [%e] in slot %p" 641 PrintF("Materializing a new heap number %p [%e] in slot %p"
585 "for stack index %d\n", 642 "for parameter slot #%d\n",
586 reinterpret_cast<void*>(*num), 643 reinterpret_cast<void*>(*num),
587 d.value(), 644 d.value(),
588 d.slot_address(), 645 d.slot_address(),
589 index); 646 index);
590 } 647 }
591 if (index >=0) { 648
592 info->SetExpression(index, *num); 649 info->SetParameter(index, *num);
593 } else { 650 } else if (expressions_top <= slot && slot < expressions_bot) {
594 // Calculate parameter index subtracting one for the receiver. 651 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
595 int parameter_index = 652
596 index + 653 int index = info->expression_count() - 1 -
597 static_cast<int>(size) / kPointerSize - 654 (slot - expressions_top) / kPointerSize;
598 info->expression_count_ - 1; 655
599 info->SetParameter(parameter_index, *num); 656 if (FLAG_trace_deopt) {
657 PrintF("Materializing a new heap number %p [%e] in slot %p"
658 "for expression slot #%d\n",
659 reinterpret_cast<void*>(*num),
660 d.value(),
661 d.slot_address(),
662 index);
600 } 663 }
664
665 info->SetExpression(index, *num);
601 } 666 }
602 } 667 }
603 } 668 }
604 #endif 669 #endif
605 670
606 671
607 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 672 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
608 int frame_index, 673 int frame_index,
609 unsigned output_offset) { 674 unsigned output_offset) {
610 disasm::NameConverter converter; 675 disasm::NameConverter converter;
611 // A GC-safe temporary placeholder that we can put in the output frame. 676 // A GC-safe temporary placeholder that we can put in the output frame.
612 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 677 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
613 678
614 // Ignore commands marked as duplicate and act on the first non-duplicate. 679 // Ignore commands marked as duplicate and act on the first non-duplicate.
615 Translation::Opcode opcode = 680 Translation::Opcode opcode =
616 static_cast<Translation::Opcode>(iterator->Next()); 681 static_cast<Translation::Opcode>(iterator->Next());
617 while (opcode == Translation::DUPLICATE) { 682 while (opcode == Translation::DUPLICATE) {
618 opcode = static_cast<Translation::Opcode>(iterator->Next()); 683 opcode = static_cast<Translation::Opcode>(iterator->Next());
619 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); 684 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
620 opcode = static_cast<Translation::Opcode>(iterator->Next()); 685 opcode = static_cast<Translation::Opcode>(iterator->Next());
621 } 686 }
622 687
623 switch (opcode) { 688 switch (opcode) {
624 case Translation::BEGIN: 689 case Translation::BEGIN:
625 case Translation::FRAME: 690 case Translation::JS_FRAME:
691 case Translation::ARGUMENTS_ADAPTOR_FRAME:
626 case Translation::DUPLICATE: 692 case Translation::DUPLICATE:
627 UNREACHABLE(); 693 UNREACHABLE();
628 return; 694 return;
629 695
630 case Translation::REGISTER: { 696 case Translation::REGISTER: {
631 int input_reg = iterator->Next(); 697 int input_reg = iterator->Next();
632 intptr_t input_value = input_->GetRegister(input_reg); 698 intptr_t input_value = input_->GetRegister(input_reg);
633 if (FLAG_trace_deopt) { 699 if (FLAG_trace_deopt) {
634 PrintF( 700 PrintF(
635 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", 701 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ",
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 // We save the untagged value on the side and store a GC-safe 750 // We save the untagged value on the side and store a GC-safe
685 // temporary placeholder in the frame. 751 // temporary placeholder in the frame.
686 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value); 752 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
687 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 753 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
688 return; 754 return;
689 } 755 }
690 756
691 case Translation::STACK_SLOT: { 757 case Translation::STACK_SLOT: {
692 int input_slot_index = iterator->Next(); 758 int input_slot_index = iterator->Next();
693 unsigned input_offset = 759 unsigned input_offset =
694 input_->GetOffsetFromSlotIndex(this, input_slot_index); 760 input_->GetOffsetFromSlotIndex(input_slot_index);
695 intptr_t input_value = input_->GetFrameSlot(input_offset); 761 intptr_t input_value = input_->GetFrameSlot(input_offset);
696 if (FLAG_trace_deopt) { 762 if (FLAG_trace_deopt) {
697 PrintF(" 0x%08" V8PRIxPTR ": ", 763 PrintF(" 0x%08" V8PRIxPTR ": ",
698 output_[frame_index]->GetTop() + output_offset); 764 output_[frame_index]->GetTop() + output_offset);
699 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d] ", 765 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d] ",
700 output_offset, 766 output_offset,
701 input_value, 767 input_value,
702 input_offset); 768 input_offset);
703 reinterpret_cast<Object*>(input_value)->ShortPrint(); 769 reinterpret_cast<Object*>(input_value)->ShortPrint();
704 PrintF("\n"); 770 PrintF("\n");
705 } 771 }
706 output_[frame_index]->SetFrameSlot(output_offset, input_value); 772 output_[frame_index]->SetFrameSlot(output_offset, input_value);
707 return; 773 return;
708 } 774 }
709 775
710 case Translation::INT32_STACK_SLOT: { 776 case Translation::INT32_STACK_SLOT: {
711 int input_slot_index = iterator->Next(); 777 int input_slot_index = iterator->Next();
712 unsigned input_offset = 778 unsigned input_offset =
713 input_->GetOffsetFromSlotIndex(this, input_slot_index); 779 input_->GetOffsetFromSlotIndex(input_slot_index);
714 intptr_t value = input_->GetFrameSlot(input_offset); 780 intptr_t value = input_->GetFrameSlot(input_offset);
715 bool is_smi = Smi::IsValid(value); 781 bool is_smi = Smi::IsValid(value);
716 if (FLAG_trace_deopt) { 782 if (FLAG_trace_deopt) {
717 PrintF(" 0x%08" V8PRIxPTR ": ", 783 PrintF(" 0x%08" V8PRIxPTR ": ",
718 output_[frame_index]->GetTop() + output_offset); 784 output_[frame_index]->GetTop() + output_offset);
719 PrintF("[top + %d] <- %" V8PRIdPTR " ; [esp + %d] (%s)\n", 785 PrintF("[top + %d] <- %" V8PRIdPTR " ; [esp + %d] (%s)\n",
720 output_offset, 786 output_offset,
721 value, 787 value,
722 input_offset, 788 input_offset,
723 is_smi ? "smi" : "heap number"); 789 is_smi ? "smi" : "heap number");
724 } 790 }
725 if (is_smi) { 791 if (is_smi) {
726 intptr_t tagged_value = 792 intptr_t tagged_value =
727 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 793 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
728 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 794 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
729 } else { 795 } else {
730 // We save the untagged value on the side and store a GC-safe 796 // We save the untagged value on the side and store a GC-safe
731 // temporary placeholder in the frame. 797 // temporary placeholder in the frame.
732 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, 798 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
733 static_cast<double>(static_cast<int32_t>(value))); 799 static_cast<double>(static_cast<int32_t>(value)));
734 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 800 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
735 } 801 }
736 return; 802 return;
737 } 803 }
738 804
739 case Translation::DOUBLE_STACK_SLOT: { 805 case Translation::DOUBLE_STACK_SLOT: {
740 int input_slot_index = iterator->Next(); 806 int input_slot_index = iterator->Next();
741 unsigned input_offset = 807 unsigned input_offset =
742 input_->GetOffsetFromSlotIndex(this, input_slot_index); 808 input_->GetOffsetFromSlotIndex(input_slot_index);
743 double value = input_->GetDoubleFrameSlot(input_offset); 809 double value = input_->GetDoubleFrameSlot(input_offset);
744 if (FLAG_trace_deopt) { 810 if (FLAG_trace_deopt) {
745 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [esp + %d]\n", 811 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [esp + %d]\n",
746 output_[frame_index]->GetTop() + output_offset, 812 output_[frame_index]->GetTop() + output_offset,
747 output_offset, 813 output_offset,
748 value, 814 value,
749 input_offset); 815 input_offset);
750 } 816 }
751 // We save the untagged value on the side and store a GC-safe 817 // We save the untagged value on the side and store a GC-safe
752 // temporary placeholder in the frame. 818 // temporary placeholder in the frame.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 867
802 Translation::Opcode opcode = 868 Translation::Opcode opcode =
803 static_cast<Translation::Opcode>(iterator->Next()); 869 static_cast<Translation::Opcode>(iterator->Next());
804 bool duplicate = (opcode == Translation::DUPLICATE); 870 bool duplicate = (opcode == Translation::DUPLICATE);
805 if (duplicate) { 871 if (duplicate) {
806 opcode = static_cast<Translation::Opcode>(iterator->Next()); 872 opcode = static_cast<Translation::Opcode>(iterator->Next());
807 } 873 }
808 874
809 switch (opcode) { 875 switch (opcode) {
810 case Translation::BEGIN: 876 case Translation::BEGIN:
811 case Translation::FRAME: 877 case Translation::JS_FRAME:
878 case Translation::ARGUMENTS_ADAPTOR_FRAME:
812 case Translation::DUPLICATE: 879 case Translation::DUPLICATE:
813 UNREACHABLE(); // Malformed input. 880 UNREACHABLE(); // Malformed input.
814 return false; 881 return false;
815 882
816 case Translation::REGISTER: { 883 case Translation::REGISTER: {
817 int output_reg = iterator->Next(); 884 int output_reg = iterator->Next();
818 if (FLAG_trace_osr) { 885 if (FLAG_trace_osr) {
819 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", 886 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n",
820 converter.NameOfCPURegister(output_reg), 887 converter.NameOfCPURegister(output_reg),
821 input_value, 888 input_value,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 double_value, 931 double_value,
865 *input_offset); 932 *input_offset);
866 } 933 }
867 output->SetDoubleRegister(output_reg, double_value); 934 output->SetDoubleRegister(output_reg, double_value);
868 break; 935 break;
869 } 936 }
870 937
871 case Translation::STACK_SLOT: { 938 case Translation::STACK_SLOT: {
872 int output_index = iterator->Next(); 939 int output_index = iterator->Next();
873 unsigned output_offset = 940 unsigned output_offset =
874 output->GetOffsetFromSlotIndex(this, output_index); 941 output->GetOffsetFromSlotIndex(output_index);
875 if (FLAG_trace_osr) { 942 if (FLAG_trace_osr) {
876 PrintF(" [sp + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ", 943 PrintF(" [sp + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
877 output_offset, 944 output_offset,
878 input_value, 945 input_value,
879 *input_offset); 946 *input_offset);
880 reinterpret_cast<Object*>(input_value)->ShortPrint(); 947 reinterpret_cast<Object*>(input_value)->ShortPrint();
881 PrintF("\n"); 948 PrintF("\n");
882 } 949 }
883 output->SetFrameSlot(output_offset, input_value); 950 output->SetFrameSlot(output_offset, input_value);
884 break; 951 break;
885 } 952 }
886 953
887 case Translation::INT32_STACK_SLOT: { 954 case Translation::INT32_STACK_SLOT: {
888 // Abort OSR if we don't have a number. 955 // Abort OSR if we don't have a number.
889 if (!input_object->IsNumber()) return false; 956 if (!input_object->IsNumber()) return false;
890 957
891 int output_index = iterator->Next(); 958 int output_index = iterator->Next();
892 unsigned output_offset = 959 unsigned output_offset =
893 output->GetOffsetFromSlotIndex(this, output_index); 960 output->GetOffsetFromSlotIndex(output_index);
894 int int32_value = input_object->IsSmi() 961 int int32_value = input_object->IsSmi()
895 ? Smi::cast(input_object)->value() 962 ? Smi::cast(input_object)->value()
896 : DoubleToInt32(input_object->Number()); 963 : DoubleToInt32(input_object->Number());
897 // Abort the translation if the conversion lost information. 964 // Abort the translation if the conversion lost information.
898 if (!input_object->IsSmi() && 965 if (!input_object->IsSmi() &&
899 FastI2D(int32_value) != input_object->Number()) { 966 FastI2D(int32_value) != input_object->Number()) {
900 if (FLAG_trace_osr) { 967 if (FLAG_trace_osr) {
901 PrintF("**** %g could not be converted to int32 ****\n", 968 PrintF("**** %g could not be converted to int32 ****\n",
902 input_object->Number()); 969 input_object->Number());
903 } 970 }
(...skipping 11 matching lines...) Expand all
915 982
916 case Translation::DOUBLE_STACK_SLOT: { 983 case Translation::DOUBLE_STACK_SLOT: {
917 static const int kLowerOffset = 0 * kPointerSize; 984 static const int kLowerOffset = 0 * kPointerSize;
918 static const int kUpperOffset = 1 * kPointerSize; 985 static const int kUpperOffset = 1 * kPointerSize;
919 986
920 // Abort OSR if we don't have a number. 987 // Abort OSR if we don't have a number.
921 if (!input_object->IsNumber()) return false; 988 if (!input_object->IsNumber()) return false;
922 989
923 int output_index = iterator->Next(); 990 int output_index = iterator->Next();
924 unsigned output_offset = 991 unsigned output_offset =
925 output->GetOffsetFromSlotIndex(this, output_index); 992 output->GetOffsetFromSlotIndex(output_index);
926 double double_value = input_object->Number(); 993 double double_value = input_object->Number();
927 uint64_t int_value = BitCast<uint64_t, double>(double_value); 994 uint64_t int_value = BitCast<uint64_t, double>(double_value);
928 int32_t lower = static_cast<int32_t>(int_value); 995 int32_t lower = static_cast<int32_t>(int_value);
929 int32_t upper = static_cast<int32_t>(int_value >> kBitsPerInt); 996 int32_t upper = static_cast<int32_t>(int_value >> kBitsPerInt);
930 if (FLAG_trace_osr) { 997 if (FLAG_trace_osr) {
931 PrintF(" [sp + %d] <- 0x%08x (upper bits of %g) ; [sp + %d]\n", 998 PrintF(" [sp + %d] <- 0x%08x (upper bits of %g) ; [sp + %d]\n",
932 output_offset + kUpperOffset, 999 output_offset + kUpperOffset,
933 upper, 1000 upper,
934 double_value, 1001 double_value,
935 *input_offset); 1002 *input_offset);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); 1093 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
1027 } 1094 }
1028 #endif 1095 #endif
1029 return result; 1096 return result;
1030 } 1097 }
1031 1098
1032 1099
1033 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { 1100 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const {
1034 // The fixed part of the frame consists of the return address, frame 1101 // The fixed part of the frame consists of the return address, frame
1035 // pointer, function, context, and all the incoming arguments. 1102 // pointer, function, context, and all the incoming arguments.
1036 static const unsigned kFixedSlotSize = 4 * kPointerSize; 1103 return ComputeIncomingArgumentSize(function) +
1037 return ComputeIncomingArgumentSize(function) + kFixedSlotSize; 1104 StandardFrameConstants::kFixedFrameSize * kPointerSize;
1038 } 1105 }
1039 1106
1040 1107
1041 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { 1108 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const {
1042 // The incoming arguments is the values for formal parameters and 1109 // The incoming arguments is the values for formal parameters and
1043 // the receiver. Every slot contains a pointer. 1110 // the receiver. Every slot contains a pointer.
1044 unsigned arguments = function->shared()->formal_parameter_count() + 1; 1111 unsigned arguments = function->shared()->formal_parameter_count() + 1;
1045 return arguments * kPointerSize; 1112 return arguments * kPointerSize;
1046 } 1113 }
1047 1114
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 SetRegister(r, kZapUint32); 1214 SetRegister(r, kZapUint32);
1148 } 1215 }
1149 1216
1150 // Zap all the slots. 1217 // Zap all the slots.
1151 for (unsigned o = 0; o < frame_size; o += kPointerSize) { 1218 for (unsigned o = 0; o < frame_size; o += kPointerSize) {
1152 SetFrameSlot(o, kZapUint32); 1219 SetFrameSlot(o, kZapUint32);
1153 } 1220 }
1154 } 1221 }
1155 1222
1156 1223
1157 unsigned FrameDescription::GetOffsetFromSlotIndex(Deoptimizer* deoptimizer, 1224 int FrameDescription::ComputeFixedSize() {
1158 int slot_index) { 1225 return StandardFrameConstants::kFixedFrameSize * kPointerSize +
1226 (ComputeParametersCount() + 1) * kPointerSize;
1227 }
1228
1229
1230 unsigned FrameDescription::GetOffsetFromSlotIndex(int slot_index) {
1159 if (slot_index >= 0) { 1231 if (slot_index >= 0) {
1160 // Local or spill slots. Skip the fixed part of the frame 1232 // Local or spill slots. Skip the fixed part of the frame
1161 // including all arguments. 1233 // including all arguments.
1162 unsigned base = 1234 unsigned base = GetFrameSize() - ComputeFixedSize();
1163 GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction());
1164 return base - ((slot_index + 1) * kPointerSize); 1235 return base - ((slot_index + 1) * kPointerSize);
1165 } else { 1236 } else {
1166 // Incoming parameter. 1237 // Incoming parameter.
1167 unsigned base = GetFrameSize() - 1238 int arg_size = (ComputeParametersCount() + 1) * kPointerSize;
1168 deoptimizer->ComputeIncomingArgumentSize(GetFunction()); 1239 unsigned base = GetFrameSize() - arg_size;
1169 return base - ((slot_index + 1) * kPointerSize); 1240 return base - ((slot_index + 1) * kPointerSize);
1170 } 1241 }
1171 } 1242 }
1172 1243
1173 1244
1174 int FrameDescription::ComputeParametersCount() { 1245 int FrameDescription::ComputeParametersCount() {
1175 return function_->shared()->formal_parameter_count(); 1246 switch (type_) {
1247 case StackFrame::JAVA_SCRIPT:
1248 return function_->shared()->formal_parameter_count();
1249 case StackFrame::ARGUMENTS_ADAPTOR: {
1250 // Last slot contains number of incomming arguments as a smi.
1251 // Can't use GetExpression(0) because it would cause infinite recursion.
1252 return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
1253 }
1254 default:
1255 UNREACHABLE();
1256 return 0;
1257 }
1176 } 1258 }
1177 1259
1178 1260
1179 Object* FrameDescription::GetParameter(Deoptimizer* deoptimizer, int index) { 1261 Object* FrameDescription::GetParameter(int index) {
1180 ASSERT_EQ(Code::FUNCTION, kind_);
1181 ASSERT(index >= 0); 1262 ASSERT(index >= 0);
1182 ASSERT(index < ComputeParametersCount()); 1263 ASSERT(index < ComputeParametersCount());
1183 // The slot indexes for incoming arguments are negative. 1264 // The slot indexes for incoming arguments are negative.
1184 unsigned offset = GetOffsetFromSlotIndex(deoptimizer, 1265 unsigned offset = GetOffsetFromSlotIndex(index - ComputeParametersCount());
1185 index - ComputeParametersCount());
1186 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 1266 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
1187 } 1267 }
1188 1268
1189 1269
1190 unsigned FrameDescription::GetExpressionCount(Deoptimizer* deoptimizer) { 1270 unsigned FrameDescription::GetExpressionCount() {
1191 ASSERT_EQ(Code::FUNCTION, kind_); 1271 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
1192 unsigned size = GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction()); 1272 unsigned size = GetFrameSize() - ComputeFixedSize();
1193 return size / kPointerSize; 1273 return size / kPointerSize;
1194 } 1274 }
1195 1275
1196 1276
1197 Object* FrameDescription::GetExpression(Deoptimizer* deoptimizer, int index) { 1277 Object* FrameDescription::GetExpression(int index) {
1198 ASSERT_EQ(Code::FUNCTION, kind_); 1278 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
1199 unsigned offset = GetOffsetFromSlotIndex(deoptimizer, index); 1279 unsigned offset = GetOffsetFromSlotIndex(index);
1200 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset)); 1280 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
1201 } 1281 }
1202 1282
1203 1283
1204 void TranslationBuffer::Add(int32_t value) { 1284 void TranslationBuffer::Add(int32_t value) {
1205 // Encode the sign bit in the least significant bit. 1285 // Encode the sign bit in the least significant bit.
1206 bool is_negative = (value < 0); 1286 bool is_negative = (value < 0);
1207 uint32_t bits = ((is_negative ? -value : value) << 1) | 1287 uint32_t bits = ((is_negative ? -value : value) << 1) |
1208 static_cast<int32_t>(is_negative); 1288 static_cast<int32_t>(is_negative);
1209 // Encode the individual bytes using the least significant bit of 1289 // Encode the individual bytes using the least significant bit of
(...skipping 25 matching lines...) Expand all
1235 1315
1236 Handle<ByteArray> TranslationBuffer::CreateByteArray() { 1316 Handle<ByteArray> TranslationBuffer::CreateByteArray() {
1237 int length = contents_.length(); 1317 int length = contents_.length();
1238 Handle<ByteArray> result = 1318 Handle<ByteArray> result =
1239 Isolate::Current()->factory()->NewByteArray(length, TENURED); 1319 Isolate::Current()->factory()->NewByteArray(length, TENURED);
1240 memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length); 1320 memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
1241 return result; 1321 return result;
1242 } 1322 }
1243 1323
1244 1324
1245 void Translation::BeginFrame(int node_id, int literal_id, unsigned height) { 1325 void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) {
1246 buffer_->Add(FRAME); 1326 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME);
1327 buffer_->Add(literal_id);
1328 buffer_->Add(height);
1329 }
1330
1331
1332 void Translation::BeginJSFrame(int node_id, int literal_id, unsigned height) {
1333 buffer_->Add(JS_FRAME);
1247 buffer_->Add(node_id); 1334 buffer_->Add(node_id);
1248 buffer_->Add(literal_id); 1335 buffer_->Add(literal_id);
1249 buffer_->Add(height); 1336 buffer_->Add(height);
1250 } 1337 }
1251 1338
1252 1339
1253 void Translation::StoreRegister(Register reg) { 1340 void Translation::StoreRegister(Register reg) {
1254 buffer_->Add(REGISTER); 1341 buffer_->Add(REGISTER);
1255 buffer_->Add(reg.code()); 1342 buffer_->Add(reg.code());
1256 } 1343 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 void Translation::MarkDuplicate() { 1387 void Translation::MarkDuplicate() {
1301 buffer_->Add(DUPLICATE); 1388 buffer_->Add(DUPLICATE);
1302 } 1389 }
1303 1390
1304 1391
1305 int Translation::NumberOfOperandsFor(Opcode opcode) { 1392 int Translation::NumberOfOperandsFor(Opcode opcode) {
1306 switch (opcode) { 1393 switch (opcode) {
1307 case ARGUMENTS_OBJECT: 1394 case ARGUMENTS_OBJECT:
1308 case DUPLICATE: 1395 case DUPLICATE:
1309 return 0; 1396 return 0;
1310 case BEGIN:
1311 case REGISTER: 1397 case REGISTER:
1312 case INT32_REGISTER: 1398 case INT32_REGISTER:
1313 case DOUBLE_REGISTER: 1399 case DOUBLE_REGISTER:
1314 case STACK_SLOT: 1400 case STACK_SLOT:
1315 case INT32_STACK_SLOT: 1401 case INT32_STACK_SLOT:
1316 case DOUBLE_STACK_SLOT: 1402 case DOUBLE_STACK_SLOT:
1317 case LITERAL: 1403 case LITERAL:
1318 return 1; 1404 return 1;
1319 case FRAME: 1405 case BEGIN:
1406 case ARGUMENTS_ADAPTOR_FRAME:
1407 return 2;
1408 case JS_FRAME:
1320 return 3; 1409 return 3;
1321 } 1410 }
1322 UNREACHABLE(); 1411 UNREACHABLE();
1323 return -1; 1412 return -1;
1324 } 1413 }
1325 1414
1326 1415
1327 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 1416 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
1328 1417
1329 const char* Translation::StringFor(Opcode opcode) { 1418 const char* Translation::StringFor(Opcode opcode) {
1330 switch (opcode) { 1419 switch (opcode) {
1331 case BEGIN: 1420 case BEGIN:
1332 return "BEGIN"; 1421 return "BEGIN";
1333 case FRAME: 1422 case JS_FRAME:
1334 return "FRAME"; 1423 return "JS_FRAME";
1424 case ARGUMENTS_ADAPTOR_FRAME:
1425 return "ARGUMENTS_ADAPTOR_FRAME";
1335 case REGISTER: 1426 case REGISTER:
1336 return "REGISTER"; 1427 return "REGISTER";
1337 case INT32_REGISTER: 1428 case INT32_REGISTER:
1338 return "INT32_REGISTER"; 1429 return "INT32_REGISTER";
1339 case DOUBLE_REGISTER: 1430 case DOUBLE_REGISTER:
1340 return "DOUBLE_REGISTER"; 1431 return "DOUBLE_REGISTER";
1341 case STACK_SLOT: 1432 case STACK_SLOT:
1342 return "STACK_SLOT"; 1433 return "STACK_SLOT";
1343 case INT32_STACK_SLOT: 1434 case INT32_STACK_SLOT:
1344 return "INT32_STACK_SLOT"; 1435 return "INT32_STACK_SLOT";
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 // deoptimization infrastracture is not GC safe. 1469 // deoptimization infrastracture is not GC safe.
1379 // Thus we build a temporary structure in malloced space. 1470 // Thus we build a temporary structure in malloced space.
1380 SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, 1471 SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
1381 DeoptimizationInputData* data, 1472 DeoptimizationInputData* data,
1382 JavaScriptFrame* frame) { 1473 JavaScriptFrame* frame) {
1383 Translation::Opcode opcode = 1474 Translation::Opcode opcode =
1384 static_cast<Translation::Opcode>(iterator->Next()); 1475 static_cast<Translation::Opcode>(iterator->Next());
1385 1476
1386 switch (opcode) { 1477 switch (opcode) {
1387 case Translation::BEGIN: 1478 case Translation::BEGIN:
1388 case Translation::FRAME: 1479 case Translation::JS_FRAME:
1480 case Translation::ARGUMENTS_ADAPTOR_FRAME:
1389 // Peeled off before getting here. 1481 // Peeled off before getting here.
1390 break; 1482 break;
1391 1483
1392 case Translation::ARGUMENTS_OBJECT: 1484 case Translation::ARGUMENTS_OBJECT:
1393 // This can be only emitted for local slots not for argument slots. 1485 // This can be only emitted for local slots not for argument slots.
1394 break; 1486 break;
1395 1487
1396 case Translation::REGISTER: 1488 case Translation::REGISTER:
1397 case Translation::INT32_REGISTER: 1489 case Translation::INT32_REGISTER:
1398 case Translation::DOUBLE_REGISTER: 1490 case Translation::DOUBLE_REGISTER:
(...skipping 25 matching lines...) Expand all
1424 int literal_index = iterator->Next(); 1516 int literal_index = iterator->Next();
1425 return SlotRef(data->LiteralArray()->get(literal_index)); 1517 return SlotRef(data->LiteralArray()->get(literal_index));
1426 } 1518 }
1427 } 1519 }
1428 1520
1429 UNREACHABLE(); 1521 UNREACHABLE();
1430 return SlotRef(); 1522 return SlotRef();
1431 } 1523 }
1432 1524
1433 1525
1434 void SlotRef::ComputeSlotMappingForArguments(JavaScriptFrame* frame, 1526 void SlotRef::ComputeSlotsForArguments(Vector<SlotRef>* args_slots,
1435 int inlined_frame_index, 1527 TranslationIterator* it,
1436 Vector<SlotRef>* args_slots) { 1528 DeoptimizationInputData* data,
1529 JavaScriptFrame* frame) {
1530 // Process the translation commands for the arguments.
1531
1532 // Skip the translation command for the receiver.
1533 it->Skip(Translation::NumberOfOperandsFor(
1534 static_cast<Translation::Opcode>(it->Next())));
1535
1536 // Compute slots for arguments.
1537 for (int i = 0; i < args_slots->length(); ++i) {
1538 (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame);
1539 }
1540 }
1541
1542
1543 Vector<SlotRef> SlotRef::ComputeSlotMappingForArguments(
1544 JavaScriptFrame* frame,
1545 int inlined_jsframe_index,
1546 int formal_parameter_count) {
1437 AssertNoAllocation no_gc; 1547 AssertNoAllocation no_gc;
1438 int deopt_index = AstNode::kNoNumber; 1548 int deopt_index = AstNode::kNoNumber;
1439 DeoptimizationInputData* data = 1549 DeoptimizationInputData* data =
1440 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index); 1550 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
1441 TranslationIterator it(data->TranslationByteArray(), 1551 TranslationIterator it(data->TranslationByteArray(),
1442 data->TranslationIndex(deopt_index)->value()); 1552 data->TranslationIndex(deopt_index)->value());
1443 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next()); 1553 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
1444 ASSERT(opcode == Translation::BEGIN); 1554 ASSERT(opcode == Translation::BEGIN);
1445 int frame_count = it.Next(); 1555 it.Next(); // Drop frame count.
1446 USE(frame_count); 1556 int jsframe_count = it.Next();
1447 ASSERT(frame_count > inlined_frame_index); 1557 USE(jsframe_count);
1448 int frames_to_skip = inlined_frame_index; 1558 ASSERT(jsframe_count > inlined_jsframe_index);
1559 int jsframes_to_skip = inlined_jsframe_index;
1449 while (true) { 1560 while (true) {
1450 opcode = static_cast<Translation::Opcode>(it.Next()); 1561 opcode = static_cast<Translation::Opcode>(it.Next());
1562 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
1563 if (jsframes_to_skip == 0) {
1564 ASSERT(Translation::NumberOfOperandsFor(opcode) == 2);
1565
1566 it.Skip(1); // literal id
1567 int height = it.Next();
1568
1569 // We reached the arguments adaptor frame corresponding to the
1570 // inlined function in question. Number of arguments is height - 1.
1571 Vector<SlotRef> args_slots =
1572 Vector<SlotRef>::New(height - 1); // Minus receiver.
1573 ComputeSlotsForArguments(&args_slots, &it, data, frame);
1574 return args_slots;
1575 }
1576 } else if (opcode == Translation::JS_FRAME) {
1577 if (jsframes_to_skip == 0) {
1578 // Skip over operands to advance to the next opcode.
1579 it.Skip(Translation::NumberOfOperandsFor(opcode));
1580
1581 // We reached the frame corresponding to the inlined function
1582 // in question. Process the translation commands for the
1583 // arguments. Number of arguments is equal to the number of
1584 // format parameter count.
1585 Vector<SlotRef> args_slots =
1586 Vector<SlotRef>::New(formal_parameter_count);
1587 ComputeSlotsForArguments(&args_slots, &it, data, frame);
1588 return args_slots;
1589 }
1590 jsframes_to_skip--;
1591 }
1592
1451 // Skip over operands to advance to the next opcode. 1593 // Skip over operands to advance to the next opcode.
1452 it.Skip(Translation::NumberOfOperandsFor(opcode)); 1594 it.Skip(Translation::NumberOfOperandsFor(opcode));
1453 if (opcode == Translation::FRAME) {
1454 if (frames_to_skip == 0) {
1455 // We reached the frame corresponding to the inlined function
1456 // in question. Process the translation commands for the
1457 // arguments.
1458 //
1459 // Skip the translation command for the receiver.
1460 it.Skip(Translation::NumberOfOperandsFor(
1461 static_cast<Translation::Opcode>(it.Next())));
1462 // Compute slots for arguments.
1463 for (int i = 0; i < args_slots->length(); ++i) {
1464 (*args_slots)[i] = ComputeSlotForNextArgument(&it, data, frame);
1465 }
1466 return;
1467 }
1468 frames_to_skip--;
1469 }
1470 } 1595 }
1471 1596
1472 UNREACHABLE(); 1597 UNREACHABLE();
1598 return Vector<SlotRef>();
1473 } 1599 }
1474 1600
1475 #ifdef ENABLE_DEBUGGER_SUPPORT 1601 #ifdef ENABLE_DEBUGGER_SUPPORT
1476 1602
1477 DeoptimizedFrameInfo::DeoptimizedFrameInfo( 1603 DeoptimizedFrameInfo::DeoptimizedFrameInfo(
1478 Deoptimizer* deoptimizer, int frame_index) { 1604 Deoptimizer* deoptimizer, int frame_index, bool has_arguments_adaptor) {
1479 FrameDescription* output_frame = deoptimizer->output_[frame_index]; 1605 FrameDescription* output_frame = deoptimizer->output_[frame_index];
1480 SetFunction(output_frame->GetFunction()); 1606 SetFunction(output_frame->GetFunction());
1481 expression_count_ = output_frame->GetExpressionCount(deoptimizer); 1607 expression_count_ = output_frame->GetExpressionCount();
1608 expression_stack_ = new Object*[expression_count_];
1609 for (int i = 0; i < expression_count_; i++) {
1610 SetExpression(i, output_frame->GetExpression(i));
1611 }
1612
1613 if (has_arguments_adaptor) {
1614 output_frame = deoptimizer->output_[frame_index - 1];
1615 ASSERT(output_frame->GetType() == StackFrame::ARGUMENTS_ADAPTOR);
1616 }
1617
1482 parameters_count_ = output_frame->ComputeParametersCount(); 1618 parameters_count_ = output_frame->ComputeParametersCount();
1483 parameters_ = new Object*[parameters_count_]; 1619 parameters_ = new Object*[parameters_count_];
1484 for (int i = 0; i < parameters_count_; i++) { 1620 for (int i = 0; i < parameters_count_; i++) {
1485 SetParameter(i, output_frame->GetParameter(deoptimizer, i)); 1621 SetParameter(i, output_frame->GetParameter(i));
1486 }
1487 expression_stack_ = new Object*[expression_count_];
1488 for (int i = 0; i < expression_count_; i++) {
1489 SetExpression(i, output_frame->GetExpression(deoptimizer, i));
1490 } 1622 }
1491 } 1623 }
1492 1624
1493 1625
1494 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() { 1626 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
1495 delete[] expression_stack_; 1627 delete[] expression_stack_;
1496 delete[] parameters_; 1628 delete[] parameters_;
1497 } 1629 }
1498 1630
1499 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { 1631 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
1500 v->VisitPointer(BitCast<Object**>(&function_)); 1632 v->VisitPointer(BitCast<Object**>(&function_));
1501 v->VisitPointers(parameters_, parameters_ + parameters_count_); 1633 v->VisitPointers(parameters_, parameters_ + parameters_count_);
1502 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); 1634 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
1503 } 1635 }
1504 1636
1505 #endif // ENABLE_DEBUGGER_SUPPORT 1637 #endif // ENABLE_DEBUGGER_SUPPORT
1506 1638
1507 } } // namespace v8::internal 1639 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698