Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index 66c4c6803d3d7685d1f373b9e5a7990a23b93a08..af3297635cbb9b2b394b760723139e10021dbf2d 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 = |
| + dominator_allocate->size_upper_bound()->GetInteger32Constant(); |
| if (MustAllocateDoubleAligned()) { |
| - if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
| - dominator_size_constant += kDoubleSize / 2; |
| + if ((dominator_size_upper_bound & kDoubleAlignmentMask) != 0) { |
| + dominator_size_upper_bound += 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 current_size_upper_bound = size_upper_bound()->GetInteger32Constant(); |
| + int32_t new_dominator_size_upper_bound = |
| + dominator_size_upper_bound + current_size_upper_bound; |
| // 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 > |
| + 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); |
| } |
| 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, |
| Representation::Integer32(), |
| dominator_allocate); |
| + } else { |
| + aligned_dominator_size = dominator_size; |
| + } |
| + |
| + 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.
|
| + HConstant::CreateAndInsertBefore(zone, |
| + context(), |
| + new_dominator_size_upper_bound, |
| + Representation::None(), |
| + dominator_allocate); |
| + |
| + HInstruction* new_dominator_size_value; |
| + if (current_size->IsInteger32Constant() && |
| + dominator_size->IsInteger32Constant()) { |
| + new_dominator_size_value = new_dominator_size_upper_bound_c; |
| + |
| + } 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); |
| + aligned_dominator_size, current_size); |
| new_dominator_size_value->ClearFlag(HValue::kCanOverflow); |
| new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); |
| new_dominator_size_value->InsertBefore(dominator_allocate); |
| } |
| - dominator_allocate->UpdateSize(new_dominator_size_value); |
| + dominator_allocate->UpdateSize( |
| + new_dominator_size_value, new_dominator_size_upper_bound_c); |
| 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,16 +4024,28 @@ 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()); |
| - clear_next_map->ClearAllSideEffects(); |
| - clear_next_map->InsertAfter(this); |
| + |
| + if (offset->IsInteger32Constant()) { |
| + int offset_value = HConstant::cast(offset)->GetInteger32Constant(); |
| + HObjectAccess access = |
| + HObjectAccess::ForObservableJSObjectOffset(offset_value); |
| + HStoreNamedField* clear_next_map = |
| + HStoreNamedField::New(zone, context(), this, access, |
| + block()->graph()->GetConstant0()); |
| + clear_next_map->ClearAllSideEffects(); |
| + clear_next_map->InsertAfter(this); |
| + } else { |
| + HStoreKeyed* 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); |
|
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.
|
| + } |
| } |
| } |