| 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 3711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3722 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3722 // TODO(hpayer): Add support for non-constant allocation in dominator. |
| 3723 if (!dominator_size->IsInteger32Constant()) { | 3723 if (!dominator_size->IsInteger32Constant()) { |
| 3724 if (FLAG_trace_allocation_folding) { | 3724 if (FLAG_trace_allocation_folding) { |
| 3725 PrintF("#%d (%s) cannot fold into #%d (%s), " | 3725 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3726 "dynamic allocation size in dominator\n", | 3726 "dynamic allocation size in dominator\n", |
| 3727 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3727 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3728 } | 3728 } |
| 3729 return false; | 3729 return false; |
| 3730 } | 3730 } |
| 3731 | 3731 |
| 3732 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3732 |
| 3733 if (dominator_allocate == NULL) { | 3733 if (!IsFoldable(dominator_allocate)) { |
| 3734 if (FLAG_trace_allocation_folding) { |
| 3735 PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", id(), |
| 3736 Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3737 } |
| 3734 return false; | 3738 return false; |
| 3735 } | 3739 } |
| 3736 | 3740 |
| 3737 if (!has_size_upper_bound()) { | 3741 if (!has_size_upper_bound()) { |
| 3738 if (FLAG_trace_allocation_folding) { | 3742 if (FLAG_trace_allocation_folding) { |
| 3739 PrintF("#%d (%s) cannot fold into #%d (%s), " | 3743 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3740 "can't estimate total allocation size\n", | 3744 "can't estimate total allocation size\n", |
| 3741 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3745 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3742 } | 3746 } |
| 3743 return false; | 3747 return false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3755 "value does not dominate target allocation\n", | 3759 "value does not dominate target allocation\n", |
| 3756 id(), Mnemonic(), dominator_allocate->id(), | 3760 id(), Mnemonic(), dominator_allocate->id(), |
| 3757 dominator_allocate->Mnemonic()); | 3761 dominator_allocate->Mnemonic()); |
| 3758 } | 3762 } |
| 3759 return false; | 3763 return false; |
| 3760 } | 3764 } |
| 3761 } | 3765 } |
| 3762 | 3766 |
| 3763 DCHECK( | 3767 DCHECK( |
| 3764 (IsNewSpaceAllocation() && dominator_allocate->IsNewSpaceAllocation()) || | 3768 (IsNewSpaceAllocation() && dominator_allocate->IsNewSpaceAllocation()) || |
| 3765 (IsOldDataSpaceAllocation() && | 3769 (IsOldSpaceAllocation() && dominator_allocate->IsOldSpaceAllocation())); |
| 3766 dominator_allocate->IsOldDataSpaceAllocation()) || | |
| 3767 (IsOldPointerSpaceAllocation() && | |
| 3768 dominator_allocate->IsOldPointerSpaceAllocation())); | |
| 3769 | 3770 |
| 3770 // First update the size of the dominator allocate instruction. | 3771 // First update the size of the dominator allocate instruction. |
| 3771 dominator_size = dominator_allocate->size(); | 3772 dominator_size = dominator_allocate->size(); |
| 3772 int32_t original_object_size = | 3773 int32_t original_object_size = |
| 3773 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3774 HConstant::cast(dominator_size)->GetInteger32Constant(); |
| 3774 int32_t dominator_size_constant = original_object_size; | 3775 int32_t dominator_size_constant = original_object_size; |
| 3775 | 3776 |
| 3776 if (MustAllocateDoubleAligned()) { | 3777 if (MustAllocateDoubleAligned()) { |
| 3777 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | 3778 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
| 3778 dominator_size_constant += kDoubleSize / 2; | 3779 dominator_size_constant += kDoubleSize / 2; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3849 DeleteAndReplaceWith(dominated_allocate_instr); | 3850 DeleteAndReplaceWith(dominated_allocate_instr); |
| 3850 if (FLAG_trace_allocation_folding) { | 3851 if (FLAG_trace_allocation_folding) { |
| 3851 PrintF("#%d (%s) folded into #%d (%s)\n", | 3852 PrintF("#%d (%s) folded into #%d (%s)\n", |
| 3852 id(), Mnemonic(), dominator_allocate->id(), | 3853 id(), Mnemonic(), dominator_allocate->id(), |
| 3853 dominator_allocate->Mnemonic()); | 3854 dominator_allocate->Mnemonic()); |
| 3854 } | 3855 } |
| 3855 return true; | 3856 return true; |
| 3856 } | 3857 } |
| 3857 | 3858 |
| 3858 | 3859 |
| 3859 HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) { | |
| 3860 if (!IsFoldable(dominator)) { | |
| 3861 // We cannot hoist old space allocations over new space allocations. | |
| 3862 if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) { | |
| 3863 if (FLAG_trace_allocation_folding) { | |
| 3864 PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n", id(), | |
| 3865 Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
| 3866 } | |
| 3867 return NULL; | |
| 3868 } | |
| 3869 | |
| 3870 HAllocate* dominator_dominator = dominator->dominating_allocate_; | |
| 3871 | |
| 3872 // We can hoist old data space allocations over an old pointer space | |
| 3873 // allocation and vice versa. For that we have to check the dominator | |
| 3874 // of the dominator allocate instruction. | |
| 3875 if (dominator_dominator == NULL) { | |
| 3876 dominating_allocate_ = dominator; | |
| 3877 if (FLAG_trace_allocation_folding) { | |
| 3878 PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", id(), | |
| 3879 Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
| 3880 } | |
| 3881 return NULL; | |
| 3882 } | |
| 3883 | |
| 3884 // We can just fold old space allocations that are in the same basic block, | |
| 3885 // since it is not guaranteed that we fill up the whole allocated old | |
| 3886 // space memory. | |
| 3887 // TODO(hpayer): Remove this limitation and add filler maps for each each | |
| 3888 // allocation as soon as we have store elimination. | |
| 3889 if (block()->block_id() != dominator_dominator->block()->block_id()) { | |
| 3890 if (FLAG_trace_allocation_folding) { | |
| 3891 PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n", | |
| 3892 id(), Mnemonic(), dominator_dominator->id(), | |
| 3893 dominator_dominator->Mnemonic()); | |
| 3894 } | |
| 3895 return NULL; | |
| 3896 } | |
| 3897 | |
| 3898 DCHECK((IsOldDataSpaceAllocation() && | |
| 3899 dominator_dominator->IsOldDataSpaceAllocation()) || | |
| 3900 (IsOldPointerSpaceAllocation() && | |
| 3901 dominator_dominator->IsOldPointerSpaceAllocation())); | |
| 3902 | |
| 3903 int32_t current_size = HConstant::cast(size())->GetInteger32Constant(); | |
| 3904 HStoreNamedField* dominator_free_space_size = | |
| 3905 dominator->filler_free_space_size_; | |
| 3906 if (dominator_free_space_size != NULL) { | |
| 3907 // We already hoisted one old space allocation, i.e., we already installed | |
| 3908 // a filler map. Hence, we just have to update the free space size. | |
| 3909 dominator->UpdateFreeSpaceFiller(current_size); | |
| 3910 } else { | |
| 3911 // This is the first old space allocation that gets hoisted. We have to | |
| 3912 // install a filler map since the follwing allocation may cause a GC. | |
| 3913 dominator->CreateFreeSpaceFiller(current_size); | |
| 3914 } | |
| 3915 | |
| 3916 // We can hoist the old space allocation over the actual dominator. | |
| 3917 return dominator_dominator; | |
| 3918 } | |
| 3919 return dominator; | |
| 3920 } | |
| 3921 | |
| 3922 | |
| 3923 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { | 3860 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { |
| 3924 DCHECK(filler_free_space_size_ != NULL); | 3861 DCHECK(filler_free_space_size_ != NULL); |
| 3925 Zone* zone = block()->zone(); | 3862 Zone* zone = block()->zone(); |
| 3926 // We must explicitly force Smi representation here because on x64 we | 3863 // We must explicitly force Smi representation here because on x64 we |
| 3927 // would otherwise automatically choose int32, but the actual store | 3864 // would otherwise automatically choose int32, but the actual store |
| 3928 // requires a Smi-tagged value. | 3865 // requires a Smi-tagged value. |
| 3929 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( | 3866 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( |
| 3930 block()->isolate(), zone, context(), | 3867 block()->isolate(), zone, context(), |
| 3931 filler_free_space_size_->value()->GetInteger32Constant() + | 3868 filler_free_space_size_->value()->GetInteger32Constant() + |
| 3932 free_space_size, | 3869 free_space_size, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3980 block()->graph()->GetConstant0()); | 3917 block()->graph()->GetConstant0()); |
| 3981 clear_next_map->ClearAllSideEffects(); | 3918 clear_next_map->ClearAllSideEffects(); |
| 3982 clear_next_map->InsertAfter(this); | 3919 clear_next_map->InsertAfter(this); |
| 3983 } | 3920 } |
| 3984 } | 3921 } |
| 3985 | 3922 |
| 3986 | 3923 |
| 3987 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT | 3924 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT |
| 3988 os << NameOf(size()) << " ("; | 3925 os << NameOf(size()) << " ("; |
| 3989 if (IsNewSpaceAllocation()) os << "N"; | 3926 if (IsNewSpaceAllocation()) os << "N"; |
| 3990 if (IsOldPointerSpaceAllocation()) os << "P"; | 3927 if (IsOldSpaceAllocation()) os << "P"; |
| 3991 if (IsOldDataSpaceAllocation()) os << "D"; | |
| 3992 if (MustAllocateDoubleAligned()) os << "A"; | 3928 if (MustAllocateDoubleAligned()) os << "A"; |
| 3993 if (MustPrefillWithFiller()) os << "F"; | 3929 if (MustPrefillWithFiller()) os << "F"; |
| 3994 return os << ")"; | 3930 return os << ")"; |
| 3995 } | 3931 } |
| 3996 | 3932 |
| 3997 | 3933 |
| 3998 bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { | 3934 bool HStoreKeyed::TryIncreaseBaseOffset(uint32_t increase_by_value) { |
| 3999 // The base offset is usually simply the size of the array header, except | 3935 // The base offset is usually simply the size of the array header, except |
| 4000 // with dehoisting adds an addition offset due to a array index key | 3936 // with dehoisting adds an addition offset due to a array index key |
| 4001 // manipulation, in which case it becomes (array header size + | 3937 // manipulation, in which case it becomes (array header size + |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4769 break; | 4705 break; |
| 4770 case HObjectAccess::kExternalMemory: | 4706 case HObjectAccess::kExternalMemory: |
| 4771 os << "[external-memory]"; | 4707 os << "[external-memory]"; |
| 4772 break; | 4708 break; |
| 4773 } | 4709 } |
| 4774 | 4710 |
| 4775 return os << "@" << access.offset(); | 4711 return os << "@" << access.offset(); |
| 4776 } | 4712 } |
| 4777 | 4713 |
| 4778 } } // namespace v8::internal | 4714 } } // namespace v8::internal |
| OLD | NEW |