OLD | NEW |
1 // Copyright 2012 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 |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 | 588 |
589 ASSERT(0 == output_offset); | 589 ASSERT(0 == output_offset); |
590 | 590 |
591 uint32_t pc = reinterpret_cast<uint32_t>( | 591 uint32_t pc = reinterpret_cast<uint32_t>( |
592 construct_stub->instruction_start() + | 592 construct_stub->instruction_start() + |
593 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 593 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); |
594 output_frame->SetPc(pc); | 594 output_frame->SetPc(pc); |
595 } | 595 } |
596 | 596 |
597 | 597 |
598 void Deoptimizer::DoComputeSetterStubFrame(TranslationIterator* iterator, | 598 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator, |
599 int frame_index) { | 599 int frame_index, |
600 JSFunction* setter = JSFunction::cast(ComputeLiteral(iterator->Next())); | 600 bool is_setter_stub_frame) { |
601 // The receiver and the implicit return value are expected in registers by the | 601 JSFunction* accessor = JSFunction::cast(ComputeLiteral(iterator->Next())); |
602 // StoreIC, so they don't belong to the output stack frame. This means that we | 602 // The receiver (and the implicit return value, if any) are expected in |
603 // have to use a height of 0. | 603 // registers by the LoadIC/StoreIC, so they don't belong to the output stack |
| 604 // frame. This means that we have to use a height of 0. |
604 unsigned height = 0; | 605 unsigned height = 0; |
605 unsigned height_in_bytes = height * kPointerSize; | 606 unsigned height_in_bytes = height * kPointerSize; |
| 607 const char* kind = is_setter_stub_frame ? "setter" : "getter"; |
606 if (FLAG_trace_deopt) { | 608 if (FLAG_trace_deopt) { |
607 PrintF(" translating setter stub => height=%u\n", height_in_bytes); | 609 PrintF(" translating %s stub => height=%u\n", kind, height_in_bytes); |
608 } | 610 } |
609 | 611 |
610 // We need 5 stack entries from StackFrame::INTERNAL (lr, fp, cp, frame type, | 612 // We need 5 stack entries from StackFrame::INTERNAL (lr, fp, cp, frame type, |
611 // code object, see MacroAssembler::EnterFrame) + 1 stack entry from setter | 613 // code object, see MacroAssembler::EnterFrame). For a setter stub frames we |
612 // stub (implicit return value, see StoreStubCompiler::CompileStoreViaSetter). | 614 // need one additional entry for the implicit return value, see |
613 unsigned fixed_frame_size = (5 + 1) * kPointerSize; | 615 // StoreStubCompiler::CompileStoreViaSetter. |
| 616 unsigned fixed_frame_entries = 5 + (is_setter_stub_frame ? 1 : 0); |
| 617 unsigned fixed_frame_size = fixed_frame_entries * kPointerSize; |
614 unsigned output_frame_size = height_in_bytes + fixed_frame_size; | 618 unsigned output_frame_size = height_in_bytes + fixed_frame_size; |
615 | 619 |
616 // Allocate and store the output frame description. | 620 // Allocate and store the output frame description. |
617 FrameDescription* output_frame = | 621 FrameDescription* output_frame = |
618 new(output_frame_size) FrameDescription(output_frame_size, setter); | 622 new(output_frame_size) FrameDescription(output_frame_size, accessor); |
619 output_frame->SetFrameType(StackFrame::INTERNAL); | 623 output_frame->SetFrameType(StackFrame::INTERNAL); |
620 | 624 |
621 // A frame for a setter stub can not be the topmost or bottommost one. | 625 // A frame for an accessor stub can not be the topmost or bottommost one. |
622 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); | 626 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); |
623 ASSERT(output_[frame_index] == NULL); | 627 ASSERT(output_[frame_index] == NULL); |
624 output_[frame_index] = output_frame; | 628 output_[frame_index] = output_frame; |
625 | 629 |
626 // The top address of the frame is computed from the previous frame's top and | 630 // The top address of the frame is computed from the previous frame's top and |
627 // this frame's size. | 631 // this frame's size. |
628 uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 632 uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size; |
629 output_frame->SetTop(top_address); | 633 output_frame->SetTop(top_address); |
630 | 634 |
631 unsigned output_offset = output_frame_size; | 635 unsigned output_offset = output_frame_size; |
(...skipping 29 matching lines...) Expand all Loading... |
661 " ; context\n", | 665 " ; context\n", |
662 top_address + output_offset, output_offset, value); | 666 top_address + output_offset, output_offset, value); |
663 } | 667 } |
664 | 668 |
665 // A marker value is used in place of the function. | 669 // A marker value is used in place of the function. |
666 output_offset -= kPointerSize; | 670 output_offset -= kPointerSize; |
667 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); | 671 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL)); |
668 output_frame->SetFrameSlot(output_offset, value); | 672 output_frame->SetFrameSlot(output_offset, value); |
669 if (FLAG_trace_deopt) { | 673 if (FLAG_trace_deopt) { |
670 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 674 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
671 " ; function (setter sentinel)\n", | 675 " ; function (%s sentinel)\n", |
672 top_address + output_offset, output_offset, value); | 676 top_address + output_offset, output_offset, value, kind); |
673 } | 677 } |
674 | 678 |
675 // Get Code object from setter stub. | 679 // Get Code object from accessor stub. |
676 output_offset -= kPointerSize; | 680 output_offset -= kPointerSize; |
677 Code* setter_stub = | 681 Builtins::Name name = is_setter_stub_frame ? |
678 isolate_->builtins()->builtin(Builtins::kStoreIC_Setter_ForDeopt); | 682 Builtins::kStoreIC_Setter_ForDeopt : |
679 value = reinterpret_cast<intptr_t>(setter_stub); | 683 Builtins::kLoadIC_Getter_ForDeopt; |
| 684 Code* accessor_stub = isolate_->builtins()->builtin(name); |
| 685 value = reinterpret_cast<intptr_t>(accessor_stub); |
680 output_frame->SetFrameSlot(output_offset, value); | 686 output_frame->SetFrameSlot(output_offset, value); |
681 if (FLAG_trace_deopt) { | 687 if (FLAG_trace_deopt) { |
682 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR | 688 PrintF(" 0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR |
683 " ; code object\n", | 689 " ; code object\n", |
684 top_address + output_offset, output_offset, value); | 690 top_address + output_offset, output_offset, value); |
685 } | 691 } |
686 | 692 |
687 // Skip receiver. | 693 // Skip receiver. |
688 Translation::Opcode opcode = | 694 Translation::Opcode opcode = |
689 static_cast<Translation::Opcode>(iterator->Next()); | 695 static_cast<Translation::Opcode>(iterator->Next()); |
690 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | 696 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); |
691 | 697 |
692 // The implicit return value was part of the artificial setter stub | 698 if (is_setter_stub_frame) { |
693 // environment. | 699 // The implicit return value was part of the artificial setter stub |
694 output_offset -= kPointerSize; | 700 // environment. |
695 DoTranslateCommand(iterator, frame_index, output_offset); | 701 output_offset -= kPointerSize; |
| 702 DoTranslateCommand(iterator, frame_index, output_offset); |
| 703 } |
696 | 704 |
697 ASSERT(0 == output_offset); | 705 ASSERT(0 == output_offset); |
698 | 706 |
| 707 Smi* offset = is_setter_stub_frame ? |
| 708 isolate_->heap()->setter_stub_deopt_pc_offset() : |
| 709 isolate_->heap()->getter_stub_deopt_pc_offset(); |
699 intptr_t pc = reinterpret_cast<intptr_t>( | 710 intptr_t pc = reinterpret_cast<intptr_t>( |
700 setter_stub->instruction_start() + | 711 accessor_stub->instruction_start() + offset->value()); |
701 isolate_->heap()->setter_stub_deopt_pc_offset()->value()); | |
702 output_frame->SetPc(pc); | 712 output_frame->SetPc(pc); |
703 } | 713 } |
704 | 714 |
705 | 715 |
706 // This code is very similar to ia32 code, but relies on register names (fp, sp) | 716 // This code is very similar to ia32 code, but relies on register names (fp, sp) |
707 // and how the frame is laid out. | 717 // and how the frame is laid out. |
708 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, | 718 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, |
709 int frame_index) { | 719 int frame_index) { |
710 // Read the ast node id, function, and frame height for this output frame. | 720 // Read the ast node id, function, and frame height for this output frame. |
711 BailoutId node_id = BailoutId(iterator->Next()); | 721 BailoutId node_id = BailoutId(iterator->Next()); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 __ push(ip); | 1122 __ push(ip); |
1113 __ b(&done); | 1123 __ b(&done); |
1114 ASSERT(masm()->pc_offset() - start == table_entry_size_); | 1124 ASSERT(masm()->pc_offset() - start == table_entry_size_); |
1115 } | 1125 } |
1116 __ bind(&done); | 1126 __ bind(&done); |
1117 } | 1127 } |
1118 | 1128 |
1119 #undef __ | 1129 #undef __ |
1120 | 1130 |
1121 } } // namespace v8::internal | 1131 } } // namespace v8::internal |
OLD | NEW |