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 3724 matching lines...) Loading... | |
3735 // Check whether we are folding within the same block for local folding. | 3735 // Check whether we are folding within the same block for local folding. |
3736 if (FLAG_use_local_allocation_folding && dominator->block() != block()) { | 3736 if (FLAG_use_local_allocation_folding && dominator->block() != block()) { |
3737 if (FLAG_trace_allocation_folding) { | 3737 if (FLAG_trace_allocation_folding) { |
3738 PrintF("#%d (%s) cannot fold into #%d (%s), crosses basic blocks\n", | 3738 PrintF("#%d (%s) cannot fold into #%d (%s), crosses basic blocks\n", |
3739 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3739 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3740 } | 3740 } |
3741 return false; | 3741 return false; |
3742 } | 3742 } |
3743 | 3743 |
3744 HAllocate* dominator_allocate = HAllocate::cast(dominator); | 3744 HAllocate* dominator_allocate = HAllocate::cast(dominator); |
3745 HValue* dominator_size = dominator_allocate->size(); | |
3746 HValue* current_size = size(); | |
3747 | |
3748 // TODO(hpayer): Add support for non-constant allocation in dominator. | |
3749 if (!dominator_size->IsInteger32Constant()) { | |
3750 if (FLAG_trace_allocation_folding) { | |
3751 PrintF("#%d (%s) cannot fold into #%d (%s), " | |
3752 "dynamic allocation size in dominator\n", | |
3753 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
3754 } | |
3755 return false; | |
3756 } | |
3757 | 3745 |
3758 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3746 dominator_allocate = GetFoldableDominator(dominator_allocate); |
3759 if (dominator_allocate == NULL) { | 3747 if (dominator_allocate == NULL) { |
3760 return false; | 3748 return false; |
3761 } | 3749 } |
3762 | 3750 |
3763 if (!has_size_upper_bound()) { | 3751 if (!has_size_upper_bound() || !dominator_allocate->has_size_upper_bound()) { |
3764 if (FLAG_trace_allocation_folding) { | 3752 if (FLAG_trace_allocation_folding) { |
3765 PrintF("#%d (%s) cannot fold into #%d (%s), " | 3753 PrintF("#%d (%s) cannot fold into #%d (%s), " |
3766 "can't estimate total allocation size\n", | 3754 "can't estimate total allocation size\n", |
3767 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3755 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3768 } | 3756 } |
3769 return false; | 3757 return false; |
3770 } | 3758 } |
3771 | 3759 |
3760 HValue* dominator_size = dominator_allocate->size(); | |
3761 // TODO(ishell): support folding of dynamic size allocation with | |
3762 // double aligned allocation. | |
3763 if (!dominator_size->IsInteger32Constant() && MustAllocateDoubleAligned()) { | |
3764 if (FLAG_trace_allocation_folding) { | |
3765 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | |
3766 "in dominator and double aligned requirement\n", | |
3767 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
3768 } | |
3769 return false; | |
3770 } | |
3771 | |
3772 HValue* current_size = size(); | |
3772 if (!current_size->IsInteger32Constant()) { | 3773 if (!current_size->IsInteger32Constant()) { |
3773 // If it's not constant then it is a size_in_bytes calculation graph | 3774 // 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 // like this: (const_header_size + const_element_size * size). |
3775 ASSERT(current_size->IsInstruction()); | 3776 ASSERT(current_size->IsInstruction()); |
3776 | 3777 |
3777 HInstruction* current_instr = HInstruction::cast(current_size); | 3778 HInstruction* current_instr = HInstruction::cast(current_size); |
3778 if (!current_instr->Dominates(dominator_allocate)) { | 3779 if (!current_instr->Dominates(dominator_allocate)) { |
3779 if (FLAG_trace_allocation_folding) { | 3780 if (FLAG_trace_allocation_folding) { |
3780 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | 3781 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
3781 "value does not dominate target allocation\n", | 3782 "value does not dominate target allocation\n", |
3782 id(), Mnemonic(), dominator_allocate->id(), | 3783 id(), Mnemonic(), dominator_allocate->id(), |
3783 dominator_allocate->Mnemonic()); | 3784 dominator_allocate->Mnemonic()); |
3784 } | 3785 } |
3785 return false; | 3786 return false; |
3786 } | 3787 } |
3787 } | 3788 } |
3788 | 3789 |
3789 ASSERT((IsNewSpaceAllocation() && | 3790 ASSERT((IsNewSpaceAllocation() && |
3790 dominator_allocate->IsNewSpaceAllocation()) || | 3791 dominator_allocate->IsNewSpaceAllocation()) || |
3791 (IsOldDataSpaceAllocation() && | 3792 (IsOldDataSpaceAllocation() && |
3792 dominator_allocate->IsOldDataSpaceAllocation()) || | 3793 dominator_allocate->IsOldDataSpaceAllocation()) || |
3793 (IsOldPointerSpaceAllocation() && | 3794 (IsOldPointerSpaceAllocation() && |
3794 dominator_allocate->IsOldPointerSpaceAllocation())); | 3795 dominator_allocate->IsOldPointerSpaceAllocation())); |
3795 | 3796 |
3796 // First update the size of the dominator allocate instruction. | 3797 // First update the size and size upper bound of the dominator allocate |
3797 dominator_size = dominator_allocate->size(); | 3798 // instruction. |
3798 int32_t original_object_size = | 3799 int32_t dominator_size_upper_bound = |
3799 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3800 dominator_allocate->size_upper_bound()->GetInteger32Constant(); |
3800 int32_t dominator_size_constant = original_object_size; | |
3801 | 3801 |
3802 if (MustAllocateDoubleAligned()) { | 3802 if (MustAllocateDoubleAligned()) { |
3803 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | 3803 if ((dominator_size_upper_bound & kDoubleAlignmentMask) != 0) { |
3804 dominator_size_constant += kDoubleSize / 2; | 3804 dominator_size_upper_bound += kDoubleSize / 2; |
3805 } | 3805 } |
3806 } | 3806 } |
3807 | 3807 |
3808 int32_t current_size_max_value = size_upper_bound()->GetInteger32Constant(); | 3808 int32_t current_size_upper_bound = size_upper_bound()->GetInteger32Constant(); |
3809 int32_t new_dominator_size = dominator_size_constant + current_size_max_value; | 3809 int32_t new_dominator_size_upper_bound = |
3810 dominator_size_upper_bound + current_size_upper_bound; | |
3810 | 3811 |
3811 // Since we clear the first word after folded memory, we cannot use the | 3812 // Since we clear the first word after folded memory, we cannot use the |
3812 // whole Page::kMaxRegularHeapObjectSize memory. | 3813 // whole Page::kMaxRegularHeapObjectSize memory. |
3813 if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { | 3814 if (new_dominator_size_upper_bound > |
3815 Page::kMaxRegularHeapObjectSize - kPointerSize) { | |
3814 if (FLAG_trace_allocation_folding) { | 3816 if (FLAG_trace_allocation_folding) { |
3815 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 3817 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", |
3816 id(), Mnemonic(), dominator_allocate->id(), | 3818 id(), Mnemonic(), dominator_allocate->id(), |
3817 dominator_allocate->Mnemonic(), new_dominator_size); | 3819 dominator_allocate->Mnemonic(), new_dominator_size_upper_bound); |
3818 } | 3820 } |
3819 return false; | 3821 return false; |
3820 } | 3822 } |
3821 | 3823 |
3822 HInstruction* new_dominator_size_value; | 3824 HValue* aligned_dominator_size; |
3823 | 3825 if (dominator_size->IsInteger32Constant()) { |
3824 if (current_size->IsInteger32Constant()) { | 3826 aligned_dominator_size = |
3825 new_dominator_size_value = | |
3826 HConstant::CreateAndInsertBefore(zone, | 3827 HConstant::CreateAndInsertBefore(zone, |
3827 context(), | 3828 context(), |
3828 new_dominator_size, | 3829 dominator_size_upper_bound, |
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(), | 3830 Representation::Integer32(), |
3837 dominator_allocate); | 3831 dominator_allocate); |
3838 | 3832 |
3833 } else { | |
3834 aligned_dominator_size = dominator_size; | |
3835 } | |
3836 | |
3837 HConstant* new_dominator_size_upper_bound_c = | |
Hannes Payer (out of office)
2014/06/04 09:44:29
I don't like the _c, can we have a proper name?
M
Igor Sheludko
2014/06/04 10:07:41
Done.
| |
3838 HConstant::CreateAndInsertBefore(zone, | |
3839 context(), | |
3840 new_dominator_size_upper_bound, | |
3841 Representation::None(), | |
3842 dominator_allocate); | |
3843 | |
3844 HInstruction* new_dominator_size_value; | |
3845 if (current_size->IsInteger32Constant() && | |
3846 dominator_size->IsInteger32Constant()) { | |
3847 new_dominator_size_value = new_dominator_size_upper_bound_c; | |
3848 | |
3849 } else { | |
3839 // Add old and new size together and insert. | 3850 // Add old and new size together and insert. |
3840 current_size->ChangeRepresentation(Representation::Integer32()); | 3851 if (current_size->IsInteger32Constant()) { |
3852 // Create a copy of constant and put it into the right place | |
3853 current_size = | |
3854 HConstant::CreateAndInsertBefore(zone, | |
3855 context(), | |
3856 current_size->GetInteger32Constant(), | |
3857 Representation::Integer32(), | |
3858 dominator_allocate); | |
3859 } else { | |
3860 current_size->ChangeRepresentation(Representation::Integer32()); | |
3861 } | |
3841 | 3862 |
3842 new_dominator_size_value = HAdd::New(zone, context(), | 3863 new_dominator_size_value = HAdd::New(zone, context(), |
3843 new_dominator_size_constant, current_size); | 3864 aligned_dominator_size, current_size); |
3844 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); | 3865 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); |
3845 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); | 3866 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); |
3846 | 3867 |
3847 new_dominator_size_value->InsertBefore(dominator_allocate); | 3868 new_dominator_size_value->InsertBefore(dominator_allocate); |
3848 } | 3869 } |
3849 | 3870 |
3850 dominator_allocate->UpdateSize(new_dominator_size_value); | 3871 dominator_allocate->UpdateSize( |
3872 new_dominator_size_value, new_dominator_size_upper_bound_c); | |
3851 | 3873 |
3852 if (MustAllocateDoubleAligned()) { | 3874 if (MustAllocateDoubleAligned()) { |
3853 if (!dominator_allocate->MustAllocateDoubleAligned()) { | 3875 if (!dominator_allocate->MustAllocateDoubleAligned()) { |
3854 dominator_allocate->MakeDoubleAligned(); | 3876 dominator_allocate->MakeDoubleAligned(); |
3855 } | 3877 } |
3856 } | 3878 } |
3857 | 3879 |
3858 bool keep_new_space_iterable = FLAG_log_gc || FLAG_heap_stats; | 3880 bool keep_new_space_iterable = FLAG_log_gc || FLAG_heap_stats; |
3859 #ifdef VERIFY_HEAP | 3881 #ifdef VERIFY_HEAP |
3860 keep_new_space_iterable = keep_new_space_iterable || FLAG_verify_heap; | 3882 keep_new_space_iterable = keep_new_space_iterable || FLAG_verify_heap; |
3861 #endif | 3883 #endif |
3862 | 3884 |
3863 if (keep_new_space_iterable && dominator_allocate->IsNewSpaceAllocation()) { | 3885 if (keep_new_space_iterable && dominator_allocate->IsNewSpaceAllocation()) { |
3864 dominator_allocate->MakePrefillWithFiller(); | 3886 dominator_allocate->MakePrefillWithFiller(); |
3865 } else { | 3887 } else { |
3866 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3888 // TODO(hpayer): This is a short-term hack to make allocation mementos |
3867 // work again in new space. | 3889 // work again in new space. |
3868 dominator_allocate->ClearNextMapWord(original_object_size); | 3890 dominator_allocate->ClearNextMapWord(dominator_size); |
3869 } | 3891 } |
3870 | 3892 |
3871 dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); | 3893 dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); |
3872 | 3894 |
3873 // After that replace the dominated allocate instruction. | 3895 // After that replace the dominated allocate instruction. |
3874 HInstruction* inner_offset = HConstant::CreateAndInsertBefore( | |
3875 zone, | |
3876 context(), | |
3877 dominator_size_constant, | |
3878 Representation::None(), | |
3879 this); | |
3880 | |
3881 HInstruction* dominated_allocate_instr = | 3896 HInstruction* dominated_allocate_instr = |
3882 HInnerAllocatedObject::New(zone, | 3897 HInnerAllocatedObject::New(zone, |
3883 context(), | 3898 context(), |
3884 dominator_allocate, | 3899 dominator_allocate, |
3885 inner_offset, | 3900 aligned_dominator_size, |
3886 type()); | 3901 type()); |
3887 dominated_allocate_instr->InsertBefore(this); | 3902 dominated_allocate_instr->InsertBefore(this); |
3888 DeleteAndReplaceWith(dominated_allocate_instr); | 3903 DeleteAndReplaceWith(dominated_allocate_instr); |
3889 if (FLAG_trace_allocation_folding) { | 3904 if (FLAG_trace_allocation_folding) { |
3890 PrintF("#%d (%s) folded into #%d (%s)\n", | 3905 PrintF("#%d (%s) folded into #%d (%s)\n", |
3891 id(), Mnemonic(), dominator_allocate->id(), | 3906 id(), Mnemonic(), dominator_allocate->id(), |
3892 dominator_allocate->Mnemonic()); | 3907 dominator_allocate->Mnemonic()); |
3893 } | 3908 } |
3894 return true; | 3909 return true; |
3895 } | 3910 } |
(...skipping 106 matching lines...) Loading... | |
4002 FreeSpace::kSizeOffset, | 4017 FreeSpace::kSizeOffset, |
4003 Representation::Smi()); | 4018 Representation::Smi()); |
4004 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), | 4019 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), |
4005 free_space_instr, access, filler_size); | 4020 free_space_instr, access, filler_size); |
4006 store_size->SetFlag(HValue::kHasNoObservableSideEffects); | 4021 store_size->SetFlag(HValue::kHasNoObservableSideEffects); |
4007 store_size->InsertAfter(filler_size); | 4022 store_size->InsertAfter(filler_size); |
4008 filler_free_space_size_ = store_size; | 4023 filler_free_space_size_ = store_size; |
4009 } | 4024 } |
4010 | 4025 |
4011 | 4026 |
4012 void HAllocate::ClearNextMapWord(int offset) { | 4027 void HAllocate::ClearNextMapWord(HValue* offset) { |
4013 if (MustClearNextMapWord()) { | 4028 if (MustClearNextMapWord()) { |
4014 Zone* zone = block()->zone(); | 4029 Zone* zone = block()->zone(); |
4015 HObjectAccess access = | 4030 |
4016 HObjectAccess::ForObservableJSObjectOffset(offset); | 4031 if (offset->IsInteger32Constant()) { |
4017 HStoreNamedField* clear_next_map = | 4032 int offset_value = HConstant::cast(offset)->GetInteger32Constant(); |
4018 HStoreNamedField::New(zone, context(), this, access, | 4033 HObjectAccess access = |
4019 block()->graph()->GetConstant0()); | 4034 HObjectAccess::ForObservableJSObjectOffset(offset_value); |
4020 clear_next_map->ClearAllSideEffects(); | 4035 HStoreNamedField* clear_next_map = |
4021 clear_next_map->InsertAfter(this); | 4036 HStoreNamedField::New(zone, context(), this, access, |
4037 block()->graph()->GetConstant0()); | |
4038 clear_next_map->ClearAllSideEffects(); | |
4039 clear_next_map->InsertAfter(this); | |
4040 } else { | |
4041 HStoreKeyed* clear_next_map = | |
4042 HStoreKeyed::New(zone, context(), | |
4043 this, offset, | |
4044 block()->graph()->GetConstant0(), | |
4045 FAST_HOLEY_SMI_ELEMENTS); | |
4046 clear_next_map->ClearAllSideEffects(); | |
4047 clear_next_map->InsertAfter(this); | |
Hannes Payer (out of office)
2014/06/04 09:44:29
Can you move
clear_next_map->ClearAllSideEffects()
Igor Sheludko
2014/06/04 10:07:41
Done.
| |
4048 } | |
4022 } | 4049 } |
4023 } | 4050 } |
4024 | 4051 |
4025 | 4052 |
4026 void HAllocate::PrintDataTo(StringStream* stream) { | 4053 void HAllocate::PrintDataTo(StringStream* stream) { |
4027 size()->PrintNameTo(stream); | 4054 size()->PrintNameTo(stream); |
4028 stream->Add(" ("); | 4055 stream->Add(" ("); |
4029 if (IsNewSpaceAllocation()) stream->Add("N"); | 4056 if (IsNewSpaceAllocation()) stream->Add("N"); |
4030 if (IsOldPointerSpaceAllocation()) stream->Add("P"); | 4057 if (IsOldPointerSpaceAllocation()) stream->Add("P"); |
4031 if (IsOldDataSpaceAllocation()) stream->Add("D"); | 4058 if (IsOldDataSpaceAllocation()) stream->Add("D"); |
(...skipping 780 matching lines...) Loading... | |
4812 break; | 4839 break; |
4813 case kExternalMemory: | 4840 case kExternalMemory: |
4814 stream->Add("[external-memory]"); | 4841 stream->Add("[external-memory]"); |
4815 break; | 4842 break; |
4816 } | 4843 } |
4817 | 4844 |
4818 stream->Add("@%d", offset()); | 4845 stream->Add("@%d", offset()); |
4819 } | 4846 } |
4820 | 4847 |
4821 } } // namespace v8::internal | 4848 } } // namespace v8::internal |
OLD | NEW |