Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index a3436ed94d771602947fade2df9eacdca9237e82..245c7c040369af136046ab87e44c2ac748fe1c86 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -3729,12 +3729,8 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
return false; |
} |
- |
- if (!IsFoldable(dominator_allocate)) { |
- if (FLAG_trace_allocation_folding) { |
- PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", id(), |
- Mnemonic(), dominator->id(), dominator->Mnemonic()); |
- } |
+ dominator_allocate = GetFoldableDominator(dominator_allocate); |
+ if (dominator_allocate == NULL) { |
return false; |
} |
@@ -3766,7 +3762,10 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
DCHECK( |
(IsNewSpaceAllocation() && dominator_allocate->IsNewSpaceAllocation()) || |
- (IsOldSpaceAllocation() && dominator_allocate->IsOldSpaceAllocation())); |
+ (IsOldDataSpaceAllocation() && |
+ dominator_allocate->IsOldDataSpaceAllocation()) || |
+ (IsOldPointerSpaceAllocation() && |
+ dominator_allocate->IsOldPointerSpaceAllocation())); |
// First update the size of the dominator allocate instruction. |
dominator_size = dominator_allocate->size(); |
@@ -3857,6 +3856,70 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
} |
+HAllocate* HAllocate::GetFoldableDominator(HAllocate* dominator) { |
+ if (!IsFoldable(dominator)) { |
+ // We cannot hoist old space allocations over new space allocations. |
+ if (IsNewSpaceAllocation() || dominator->IsNewSpaceAllocation()) { |
+ if (FLAG_trace_allocation_folding) { |
+ PrintF("#%d (%s) cannot fold into #%d (%s), new space hoisting\n", id(), |
+ Mnemonic(), dominator->id(), dominator->Mnemonic()); |
+ } |
+ return NULL; |
+ } |
+ |
+ HAllocate* dominator_dominator = dominator->dominating_allocate_; |
+ |
+ // We can hoist old data space allocations over an old pointer space |
+ // allocation and vice versa. For that we have to check the dominator |
+ // of the dominator allocate instruction. |
+ if (dominator_dominator == NULL) { |
+ dominating_allocate_ = dominator; |
+ if (FLAG_trace_allocation_folding) { |
+ PrintF("#%d (%s) cannot fold into #%d (%s), different spaces\n", id(), |
+ Mnemonic(), dominator->id(), dominator->Mnemonic()); |
+ } |
+ return NULL; |
+ } |
+ |
+ // We can just fold old space allocations that are in the same basic block, |
+ // since it is not guaranteed that we fill up the whole allocated old |
+ // space memory. |
+ // TODO(hpayer): Remove this limitation and add filler maps for each each |
+ // allocation as soon as we have store elimination. |
+ if (block()->block_id() != dominator_dominator->block()->block_id()) { |
+ if (FLAG_trace_allocation_folding) { |
+ PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n", |
+ id(), Mnemonic(), dominator_dominator->id(), |
+ dominator_dominator->Mnemonic()); |
+ } |
+ return NULL; |
+ } |
+ |
+ DCHECK((IsOldDataSpaceAllocation() && |
+ dominator_dominator->IsOldDataSpaceAllocation()) || |
+ (IsOldPointerSpaceAllocation() && |
+ dominator_dominator->IsOldPointerSpaceAllocation())); |
+ |
+ int32_t current_size = HConstant::cast(size())->GetInteger32Constant(); |
+ HStoreNamedField* dominator_free_space_size = |
+ dominator->filler_free_space_size_; |
+ if (dominator_free_space_size != NULL) { |
+ // We already hoisted one old space allocation, i.e., we already installed |
+ // a filler map. Hence, we just have to update the free space size. |
+ dominator->UpdateFreeSpaceFiller(current_size); |
+ } else { |
+ // This is the first old space allocation that gets hoisted. We have to |
+ // install a filler map since the follwing allocation may cause a GC. |
+ dominator->CreateFreeSpaceFiller(current_size); |
+ } |
+ |
+ // We can hoist the old space allocation over the actual dominator. |
+ return dominator_dominator; |
+ } |
+ return dominator; |
+} |
+ |
+ |
void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { |
DCHECK(filler_free_space_size_ != NULL); |
Zone* zone = block()->zone(); |
@@ -3924,7 +3987,8 @@ void HAllocate::ClearNextMapWord(int offset) { |
std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT |
os << NameOf(size()) << " ("; |
if (IsNewSpaceAllocation()) os << "N"; |
- if (IsOldSpaceAllocation()) os << "P"; |
+ if (IsOldPointerSpaceAllocation()) os << "P"; |
+ if (IsOldDataSpaceAllocation()) os << "D"; |
if (MustAllocateDoubleAligned()) os << "A"; |
if (MustPrefillWithFiller()) os << "F"; |
return os << ")"; |