Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "lithium-allocator.h" | 28 #include "lithium-allocator-inl.h" |
| 29 | 29 |
| 30 #include "hydrogen.h" | 30 #include "hydrogen.h" |
| 31 #include "string-stream.h" | 31 #include "string-stream.h" |
| 32 | 32 |
| 33 #if V8_TARGET_ARCH_IA32 | 33 #if V8_TARGET_ARCH_IA32 |
| 34 #include "ia32/lithium-ia32.h" | 34 #include "ia32/lithium-ia32.h" |
| 35 #elif V8_TARGET_ARCH_X64 | 35 #elif V8_TARGET_ARCH_X64 |
| 36 #include "x64/lithium-x64.h" | 36 #include "x64/lithium-x64.h" |
| 37 #elif V8_TARGET_ARCH_ARM | 37 #elif V8_TARGET_ARCH_ARM |
| 38 #include "arm/lithium-arm.h" | 38 #include "arm/lithium-arm.h" |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 754 } | 754 } |
| 755 move->AddMove(from, to); | 755 move->AddMove(from, to); |
| 756 } | 756 } |
| 757 | 757 |
| 758 | 758 |
| 759 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { | 759 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { |
| 760 int start = block->first_instruction_index(); | 760 int start = block->first_instruction_index(); |
| 761 int end = block->last_instruction_index(); | 761 int end = block->last_instruction_index(); |
| 762 for (int i = start; i <= end; ++i) { | 762 for (int i = start; i <= end; ++i) { |
| 763 if (chunk_->IsGapAt(i)) { | 763 if (chunk_->IsGapAt(i)) { |
| 764 InstructionSummary* summary = NULL; | 764 LInstruction* instr = NULL; |
| 765 InstructionSummary* prev_summary = NULL; | 765 LInstruction* prev_instr = NULL; |
| 766 if (i < end) summary = GetSummary(i + 1); | 766 if (i < end) instr = chunk_->instructions()->at(i + 1); |
| 767 if (i > start) prev_summary = GetSummary(i - 1); | 767 if (i > start) prev_instr = chunk_->instructions()->at(i - 1); |
| 768 MeetConstraintsBetween(prev_summary, summary, i); | 768 MeetConstraintsBetween(prev_instr, instr, i); |
| 769 } | 769 } |
| 770 } | 770 } |
| 771 } | 771 } |
| 772 | 772 |
| 773 | 773 |
| 774 void LAllocator::MeetConstraintsBetween(InstructionSummary* first, | 774 void LAllocator::MeetConstraintsBetween(LInstruction* first, |
| 775 InstructionSummary* second, | 775 LInstruction* second, |
| 776 int gap_index) { | 776 int gap_index) { |
| 777 // Handle fixed temporaries. | 777 // Handle fixed temporaries. |
| 778 if (first != NULL) { | 778 if (first != NULL) { |
| 779 for (int i = 0; i < first->TempCount(); ++i) { | 779 for (TempIterator it = first->GetTempIterator(); it.HasNext(); ) { |
|
Kevin Millikin (Chromium)
2011/01/20 12:20:30
for (TempIterator it(first); it.HasNext(); it.Adva
fschneider
2011/01/20 17:13:08
Done.
| |
| 780 LUnallocated* temp = LUnallocated::cast(first->TempAt(i)); | 780 LUnallocated* temp = LUnallocated::cast(it.Next()); |
|
Kevin Millikin (Chromium)
2011/01/20 12:20:30
There's an extra space after =.
fschneider
2011/01/20 17:13:08
Done.
| |
| 781 if (temp->HasFixedPolicy()) { | 781 if (temp->HasFixedPolicy()) { |
| 782 AllocateFixed(temp, gap_index - 1, false); | 782 AllocateFixed(temp, gap_index - 1, false); |
| 783 } | 783 } |
| 784 } | 784 } |
| 785 } | 785 } |
| 786 | 786 |
| 787 // Handle fixed output operand. | 787 // Handle fixed output operand. |
| 788 if (first != NULL && first->Output() != NULL) { | 788 if (first != NULL && first->Output() != NULL) { |
| 789 LUnallocated* first_output = LUnallocated::cast(first->Output()); | 789 LUnallocated* first_output = LUnallocated::cast(first->Output()); |
| 790 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); | 790 LiveRange* range = LiveRangeFor(first_output->VirtualRegister()); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 811 // Thus it should be inserted to a lifetime position corresponding to | 811 // Thus it should be inserted to a lifetime position corresponding to |
| 812 // the instruction end. | 812 // the instruction end. |
| 813 LGap* gap = chunk_->GetGapAt(gap_index); | 813 LGap* gap = chunk_->GetGapAt(gap_index); |
| 814 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); | 814 LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); |
| 815 move->AddMove(first_output, range->GetSpillOperand()); | 815 move->AddMove(first_output, range->GetSpillOperand()); |
| 816 } | 816 } |
| 817 } | 817 } |
| 818 | 818 |
| 819 // Handle fixed input operands of second instruction. | 819 // Handle fixed input operands of second instruction. |
| 820 if (second != NULL) { | 820 if (second != NULL) { |
| 821 for (int i = 0; i < second->InputCount(); ++i) { | 821 for (UseIterator it = second->GetUseIterator(); it.HasNext(); ) { |
| 822 LUnallocated* cur_input = LUnallocated::cast(second->InputAt(i)); | 822 LUnallocated* cur_input = LUnallocated::cast(it.Next()); |
| 823 if (cur_input->HasFixedPolicy()) { | 823 if (cur_input->HasFixedPolicy()) { |
| 824 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 824 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
| 825 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); | 825 bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); |
| 826 AllocateFixed(cur_input, gap_index + 1, is_tagged); | 826 AllocateFixed(cur_input, gap_index + 1, is_tagged); |
| 827 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 827 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
| 828 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { | 828 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { |
| 829 // The live range of writable input registers always goes until the end | 829 // The live range of writable input registers always goes until the end |
| 830 // of the instruction. | 830 // of the instruction. |
| 831 ASSERT(!cur_input->IsUsedAtStart()); | 831 ASSERT(!cur_input->IsUsedAtStart()); |
| 832 | 832 |
| 833 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 833 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
| 834 cur_input->set_virtual_register(next_virtual_register_++); | 834 cur_input->set_virtual_register(next_virtual_register_++); |
| 835 | 835 |
| 836 if (RequiredRegisterKind(input_copy->virtual_register()) == | 836 if (RequiredRegisterKind(input_copy->virtual_register()) == |
| 837 DOUBLE_REGISTERS) { | 837 DOUBLE_REGISTERS) { |
| 838 double_artificial_registers_.Add( | 838 double_artificial_registers_.Add( |
| 839 cur_input->virtual_register() - first_artificial_register_); | 839 cur_input->virtual_register() - first_artificial_register_); |
| 840 } | 840 } |
| 841 | 841 |
| 842 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 842 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
| 843 } | 843 } |
| 844 } | 844 } |
| 845 } | 845 } |
| 846 | 846 |
| 847 // Handle "output same as input" for second instruction. | 847 // Handle "output same as input" for second instruction. |
| 848 if (second != NULL && second->Output() != NULL) { | 848 if (second != NULL && second->Output() != NULL) { |
| 849 LUnallocated* second_output = LUnallocated::cast(second->Output()); | 849 LUnallocated* second_output = LUnallocated::cast(second->Output()); |
| 850 if (second_output->HasSameAsInputPolicy()) { | 850 if (second_output->HasSameAsInputPolicy()) { |
| 851 LUnallocated* cur_input = LUnallocated::cast(second->InputAt(0)); | 851 LUnallocated* cur_input = LUnallocated::cast(second->FirstInput()); |
| 852 int output_vreg = second_output->VirtualRegister(); | 852 int output_vreg = second_output->VirtualRegister(); |
| 853 int input_vreg = cur_input->VirtualRegister(); | 853 int input_vreg = cur_input->VirtualRegister(); |
| 854 | 854 |
| 855 LUnallocated* input_copy = cur_input->CopyUnconstrained(); | 855 LUnallocated* input_copy = cur_input->CopyUnconstrained(); |
| 856 cur_input->set_virtual_register(second_output->virtual_register()); | 856 cur_input->set_virtual_register(second_output->virtual_register()); |
| 857 AddConstraintsGapMove(gap_index, input_copy, cur_input); | 857 AddConstraintsGapMove(gap_index, input_copy, cur_input); |
| 858 | 858 |
| 859 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { | 859 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { |
| 860 int index = gap_index + 1; | 860 int index = gap_index + 1; |
| 861 LInstruction* instr = chunk_->instructions()->at(index); | 861 LInstruction* instr = chunk_->instructions()->at(index); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 916 Define(curr_position, to, from); | 916 Define(curr_position, to, from); |
| 917 } | 917 } |
| 918 } | 918 } |
| 919 Use(block_start_position, curr_position, from, hint); | 919 Use(block_start_position, curr_position, from, hint); |
| 920 if (from->IsUnallocated()) { | 920 if (from->IsUnallocated()) { |
| 921 live->Add(from->VirtualRegister()); | 921 live->Add(from->VirtualRegister()); |
| 922 } | 922 } |
| 923 } | 923 } |
| 924 } else { | 924 } else { |
| 925 ASSERT(!chunk_->IsGapAt(index)); | 925 ASSERT(!chunk_->IsGapAt(index)); |
| 926 InstructionSummary* summary = GetSummary(index); | 926 LInstruction* instr = chunk_->instructions()->at(index); |
|
Kevin Millikin (Chromium)
2011/01/20 12:20:30
It might be easier to read and write these sites i
fschneider
2011/01/20 17:13:08
Done. Introduces InstructionAt and GapAt helpers.
| |
| 927 | 927 |
| 928 if (summary != NULL) { | 928 if (instr != NULL) { |
| 929 LOperand* output = summary->Output(); | 929 LOperand* output = instr->Output(); |
| 930 if (output != NULL) { | 930 if (output != NULL) { |
| 931 if (output->IsUnallocated()) live->Remove(output->VirtualRegister()); | 931 if (output->IsUnallocated()) live->Remove(output->VirtualRegister()); |
| 932 Define(curr_position, output, NULL); | 932 Define(curr_position, output, NULL); |
| 933 } | 933 } |
| 934 | 934 |
| 935 if (summary->IsCall()) { | 935 if (instr->IsMarkedAsCall()) { |
| 936 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { | 936 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { |
| 937 if (output == NULL || !output->IsRegister() || | 937 if (output == NULL || !output->IsRegister() || |
| 938 output->index() != i) { | 938 output->index() != i) { |
| 939 LiveRange* range = FixedLiveRangeFor(i); | 939 LiveRange* range = FixedLiveRangeFor(i); |
| 940 range->AddUseInterval(curr_position, | 940 range->AddUseInterval(curr_position, |
| 941 curr_position.InstructionEnd()); | 941 curr_position.InstructionEnd()); |
| 942 } | 942 } |
| 943 } | 943 } |
| 944 } | 944 } |
| 945 | 945 |
| 946 if (summary->IsCall() || summary->IsSaveDoubles()) { | 946 if (instr->IsMarkedAsCall() || instr->IsSaveDoubles()) { |
| 947 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { | 947 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { |
| 948 if (output == NULL || !output->IsDoubleRegister() || | 948 if (output == NULL || !output->IsDoubleRegister() || |
| 949 output->index() != i) { | 949 output->index() != i) { |
| 950 LiveRange* range = FixedDoubleLiveRangeFor(i); | 950 LiveRange* range = FixedDoubleLiveRangeFor(i); |
| 951 range->AddUseInterval(curr_position, | 951 range->AddUseInterval(curr_position, |
| 952 curr_position.InstructionEnd()); | 952 curr_position.InstructionEnd()); |
| 953 } | 953 } |
| 954 } | 954 } |
| 955 } | 955 } |
| 956 | 956 |
| 957 for (int i = 0; i < summary->InputCount(); ++i) { | 957 for (UseIterator it = instr->GetUseIterator(); it.HasNext(); ) { |
| 958 LOperand* input = summary->InputAt(i); | 958 LOperand* input = it.Next(); |
| 959 | 959 |
| 960 LifetimePosition use_pos; | 960 LifetimePosition use_pos; |
| 961 if (input->IsUnallocated() && | 961 if (input->IsUnallocated() && |
| 962 LUnallocated::cast(input)->IsUsedAtStart()) { | 962 LUnallocated::cast(input)->IsUsedAtStart()) { |
| 963 use_pos = curr_position; | 963 use_pos = curr_position; |
| 964 } else { | 964 } else { |
| 965 use_pos = curr_position.InstructionEnd(); | 965 use_pos = curr_position.InstructionEnd(); |
| 966 } | 966 } |
| 967 | 967 |
| 968 Use(block_start_position, use_pos, input, NULL); | 968 Use(block_start_position, use_pos, input, NULL); |
| 969 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); | 969 if (input->IsUnallocated()) live->Add(input->VirtualRegister()); |
| 970 } | 970 } |
| 971 | 971 |
| 972 for (int i = 0; i < summary->TempCount(); ++i) { | 972 for (TempIterator it = instr->GetTempIterator(); it.HasNext(); ) { |
| 973 LOperand* temp = summary->TempAt(i); | 973 LOperand* temp = it.Next(); |
| 974 if (summary->IsCall()) { | 974 if (instr->IsMarkedAsCall()) { |
| 975 if (temp->IsRegister()) continue; | 975 if (temp->IsRegister()) continue; |
| 976 if (temp->IsUnallocated()) { | 976 if (temp->IsUnallocated()) { |
| 977 LUnallocated* temp_unalloc = LUnallocated::cast(temp); | 977 LUnallocated* temp_unalloc = LUnallocated::cast(temp); |
| 978 if (temp_unalloc->HasFixedPolicy()) { | 978 if (temp_unalloc->HasFixedPolicy()) { |
| 979 continue; | 979 continue; |
| 980 } | 980 } |
| 981 } | 981 } |
| 982 } | 982 } |
| 983 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); | 983 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); |
| 984 Define(curr_position, temp, NULL); | 984 Define(curr_position, temp, NULL); |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1551 void LAllocator::TraceAlloc(const char* msg, ...) { | 1551 void LAllocator::TraceAlloc(const char* msg, ...) { |
| 1552 if (FLAG_trace_alloc) { | 1552 if (FLAG_trace_alloc) { |
| 1553 va_list arguments; | 1553 va_list arguments; |
| 1554 va_start(arguments, msg); | 1554 va_start(arguments, msg); |
| 1555 OS::VPrint(msg, arguments); | 1555 OS::VPrint(msg, arguments); |
| 1556 va_end(arguments); | 1556 va_end(arguments); |
| 1557 } | 1557 } |
| 1558 } | 1558 } |
| 1559 | 1559 |
| 1560 | 1560 |
| 1561 void LAllocator::RecordUse(HValue* value, LUnallocated* operand) { | |
| 1562 operand->set_virtual_register(value->id()); | |
| 1563 current_summary()->AddInput(operand); | |
| 1564 } | |
| 1565 | |
| 1566 | |
| 1567 bool LAllocator::HasTaggedValue(int virtual_register) const { | 1561 bool LAllocator::HasTaggedValue(int virtual_register) const { |
| 1568 HValue* value = graph()->LookupValue(virtual_register); | 1562 HValue* value = graph()->LookupValue(virtual_register); |
| 1569 if (value == NULL) return false; | 1563 if (value == NULL) return false; |
| 1570 return value->representation().IsTagged(); | 1564 return value->representation().IsTagged(); |
| 1571 } | 1565 } |
| 1572 | 1566 |
| 1573 | 1567 |
| 1574 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { | 1568 RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { |
| 1575 if (virtual_register < first_artificial_register_) { | 1569 if (virtual_register < first_artificial_register_) { |
| 1576 HValue* value = graph()->LookupValue(virtual_register); | 1570 HValue* value = graph()->LookupValue(virtual_register); |
| 1577 if (value != NULL && value->representation().IsDouble()) { | 1571 if (value != NULL && value->representation().IsDouble()) { |
| 1578 return DOUBLE_REGISTERS; | 1572 return DOUBLE_REGISTERS; |
| 1579 } | 1573 } |
| 1580 } else if (double_artificial_registers_.Contains( | 1574 } else if (double_artificial_registers_.Contains( |
| 1581 virtual_register - first_artificial_register_)) { | 1575 virtual_register - first_artificial_register_)) { |
| 1582 return DOUBLE_REGISTERS; | 1576 return DOUBLE_REGISTERS; |
| 1583 } | 1577 } |
| 1584 | 1578 |
| 1585 return GENERAL_REGISTERS; | 1579 return GENERAL_REGISTERS; |
| 1586 } | 1580 } |
| 1587 | 1581 |
| 1588 | 1582 |
| 1589 void LAllocator::MarkAsCall() { | |
| 1590 // Call instructions can use only fixed registers as | |
| 1591 // temporaries and outputs because all registers | |
| 1592 // are blocked by the calling convention. | |
| 1593 // Inputs can use either fixed register or have a short lifetime (be | |
| 1594 // used at start of the instruction). | |
| 1595 InstructionSummary* summary = current_summary(); | |
| 1596 #ifdef DEBUG | |
| 1597 ASSERT(summary->Output() == NULL || | |
| 1598 LUnallocated::cast(summary->Output())->HasFixedPolicy() || | |
| 1599 !LUnallocated::cast(summary->Output())->HasRegisterPolicy()); | |
| 1600 for (int i = 0; i < summary->InputCount(); i++) { | |
| 1601 ASSERT(LUnallocated::cast(summary->InputAt(i))->HasFixedPolicy() || | |
| 1602 LUnallocated::cast(summary->InputAt(i))->IsUsedAtStart() || | |
| 1603 !LUnallocated::cast(summary->InputAt(i))->HasRegisterPolicy()); | |
| 1604 } | |
| 1605 for (int i = 0; i < summary->TempCount(); i++) { | |
| 1606 ASSERT(LUnallocated::cast(summary->TempAt(i))->HasFixedPolicy() || | |
| 1607 !LUnallocated::cast(summary->TempAt(i))->HasRegisterPolicy()); | |
| 1608 } | |
| 1609 #endif | |
| 1610 summary->MarkAsCall(); | |
| 1611 } | |
| 1612 | |
| 1613 | |
| 1614 void LAllocator::MarkAsSaveDoubles() { | |
| 1615 current_summary()->MarkAsSaveDoubles(); | |
| 1616 } | |
| 1617 | |
| 1618 | |
| 1619 void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) { | 1583 void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) { |
| 1620 operand->set_virtual_register(instr->id()); | 1584 operand->set_virtual_register(instr->id()); |
| 1621 current_summary()->SetOutput(operand); | |
| 1622 } | 1585 } |
| 1623 | 1586 |
| 1624 | 1587 |
| 1625 void LAllocator::RecordTemporary(LUnallocated* operand) { | 1588 void LAllocator::RecordTemporary(LUnallocated* operand) { |
| 1626 ASSERT(next_virtual_register_ < LUnallocated::kMaxVirtualRegisters); | 1589 ASSERT(next_virtual_register_ < LUnallocated::kMaxVirtualRegisters); |
| 1627 if (!operand->HasFixedPolicy()) { | 1590 if (!operand->HasFixedPolicy()) { |
| 1628 operand->set_virtual_register(next_virtual_register_++); | 1591 operand->set_virtual_register(next_virtual_register_++); |
| 1629 } | 1592 } |
| 1630 current_summary()->AddTemp(operand); | 1593 } |
| 1594 | |
| 1595 | |
| 1596 void LAllocator::RecordUse(HValue* value, LUnallocated* operand) { | |
| 1597 operand->set_virtual_register(value->id()); | |
| 1631 } | 1598 } |
| 1632 | 1599 |
| 1633 | 1600 |
| 1634 int LAllocator::max_initial_value_ids() { | 1601 int LAllocator::max_initial_value_ids() { |
| 1635 return LUnallocated::kMaxVirtualRegisters / 32; | 1602 return LUnallocated::kMaxVirtualRegisters / 32; |
| 1636 } | 1603 } |
| 1637 | 1604 |
| 1638 | 1605 |
| 1639 void LAllocator::BeginInstruction() { | |
| 1640 if (next_summary_ == NULL) { | |
| 1641 next_summary_ = new InstructionSummary(); | |
| 1642 } | |
| 1643 summary_stack_.Add(next_summary_); | |
| 1644 next_summary_ = NULL; | |
| 1645 } | |
| 1646 | |
| 1647 | |
| 1648 void LAllocator::SummarizeInstruction(int index) { | |
| 1649 InstructionSummary* sum = summary_stack_.RemoveLast(); | |
| 1650 if (summaries_.length() <= index) { | |
| 1651 summaries_.AddBlock(NULL, index + 1 - summaries_.length()); | |
| 1652 } | |
| 1653 ASSERT(summaries_[index] == NULL); | |
| 1654 if (sum->Output() != NULL || sum->InputCount() > 0 || sum->TempCount() > 0) { | |
| 1655 summaries_[index] = sum; | |
| 1656 } else { | |
| 1657 next_summary_ = sum; | |
| 1658 } | |
| 1659 } | |
| 1660 | |
| 1661 | |
| 1662 void LAllocator::OmitInstruction() { | |
| 1663 summary_stack_.RemoveLast(); | |
| 1664 } | |
| 1665 | |
| 1666 | |
| 1667 void LAllocator::AddToActive(LiveRange* range) { | 1606 void LAllocator::AddToActive(LiveRange* range) { |
| 1668 TraceAlloc("Add live range %d to active\n", range->id()); | 1607 TraceAlloc("Add live range %d to active\n", range->id()); |
| 1669 active_live_ranges_.Add(range); | 1608 active_live_ranges_.Add(range); |
| 1670 } | 1609 } |
| 1671 | 1610 |
| 1672 | 1611 |
| 1673 void LAllocator::AddToInactive(LiveRange* range) { | 1612 void LAllocator::AddToInactive(LiveRange* range) { |
| 1674 TraceAlloc("Add live range %d to inactive\n", range->id()); | 1613 TraceAlloc("Add live range %d to inactive\n", range->id()); |
| 1675 inactive_live_ranges_.Add(range); | 1614 inactive_live_ranges_.Add(range); |
| 1676 } | 1615 } |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2146 LiveRange* current = live_ranges()->at(i); | 2085 LiveRange* current = live_ranges()->at(i); |
| 2147 if (current != NULL) current->Verify(); | 2086 if (current != NULL) current->Verify(); |
| 2148 } | 2087 } |
| 2149 } | 2088 } |
| 2150 | 2089 |
| 2151 | 2090 |
| 2152 #endif | 2091 #endif |
| 2153 | 2092 |
| 2154 | 2093 |
| 2155 } } // namespace v8::internal | 2094 } } // namespace v8::internal |
| OLD | NEW |