| 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 "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/double.h" | 8 #include "src/double.h" |
| 9 #include "src/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/hydrogen-infer-representation.h" | 10 #include "src/hydrogen-infer-representation.h" |
| (...skipping 3739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3750 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3750 // TODO(hpayer): Add support for non-constant allocation in dominator. |
| 3751 if (!dominator_size->IsInteger32Constant()) { | 3751 if (!dominator_size->IsInteger32Constant()) { |
| 3752 if (FLAG_trace_allocation_folding) { | 3752 if (FLAG_trace_allocation_folding) { |
| 3753 PrintF("#%d (%s) cannot fold into #%d (%s), " | 3753 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3754 "dynamic allocation size in dominator\n", | 3754 "dynamic allocation size in dominator\n", |
| 3755 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3755 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3756 } | 3756 } |
| 3757 return false; | 3757 return false; |
| 3758 } | 3758 } |
| 3759 | 3759 |
| 3760 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3760 |
| 3761 if (dominator_allocate == NULL) { | 3761 if (!IsFoldable(dominator_allocate)) { |
| 3762 if (FLAG_trace_allocation_folding) { |
| 3763 PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", id(), |
| 3764 Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3765 } |
| 3762 return false; | 3766 return false; |
| 3763 } | 3767 } |
| 3764 | 3768 |
| 3765 if (!has_size_upper_bound()) { | 3769 if (!has_size_upper_bound()) { |
| 3766 if (FLAG_trace_allocation_folding) { | 3770 if (FLAG_trace_allocation_folding) { |
| 3767 PrintF("#%d (%s) cannot fold into #%d (%s), " | 3771 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3768 "can't estimate total allocation size\n", | 3772 "can't estimate total allocation size\n", |
| 3769 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3773 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3770 } | 3774 } |
| 3771 return false; | 3775 return false; |
| 3772 } | 3776 } |
| 3773 | 3777 |
| 3774 if (!current_size->IsInteger32Constant()) { | 3778 if (!current_size->IsInteger32Constant()) { |
| 3775 // If it's not constant then it is a size_in_bytes calculation graph | 3779 // If it's not constant then it is a size_in_bytes calculation graph |
| 3776 // like this: (const_header_size + const_element_size * size). | 3780 // like this: (const_header_size + const_element_size * size). |
| 3777 DCHECK(current_size->IsInstruction()); | 3781 DCHECK(current_size->IsInstruction()); |
| 3778 | 3782 |
| 3779 HInstruction* current_instr = HInstruction::cast(current_size); | 3783 HInstruction* current_instr = HInstruction::cast(current_size); |
| 3780 if (!current_instr->Dominates(dominator_allocate)) { | 3784 if (!current_instr->Dominates(dominator_allocate)) { |
| 3781 if (FLAG_trace_allocation_folding) { | 3785 if (FLAG_trace_allocation_folding) { |
| 3782 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | 3786 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
| 3783 "value does not dominate target allocation\n", | 3787 "value does not dominate target allocation\n", |
| 3784 id(), Mnemonic(), dominator_allocate->id(), | 3788 id(), Mnemonic(), dominator_allocate->id(), |
| 3785 dominator_allocate->Mnemonic()); | 3789 dominator_allocate->Mnemonic()); |
| 3786 } | 3790 } |
| 3787 return false; | 3791 return false; |
| 3788 } | 3792 } |
| 3789 } | 3793 } |
| 3790 | 3794 |
| 3791 DCHECK((IsNewSpaceAllocation() && | 3795 DCHECK( |
| 3792 dominator_allocate->IsNewSpaceAllocation()) || | 3796 (IsNewSpaceAllocation() && dominator_allocate->IsNewSpaceAllocation()) || |
| 3793 (IsOldDataSpaceAllocation() && | 3797 (IsOldSpaceAllocation() && dominator_allocate->IsOldSpaceAllocation())); |
| 3794 dominator_allocate->IsOldDataSpaceAllocation()) || | |
| 3795 (IsOldPointerSpaceAllocation() && | |
| 3796 dominator_allocate->IsOldPointerSpaceAllocation())); | |
| 3797 | 3798 |
| 3798 // First update the size of the dominator allocate instruction. | 3799 // First update the size of the dominator allocate instruction. |
| 3799 dominator_size = dominator_allocate->size(); | 3800 dominator_size = dominator_allocate->size(); |
| 3800 int32_t original_object_size = | 3801 int32_t original_object_size = |
| 3801 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3802 HConstant::cast(dominator_size)->GetInteger32Constant(); |
| 3802 int32_t dominator_size_constant = original_object_size; | 3803 int32_t dominator_size_constant = original_object_size; |
| 3803 | 3804 |
| 3804 if (MustAllocateDoubleAligned()) { | 3805 if (MustAllocateDoubleAligned()) { |
| 3805 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | 3806 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
| 3806 dominator_size_constant += kDoubleSize / 2; | 3807 dominator_size_constant += kDoubleSize / 2; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3877 DeleteAndReplaceWith(dominated_allocate_instr); | 3878 DeleteAndReplaceWith(dominated_allocate_instr); |
| 3878 if (FLAG_trace_allocation_folding) { | 3879 if (FLAG_trace_allocation_folding) { |
| 3879 PrintF("#%d (%s) folded into #%d (%s)\n", | 3880 PrintF("#%d (%s) folded into #%d (%s)\n", |
| 3880 id(), Mnemonic(), dominator_allocate->id(), | 3881 id(), Mnemonic(), dominator_allocate->id(), |
| 3881 dominator_allocate->Mnemonic()); | 3882 dominator_allocate->Mnemonic()); |
| 3882 } | 3883 } |
| 3883 return true; | 3884 return true; |
| 3884 } | 3885 } |
| 3885 | 3886 |
| 3886 | 3887 |
| 3887 HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) { | |
| 3888 if (!IsFoldable(dominator)) { | |
| 3889 // We cannot hoist old space allocations over new space allocations. | |
| 3890 if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) { | |
| 3891 if (FLAG_trace_allocation_folding) { | |
| 3892 PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n", | |
| 3893 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
| 3894 } | |
| 3895 return NULL; | |
| 3896 } | |
| 3897 | |
| 3898 HAllocate* dominator_dominator = dominator->dominating_allocate_; | |
| 3899 | |
| 3900 // We can hoist old data space allocations over an old pointer space | |
| 3901 // allocation and vice versa. For that we have to check the dominator | |
| 3902 // of the dominator allocate instruction. | |
| 3903 if (dominator_dominator == NULL) { | |
| 3904 dominating_allocate_ = dominator; | |
| 3905 if (FLAG_trace_allocation_folding) { | |
| 3906 PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", | |
| 3907 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
| 3908 } | |
| 3909 return NULL; | |
| 3910 } | |
| 3911 | |
| 3912 // We can just fold old space allocations that are in the same basic block, | |
| 3913 // since it is not guaranteed that we fill up the whole allocated old | |
| 3914 // space memory. | |
| 3915 // TODO(hpayer): Remove this limitation and add filler maps for each each | |
| 3916 // allocation as soon as we have store elimination. | |
| 3917 if (block()->block_id() != dominator_dominator->block()->block_id()) { | |
| 3918 if (FLAG_trace_allocation_folding) { | |
| 3919 PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n", | |
| 3920 id(), Mnemonic(), dominator_dominator->id(), | |
| 3921 dominator_dominator->Mnemonic()); | |
| 3922 } | |
| 3923 return NULL; | |
| 3924 } | |
| 3925 | |
| 3926 DCHECK((IsOldDataSpaceAllocation() && | |
| 3927 dominator_dominator->IsOldDataSpaceAllocation()) || | |
| 3928 (IsOldPointerSpaceAllocation() && | |
| 3929 dominator_dominator->IsOldPointerSpaceAllocation())); | |
| 3930 | |
| 3931 int32_t current_size = HConstant::cast(size())->GetInteger32Constant(); | |
| 3932 HStoreNamedField* dominator_free_space_size = | |
| 3933 dominator->filler_free_space_size_; | |
| 3934 if (dominator_free_space_size != NULL) { | |
| 3935 // We already hoisted one old space allocation, i.e., we already installed | |
| 3936 // a filler map. Hence, we just have to update the free space size. | |
| 3937 dominator->UpdateFreeSpaceFiller(current_size); | |
| 3938 } else { | |
| 3939 // This is the first old space allocation that gets hoisted. We have to | |
| 3940 // install a filler map since the follwing allocation may cause a GC. | |
| 3941 dominator->CreateFreeSpaceFiller(current_size); | |
| 3942 } | |
| 3943 | |
| 3944 // We can hoist the old space allocation over the actual dominator. | |
| 3945 return dominator_dominator; | |
| 3946 } | |
| 3947 return dominator; | |
| 3948 } | |
| 3949 | |
| 3950 | |
| 3951 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { | 3888 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { |
| 3952 DCHECK(filler_free_space_size_ != NULL); | 3889 DCHECK(filler_free_space_size_ != NULL); |
| 3953 Zone* zone = block()->zone(); | 3890 Zone* zone = block()->zone(); |
| 3954 // We must explicitly force Smi representation here because on x64 we | 3891 // We must explicitly force Smi representation here because on x64 we |
| 3955 // would otherwise automatically choose int32, but the actual store | 3892 // would otherwise automatically choose int32, but the actual store |
| 3956 // requires a Smi-tagged value. | 3893 // requires a Smi-tagged value. |
| 3957 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( | 3894 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( |
| 3958 block()->isolate(), zone, context(), | 3895 block()->isolate(), zone, context(), |
| 3959 filler_free_space_size_->value()->GetInteger32Constant() + | 3896 filler_free_space_size_->value()->GetInteger32Constant() + |
| 3960 free_space_size, | 3897 free_space_size, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4008 block()->graph()->GetConstant0()); | 3945 block()->graph()->GetConstant0()); |
| 4009 clear_next_map->ClearAllSideEffects(); | 3946 clear_next_map->ClearAllSideEffects(); |
| 4010 clear_next_map->InsertAfter(this); | 3947 clear_next_map->InsertAfter(this); |
| 4011 } | 3948 } |
| 4012 } | 3949 } |
| 4013 | 3950 |
| 4014 | 3951 |
| 4015 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT | 3952 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT |
| 4016 os << NameOf(size()) << " ("; | 3953 os << NameOf(size()) << " ("; |
| 4017 if (IsNewSpaceAllocation()) os << "N"; | 3954 if (IsNewSpaceAllocation()) os << "N"; |
| 4018 if (IsOldPointerSpaceAllocation()) os << "P"; | 3955 if (IsOldSpaceAllocation()) os << "P"; |
| 4019 if (IsOldDataSpaceAllocation()) os << "D"; | |
| 4020 if (MustAllocateDoubleAligned()) os << "A"; | 3956 if (MustAllocateDoubleAligned()) os << "A"; |
| 4021 if (MustPrefillWithFiller()) os << "F"; | 3957 if (MustPrefillWithFiller()) os << "F"; |
| 4022 return os << ")"; | 3958 return os << ")"; |
| 4023 } | 3959 } |
| 4024 | 3960 |
| 4025 | 3961 |
| 4026 bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { | 3962 bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { |
| 4027 // The base offset is usually simply the size of the array header, except | 3963 // The base offset is usually simply the size of the array header, except |
| 4028 // with dehoisting adds an addition offset due to a array index key | 3964 // with dehoisting adds an addition offset due to a array index key |
| 4029 // manipulation, in which case it becomes (array header size + | 3965 // manipulation, in which case it becomes (array header size + |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4803 break; | 4739 break; |
| 4804 case HObjectAccess::kExternalMemory: | 4740 case HObjectAccess::kExternalMemory: |
| 4805 os << "[external-memory]"; | 4741 os << "[external-memory]"; |
| 4806 break; | 4742 break; |
| 4807 } | 4743 } |
| 4808 | 4744 |
| 4809 return os << "@" << access.offset(); | 4745 return os << "@" << access.offset(); |
| 4810 } | 4746 } |
| 4811 | 4747 |
| 4812 } } // namespace v8::internal | 4748 } } // namespace v8::internal |
| OLD | NEW |