OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "double.h" | 7 #include "double.h" |
8 #include "factory.h" | 8 #include "factory.h" |
9 #include "hydrogen-infer-representation.h" | 9 #include "hydrogen-infer-representation.h" |
10 #include "property-details-inl.h" | 10 #include "property-details-inl.h" |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 if (next != NULL) next->previous_ = this; | 717 if (next != NULL) next->previous_ = this; |
718 if (block->last() == previous) { | 718 if (block->last() == previous) { |
719 block->set_last(this); | 719 block->set_last(this); |
720 } | 720 } |
721 if (!has_position() && previous->has_position()) { | 721 if (!has_position() && previous->has_position()) { |
722 set_position(previous->position()); | 722 set_position(previous->position()); |
723 } | 723 } |
724 } | 724 } |
725 | 725 |
726 | 726 |
| 727 bool HInstruction::Dominates(HInstruction* other) { |
| 728 if (block() != other->block()) { |
| 729 return block()->Dominates(other->block()); |
| 730 } |
| 731 // Both instructions are in the same basic block. This instruction |
| 732 // should precede the other one in order to dominate it. |
| 733 for (HInstruction* instr = next(); instr != NULL; instr = instr->next()) { |
| 734 if (instr == other) { |
| 735 return true; |
| 736 } |
| 737 } |
| 738 return false; |
| 739 } |
| 740 |
| 741 |
727 #ifdef DEBUG | 742 #ifdef DEBUG |
728 void HInstruction::Verify() { | 743 void HInstruction::Verify() { |
729 // Verify that input operands are defined before use. | 744 // Verify that input operands are defined before use. |
730 HBasicBlock* cur_block = block(); | 745 HBasicBlock* cur_block = block(); |
731 for (int i = 0; i < OperandCount(); ++i) { | 746 for (int i = 0; i < OperandCount(); ++i) { |
732 HValue* other_operand = OperandAt(i); | 747 HValue* other_operand = OperandAt(i); |
733 if (other_operand == NULL) continue; | 748 if (other_operand == NULL) continue; |
734 HBasicBlock* other_block = other_operand->block(); | 749 HBasicBlock* other_block = other_operand->block(); |
735 if (cur_block == other_block) { | 750 if (cur_block == other_block) { |
736 if (!other_operand->IsPhi()) { | 751 if (!other_operand->IsPhi()) { |
(...skipping 2987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3724 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3739 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3725 } | 3740 } |
3726 return false; | 3741 return false; |
3727 } | 3742 } |
3728 | 3743 |
3729 HAllocate* dominator_allocate = HAllocate::cast(dominator); | 3744 HAllocate* dominator_allocate = HAllocate::cast(dominator); |
3730 HValue* dominator_size = dominator_allocate->size(); | 3745 HValue* dominator_size = dominator_allocate->size(); |
3731 HValue* current_size = size(); | 3746 HValue* current_size = size(); |
3732 | 3747 |
3733 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3748 // TODO(hpayer): Add support for non-constant allocation in dominator. |
3734 if (!current_size->IsInteger32Constant() || | 3749 if (!dominator_size->IsInteger32Constant()) { |
3735 !dominator_size->IsInteger32Constant()) { | |
3736 if (FLAG_trace_allocation_folding) { | 3750 if (FLAG_trace_allocation_folding) { |
3737 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n", | 3751 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3752 "dynamic allocation size in dominator\n", |
3738 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3753 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3739 } | 3754 } |
3740 return false; | 3755 return false; |
3741 } | 3756 } |
3742 | 3757 |
3743 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3758 dominator_allocate = GetFoldableDominator(dominator_allocate); |
3744 if (dominator_allocate == NULL) { | 3759 if (dominator_allocate == NULL) { |
3745 return false; | 3760 return false; |
3746 } | 3761 } |
3747 | 3762 |
| 3763 if (!has_size_upper_bound()) { |
| 3764 if (FLAG_trace_allocation_folding) { |
| 3765 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3766 "can't estimate total allocation size\n", |
| 3767 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3768 } |
| 3769 return false; |
| 3770 } |
| 3771 |
| 3772 if (!current_size->IsInteger32Constant()) { |
| 3773 // If it's not constant then it is a size_in_bytes calculation graph |
| 3774 // like this: (const_header_size + const_element_size * size). |
| 3775 ASSERT(current_size->IsInstruction()); |
| 3776 |
| 3777 HInstruction* current_instr = HInstruction::cast(current_size); |
| 3778 if (!current_instr->Dominates(dominator_allocate)) { |
| 3779 if (FLAG_trace_allocation_folding) { |
| 3780 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
| 3781 "value does not dominate target allocation\n", |
| 3782 id(), Mnemonic(), dominator_allocate->id(), |
| 3783 dominator_allocate->Mnemonic()); |
| 3784 } |
| 3785 return false; |
| 3786 } |
| 3787 } |
| 3788 |
3748 ASSERT((IsNewSpaceAllocation() && | 3789 ASSERT((IsNewSpaceAllocation() && |
3749 dominator_allocate->IsNewSpaceAllocation()) || | 3790 dominator_allocate->IsNewSpaceAllocation()) || |
3750 (IsOldDataSpaceAllocation() && | 3791 (IsOldDataSpaceAllocation() && |
3751 dominator_allocate->IsOldDataSpaceAllocation()) || | 3792 dominator_allocate->IsOldDataSpaceAllocation()) || |
3752 (IsOldPointerSpaceAllocation() && | 3793 (IsOldPointerSpaceAllocation() && |
3753 dominator_allocate->IsOldPointerSpaceAllocation())); | 3794 dominator_allocate->IsOldPointerSpaceAllocation())); |
3754 | 3795 |
3755 // First update the size of the dominator allocate instruction. | 3796 // First update the size of the dominator allocate instruction. |
3756 dominator_size = dominator_allocate->size(); | 3797 dominator_size = dominator_allocate->size(); |
3757 int32_t original_object_size = | 3798 int32_t original_object_size = |
3758 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3799 HConstant::cast(dominator_size)->GetInteger32Constant(); |
3759 int32_t dominator_size_constant = original_object_size; | 3800 int32_t dominator_size_constant = original_object_size; |
3760 int32_t current_size_constant = | |
3761 HConstant::cast(current_size)->GetInteger32Constant(); | |
3762 int32_t new_dominator_size = dominator_size_constant + current_size_constant; | |
3763 | 3801 |
3764 if (MustAllocateDoubleAligned()) { | 3802 if (MustAllocateDoubleAligned()) { |
3765 if (!dominator_allocate->MustAllocateDoubleAligned()) { | |
3766 dominator_allocate->MakeDoubleAligned(); | |
3767 } | |
3768 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | 3803 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
3769 dominator_size_constant += kDoubleSize / 2; | 3804 dominator_size_constant += kDoubleSize / 2; |
3770 new_dominator_size += kDoubleSize / 2; | |
3771 } | 3805 } |
3772 } | 3806 } |
3773 | 3807 |
| 3808 int32_t current_size_max_value = size_upper_bound()->GetInteger32Constant(); |
| 3809 int32_t new_dominator_size = dominator_size_constant + current_size_max_value; |
| 3810 |
3774 // Since we clear the first word after folded memory, we cannot use the | 3811 // Since we clear the first word after folded memory, we cannot use the |
3775 // whole Page::kMaxRegularHeapObjectSize memory. | 3812 // whole Page::kMaxRegularHeapObjectSize memory. |
3776 if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { | 3813 if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { |
3777 if (FLAG_trace_allocation_folding) { | 3814 if (FLAG_trace_allocation_folding) { |
3778 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 3815 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", |
3779 id(), Mnemonic(), dominator_allocate->id(), | 3816 id(), Mnemonic(), dominator_allocate->id(), |
3780 dominator_allocate->Mnemonic(), new_dominator_size); | 3817 dominator_allocate->Mnemonic(), new_dominator_size); |
3781 } | 3818 } |
3782 return false; | 3819 return false; |
3783 } | 3820 } |
3784 | 3821 |
3785 HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore( | 3822 HInstruction* new_dominator_size_value; |
3786 zone, | 3823 |
3787 context(), | 3824 if (current_size->IsInteger32Constant()) { |
3788 new_dominator_size, | 3825 new_dominator_size_value = |
3789 Representation::None(), | 3826 HConstant::CreateAndInsertBefore(zone, |
3790 dominator_allocate); | 3827 context(), |
3791 dominator_allocate->UpdateSize(new_dominator_size_constant); | 3828 new_dominator_size, |
| 3829 Representation::None(), |
| 3830 dominator_allocate); |
| 3831 } else { |
| 3832 HValue* new_dominator_size_constant = |
| 3833 HConstant::CreateAndInsertBefore(zone, |
| 3834 context(), |
| 3835 dominator_size_constant, |
| 3836 Representation::Integer32(), |
| 3837 dominator_allocate); |
| 3838 |
| 3839 // Add old and new size together and insert. |
| 3840 current_size->ChangeRepresentation(Representation::Integer32()); |
| 3841 |
| 3842 new_dominator_size_value = HAdd::New(zone, context(), |
| 3843 new_dominator_size_constant, current_size); |
| 3844 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); |
| 3845 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); |
| 3846 |
| 3847 new_dominator_size_value->InsertBefore(dominator_allocate); |
| 3848 } |
| 3849 |
| 3850 dominator_allocate->UpdateSize(new_dominator_size_value); |
| 3851 |
| 3852 if (MustAllocateDoubleAligned()) { |
| 3853 if (!dominator_allocate->MustAllocateDoubleAligned()) { |
| 3854 dominator_allocate->MakeDoubleAligned(); |
| 3855 } |
| 3856 } |
3792 | 3857 |
3793 bool keep_new_space_iterable = FLAG_log_gc || FLAG_heap_stats; | 3858 bool keep_new_space_iterable = FLAG_log_gc || FLAG_heap_stats; |
3794 #ifdef VERIFY_HEAP | 3859 #ifdef VERIFY_HEAP |
3795 keep_new_space_iterable = keep_new_space_iterable || FLAG_verify_heap; | 3860 keep_new_space_iterable = keep_new_space_iterable || FLAG_verify_heap; |
3796 #endif | 3861 #endif |
3797 | 3862 |
3798 if (keep_new_space_iterable && dominator_allocate->IsNewSpaceAllocation()) { | 3863 if (keep_new_space_iterable && dominator_allocate->IsNewSpaceAllocation()) { |
3799 dominator_allocate->MakePrefillWithFiller(); | 3864 dominator_allocate->MakePrefillWithFiller(); |
3800 } else { | 3865 } else { |
3801 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3866 // TODO(hpayer): This is a short-term hack to make allocation mementos |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4747 break; | 4812 break; |
4748 case kExternalMemory: | 4813 case kExternalMemory: |
4749 stream->Add("[external-memory]"); | 4814 stream->Add("[external-memory]"); |
4750 break; | 4815 break; |
4751 } | 4816 } |
4752 | 4817 |
4753 stream->Add("@%d", offset()); | 4818 stream->Add("@%d", offset()); |
4754 } | 4819 } |
4755 | 4820 |
4756 } } // namespace v8::internal | 4821 } } // namespace v8::internal |
OLD | NEW |