Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index 66c4c6803d3d7685d1f373b9e5a7990a23b93a08..24a778e31a9fde2b9e5836621a42024e87350864 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -3742,25 +3742,13 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
} |
HAllocate* dominator_allocate = HAllocate::cast(dominator); |
- HValue* dominator_size = dominator_allocate->size(); |
- HValue* current_size = size(); |
- |
- // TODO(hpayer): Add support for non-constant allocation in dominator. |
- if (!dominator_size->IsInteger32Constant()) { |
- if (FLAG_trace_allocation_folding) { |
- PrintF("#%d (%s) cannot fold into #%d (%s), " |
- "dynamic allocation size in dominator\n", |
- id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
- } |
- return false; |
- } |
dominator_allocate = GetFoldableDominator(dominator_allocate); |
if (dominator_allocate == NULL) { |
return false; |
} |
- if (!has_size_upper_bound()) { |
+ if (!has_size_upper_bound() || !dominator_allocate->has_size_upper_bound()) { |
if (FLAG_trace_allocation_folding) { |
PrintF("#%d (%s) cannot fold into #%d (%s), " |
"can't estimate total allocation size\n", |
@@ -3769,6 +3757,19 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
return false; |
} |
+ HValue* dominator_size = dominator_allocate->size(); |
+ // TODO(ishell): support folding of dynamic size allocation with |
+ // double aligned allocation. |
+ if (!dominator_size->IsInteger32Constant() && MustAllocateDoubleAligned()) { |
+ if (FLAG_trace_allocation_folding) { |
+ PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
+ "in dominator and double aligned requirement\n", |
+ id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
+ } |
+ return false; |
+ } |
+ |
+ HValue* current_size = size(); |
if (!current_size->IsInteger32Constant()) { |
// If it's not constant then it is a size_in_bytes calculation graph |
// like this: (const_header_size + const_element_size * size). |
@@ -3793,61 +3794,82 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
(IsOldPointerSpaceAllocation() && |
dominator_allocate->IsOldPointerSpaceAllocation())); |
- // First update the size of the dominator allocate instruction. |
- dominator_size = dominator_allocate->size(); |
- int32_t original_object_size = |
- HConstant::cast(dominator_size)->GetInteger32Constant(); |
- int32_t dominator_size_constant = original_object_size; |
+ // First update the size and size upper bound of the dominator allocate |
+ // instruction. |
+ int32_t dominator_size_upper_bound_value = |
+ dominator_allocate->size_upper_bound()->GetInteger32Constant(); |
if (MustAllocateDoubleAligned()) { |
- if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
- dominator_size_constant += kDoubleSize / 2; |
+ if ((dominator_size_upper_bound_value & kDoubleAlignmentMask) != 0) { |
+ dominator_size_upper_bound_value += kDoubleSize / 2; |
} |
} |
- int32_t current_size_max_value = size_upper_bound()->GetInteger32Constant(); |
- int32_t new_dominator_size = dominator_size_constant + current_size_max_value; |
+ int32_t new_dominator_size_upper_bound_value = |
+ dominator_size_upper_bound_value + |
+ size_upper_bound()->GetInteger32Constant(); |
// Since we clear the first word after folded memory, we cannot use the |
// whole Page::kMaxRegularHeapObjectSize memory. |
- if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { |
+ if (new_dominator_size_upper_bound_value > |
+ Page::kMaxRegularHeapObjectSize - kPointerSize) { |
if (FLAG_trace_allocation_folding) { |
PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", |
id(), Mnemonic(), dominator_allocate->id(), |
- dominator_allocate->Mnemonic(), new_dominator_size); |
+ dominator_allocate->Mnemonic(), new_dominator_size_upper_bound_value); |
} |
return false; |
} |
- HInstruction* new_dominator_size_value; |
- |
- if (current_size->IsInteger32Constant()) { |
- new_dominator_size_value = |
+ HValue* aligned_dominator_size; |
+ if (dominator_size->IsInteger32Constant()) { |
+ aligned_dominator_size = |
HConstant::CreateAndInsertBefore(zone, |
context(), |
- new_dominator_size, |
- Representation::None(), |
- dominator_allocate); |
- } else { |
- HValue* new_dominator_size_constant = |
- HConstant::CreateAndInsertBefore(zone, |
- context(), |
- dominator_size_constant, |
+ dominator_size_upper_bound_value, |
Representation::Integer32(), |
dominator_allocate); |
+ } else { |
+ aligned_dominator_size = dominator_size; |
+ } |
+ |
+ HConstant* new_dominator_size_upper_bound = |
+ HConstant::CreateAndInsertBefore(zone, |
+ context(), |
+ new_dominator_size_upper_bound_value, |
+ Representation::None(), |
+ dominator_allocate); |
+ |
+ HInstruction* new_dominator_size; |
+ if (current_size->IsInteger32Constant() && |
+ dominator_size->IsInteger32Constant()) { |
+ new_dominator_size = new_dominator_size_upper_bound; |
+ |
+ } else { |
// Add old and new size together and insert. |
- current_size->ChangeRepresentation(Representation::Integer32()); |
+ if (current_size->IsInteger32Constant()) { |
+ // Create a copy of constant and put it into the right place |
+ current_size = |
+ HConstant::CreateAndInsertBefore(zone, |
+ context(), |
+ current_size->GetInteger32Constant(), |
+ Representation::Integer32(), |
+ dominator_allocate); |
+ } else { |
+ current_size->ChangeRepresentation(Representation::Integer32()); |
+ } |
- new_dominator_size_value = HAdd::New(zone, context(), |
- new_dominator_size_constant, current_size); |
- new_dominator_size_value->ClearFlag(HValue::kCanOverflow); |
- new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); |
+ new_dominator_size = HAdd::New(zone, context(), |
+ aligned_dominator_size, current_size); |
+ new_dominator_size->ClearFlag(HValue::kCanOverflow); |
+ new_dominator_size->ChangeRepresentation(Representation::Integer32()); |
- new_dominator_size_value->InsertBefore(dominator_allocate); |
+ new_dominator_size->InsertBefore(dominator_allocate); |
} |
- dominator_allocate->UpdateSize(new_dominator_size_value); |
+ dominator_allocate->UpdateSize(new_dominator_size, |
+ new_dominator_size_upper_bound); |
if (MustAllocateDoubleAligned()) { |
if (!dominator_allocate->MustAllocateDoubleAligned()) { |
@@ -3865,24 +3887,17 @@ bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
} else { |
// TODO(hpayer): This is a short-term hack to make allocation mementos |
// work again in new space. |
- dominator_allocate->ClearNextMapWord(original_object_size); |
+ dominator_allocate->ClearNextMapWord(dominator_size); |
} |
dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); |
// After that replace the dominated allocate instruction. |
- HInstruction* inner_offset = HConstant::CreateAndInsertBefore( |
- zone, |
- context(), |
- dominator_size_constant, |
- Representation::None(), |
- this); |
- |
HInstruction* dominated_allocate_instr = |
HInnerAllocatedObject::New(zone, |
context(), |
dominator_allocate, |
- inner_offset, |
+ aligned_dominator_size, |
type()); |
dominated_allocate_instr->InsertBefore(this); |
DeleteAndReplaceWith(dominated_allocate_instr); |
@@ -4009,14 +4024,25 @@ void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { |
} |
-void HAllocate::ClearNextMapWord(int offset) { |
+void HAllocate::ClearNextMapWord(HValue* offset) { |
if (MustClearNextMapWord()) { |
Zone* zone = block()->zone(); |
- HObjectAccess access = |
- HObjectAccess::ForObservableJSObjectOffset(offset); |
- HStoreNamedField* clear_next_map = |
- HStoreNamedField::New(zone, context(), this, access, |
- block()->graph()->GetConstant0()); |
+ |
+ HInstruction* clear_next_map; |
+ if (offset->IsInteger32Constant()) { |
+ int offset_value = HConstant::cast(offset)->GetInteger32Constant(); |
+ HObjectAccess access = |
+ HObjectAccess::ForObservableJSObjectOffset(offset_value); |
+ clear_next_map = |
+ HStoreNamedField::New(zone, context(), this, access, |
+ block()->graph()->GetConstant0()); |
+ } else { |
+ clear_next_map = |
+ HStoreKeyed::New(zone, context(), |
+ this, offset, |
+ block()->graph()->GetConstant0(), |
+ FAST_HOLEY_SMI_ELEMENTS); |
+ } |
clear_next_map->ClearAllSideEffects(); |
clear_next_map->InsertAfter(this); |
} |