OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/address-map.h" | 7 #include "src/address-map.h" |
8 #include "src/base/adapters.h" | 8 #include "src/base/adapters.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 handlers_(code->zone()), | 51 handlers_(code->zone()), |
52 deoptimization_exits_(code->zone()), | 52 deoptimization_exits_(code->zone()), |
53 deoptimization_states_(code->zone()), | 53 deoptimization_states_(code->zone()), |
54 deoptimization_literals_(code->zone()), | 54 deoptimization_literals_(code->zone()), |
55 inlined_function_count_(0), | 55 inlined_function_count_(0), |
56 translations_(code->zone()), | 56 translations_(code->zone()), |
57 last_lazy_deopt_pc_(0), | 57 last_lazy_deopt_pc_(0), |
58 jump_tables_(nullptr), | 58 jump_tables_(nullptr), |
59 ools_(nullptr), | 59 ools_(nullptr), |
60 osr_pc_offset_(-1), | 60 osr_pc_offset_(-1), |
| 61 optimized_out_literal_id_(-1), |
61 source_position_table_builder_(code->zone(), | 62 source_position_table_builder_(code->zone(), |
62 info->SourcePositionRecordingMode()), | 63 info->SourcePositionRecordingMode()), |
63 protected_instructions_(protected_instructions) { | 64 protected_instructions_(protected_instructions) { |
64 for (int i = 0; i < code->InstructionBlockCount(); ++i) { | 65 for (int i = 0; i < code->InstructionBlockCount(); ++i) { |
65 new (&labels_[i]) Label; | 66 new (&labels_[i]) Label; |
66 } | 67 } |
67 CreateFrameAccessState(frame); | 68 CreateFrameAccessState(frame); |
68 } | 69 } |
69 | 70 |
70 Isolate* CodeGenerator::isolate() const { return info_->isolate(); } | 71 Isolate* CodeGenerator::isolate() const { return info_->isolate(); } |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 // If the pre-call frame state differs from the post-call one, produce the | 634 // If the pre-call frame state differs from the post-call one, produce the |
634 // pre-call frame state, too. | 635 // pre-call frame state, too. |
635 // TODO(jarin) We might want to avoid building the pre-call frame state | 636 // TODO(jarin) We might want to avoid building the pre-call frame state |
636 // because it is only used to get locals and arguments (by the debugger and | 637 // because it is only used to get locals and arguments (by the debugger and |
637 // f.arguments), and those are the same in the pre-call and post-call | 638 // f.arguments), and those are the same in the pre-call and post-call |
638 // states. | 639 // states. |
639 if (!descriptor->state_combine().IsOutputIgnored()) { | 640 if (!descriptor->state_combine().IsOutputIgnored()) { |
640 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, | 641 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, |
641 OutputFrameStateCombine::Ignore()); | 642 OutputFrameStateCombine::Ignore()); |
642 } | 643 } |
643 #if DEBUG | |
644 // Make sure all the values live in stack slots or they are immediates. | |
645 // (The values should not live in register because registers are clobbered | |
646 // by calls.) | |
647 for (size_t i = 0; i < descriptor->GetSize(); i++) { | |
648 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); | |
649 CHECK(op->IsStackSlot() || op->IsFPStackSlot() || op->IsImmediate()); | |
650 } | |
651 #endif | |
652 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); | 644 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); |
653 } | 645 } |
654 } | 646 } |
655 | 647 |
656 | 648 |
657 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { | 649 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { |
658 int result = static_cast<int>(deoptimization_literals_.size()); | 650 int result = static_cast<int>(deoptimization_literals_.size()); |
659 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { | 651 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { |
660 if (deoptimization_literals_[i].is_identical_to(literal)) return i; | 652 if (deoptimization_literals_[i].is_identical_to(literal)) return i; |
661 } | 653 } |
662 deoptimization_literals_.push_back(literal); | 654 deoptimization_literals_.push_back(literal); |
663 return result; | 655 return result; |
664 } | 656 } |
665 | 657 |
666 DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry( | 658 DeoptimizationEntry const& CodeGenerator::GetDeoptimizationEntry( |
667 Instruction* instr, size_t frame_state_offset) { | 659 Instruction* instr, size_t frame_state_offset) { |
668 InstructionOperandConverter i(this, instr); | 660 InstructionOperandConverter i(this, instr); |
669 int const state_id = i.InputInt32(frame_state_offset); | 661 int const state_id = i.InputInt32(frame_state_offset); |
670 return code()->GetDeoptimizationEntry(state_id); | 662 return code()->GetDeoptimizationEntry(state_id); |
671 } | 663 } |
672 | 664 |
673 DeoptimizeReason CodeGenerator::GetDeoptimizationReason( | 665 DeoptimizeReason CodeGenerator::GetDeoptimizationReason( |
674 int deoptimization_id) const { | 666 int deoptimization_id) const { |
675 size_t const index = static_cast<size_t>(deoptimization_id); | 667 size_t const index = static_cast<size_t>(deoptimization_id); |
676 DCHECK_LT(index, deoptimization_states_.size()); | 668 DCHECK_LT(index, deoptimization_states_.size()); |
677 return deoptimization_states_[index]->reason(); | 669 return deoptimization_states_[index]->reason(); |
678 } | 670 } |
679 | 671 |
680 void CodeGenerator::TranslateStateValueDescriptor( | 672 void CodeGenerator::TranslateStateValueDescriptor( |
681 StateValueDescriptor* desc, Translation* translation, | 673 StateValueDescriptor* desc, StateValueList* nested, |
682 InstructionOperandIterator* iter) { | 674 Translation* translation, InstructionOperandIterator* iter) { |
683 if (desc->IsNested()) { | 675 if (desc->IsNested()) { |
684 translation->BeginCapturedObject(static_cast<int>(desc->size())); | 676 translation->BeginCapturedObject(static_cast<int>(nested->size())); |
685 for (size_t index = 0; index < desc->fields().size(); index++) { | 677 for (auto field : *nested) { |
686 TranslateStateValueDescriptor(&desc->fields()[index], translation, iter); | 678 TranslateStateValueDescriptor(field.desc, field.nested, translation, |
| 679 iter); |
687 } | 680 } |
688 } else if (desc->IsDuplicate()) { | 681 } else if (desc->IsDuplicate()) { |
689 translation->DuplicateObject(static_cast<int>(desc->id())); | 682 translation->DuplicateObject(static_cast<int>(desc->id())); |
690 } else { | 683 } else if (desc->IsPlain()) { |
691 DCHECK(desc->IsPlain()); | |
692 AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), | 684 AddTranslationForOperand(translation, iter->instruction(), iter->Advance(), |
693 desc->type()); | 685 desc->type()); |
| 686 } else { |
| 687 DCHECK(desc->IsOptimizedOut()); |
| 688 if (optimized_out_literal_id_ == -1) { |
| 689 optimized_out_literal_id_ = |
| 690 DefineDeoptimizationLiteral(isolate()->factory()->optimized_out()); |
| 691 } |
| 692 translation->StoreLiteral(optimized_out_literal_id_); |
694 } | 693 } |
695 } | 694 } |
696 | 695 |
697 | 696 |
698 void CodeGenerator::TranslateFrameStateDescriptorOperands( | 697 void CodeGenerator::TranslateFrameStateDescriptorOperands( |
699 FrameStateDescriptor* desc, InstructionOperandIterator* iter, | 698 FrameStateDescriptor* desc, InstructionOperandIterator* iter, |
700 OutputFrameStateCombine combine, Translation* translation) { | 699 OutputFrameStateCombine combine, Translation* translation) { |
701 for (size_t index = 0; index < desc->GetSize(combine); index++) { | 700 size_t index = 0; |
702 switch (combine.kind()) { | 701 StateValueList* values = desc->GetStateValueDescriptors(); |
703 case OutputFrameStateCombine::kPushOutput: { | 702 for (StateValueList::iterator it = values->begin(); it != values->end(); |
704 DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); | 703 ++it, ++index) { |
705 size_t size_without_output = | 704 if (combine.kind() == OutputFrameStateCombine::kPokeAt) { |
706 desc->GetSize(OutputFrameStateCombine::Ignore()); | 705 // The result of the call should be placed at position |
707 // If the index is past the existing stack items in values_. | 706 // [index_from_top] in the stack (overwriting whatever was |
708 if (index >= size_without_output) { | 707 // previously there). |
709 // Materialize the result of the call instruction in this slot. | 708 size_t index_from_top = |
710 AddTranslationForOperand( | 709 desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); |
711 translation, iter->instruction(), | 710 if (index >= index_from_top && |
712 iter->instruction()->OutputAt(index - size_without_output), | 711 index < index_from_top + iter->instruction()->OutputCount()) { |
713 MachineType::AnyTagged()); | 712 AddTranslationForOperand( |
714 continue; | 713 translation, iter->instruction(), |
715 } | 714 iter->instruction()->OutputAt(index - index_from_top), |
716 break; | 715 MachineType::AnyTagged()); |
| 716 iter->Advance(); // We do not use this input, but we need to |
| 717 // advace, as the input got replaced. |
| 718 continue; |
717 } | 719 } |
718 case OutputFrameStateCombine::kPokeAt: | |
719 // The result of the call should be placed at position | |
720 // [index_from_top] in the stack (overwriting whatever was | |
721 // previously there). | |
722 size_t index_from_top = | |
723 desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); | |
724 if (index >= index_from_top && | |
725 index < index_from_top + iter->instruction()->OutputCount()) { | |
726 AddTranslationForOperand( | |
727 translation, iter->instruction(), | |
728 iter->instruction()->OutputAt(index - index_from_top), | |
729 MachineType::AnyTagged()); | |
730 iter->Advance(); // We do not use this input, but we need to | |
731 // advace, as the input got replaced. | |
732 continue; | |
733 } | |
734 break; | |
735 } | 720 } |
736 StateValueDescriptor* value_desc = desc->GetStateValueDescriptor(); | 721 TranslateStateValueDescriptor((*it).desc, (*it).nested, translation, iter); |
737 TranslateStateValueDescriptor(&value_desc->fields()[index], translation, | 722 } |
738 iter); | 723 DCHECK_EQ(desc->GetSize(OutputFrameStateCombine::Ignore()), index); |
| 724 |
| 725 if (combine.kind() == OutputFrameStateCombine::kPushOutput) { |
| 726 DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount()); |
| 727 for (size_t output = 0; output < combine.GetPushCount(); output++) { |
| 728 // Materialize the result of the call instruction in this slot. |
| 729 AddTranslationForOperand(translation, iter->instruction(), |
| 730 iter->instruction()->OutputAt(output), |
| 731 MachineType::AnyTagged()); |
| 732 } |
739 } | 733 } |
740 } | 734 } |
741 | 735 |
742 | 736 |
743 void CodeGenerator::BuildTranslationForFrameStateDescriptor( | 737 void CodeGenerator::BuildTranslationForFrameStateDescriptor( |
744 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, | 738 FrameStateDescriptor* descriptor, InstructionOperandIterator* iter, |
745 Translation* translation, OutputFrameStateCombine state_combine) { | 739 Translation* translation, OutputFrameStateCombine state_combine) { |
746 // Outer-most state must be added to translation first. | 740 // Outer-most state must be added to translation first. |
747 if (descriptor->outer_state() != nullptr) { | 741 if (descriptor->outer_state() != nullptr) { |
748 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, | 742 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter, |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { | 967 : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) { |
974 gen->ools_ = this; | 968 gen->ools_ = this; |
975 } | 969 } |
976 | 970 |
977 | 971 |
978 OutOfLineCode::~OutOfLineCode() {} | 972 OutOfLineCode::~OutOfLineCode() {} |
979 | 973 |
980 } // namespace compiler | 974 } // namespace compiler |
981 } // namespace internal | 975 } // namespace internal |
982 } // namespace v8 | 976 } // namespace v8 |
OLD | NEW |