Chromium Code Reviews| Index: src/hydrogen-instructions.cc |
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
| index e93d3402037c11d59698db991e77e4c9ba3f0c17..ab1fabfc3a6b82ef82208c5f77f57c716606ff26 100644 |
| --- a/src/hydrogen-instructions.cc |
| +++ b/src/hydrogen-instructions.cc |
| @@ -786,6 +786,21 @@ void HInstruction::InsertAfter(HInstruction* previous) { |
| } |
| +bool HInstruction::Dominates(HInstruction* other) { |
| + if (block() != other->block()) { |
| + return block()->Dominates(other->block()); |
| + } |
| + // Both instructions are in the same basic block. This instruction |
| + // should precede the other one in order to dominate it. |
| + for (HInstruction* instr = next(); instr != NULL; instr = instr->next()) { |
| + if (instr == other) { |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| + |
| #ifdef DEBUG |
| void HInstruction::Verify() { |
| // Verify that input operands are defined before use. |
| @@ -3422,15 +3437,24 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
| return; |
| } |
| + // This allocation has wired allocation with dynamic size |
| + // (JSArray + FixedArray). We want them to be allocated together instead |
| + // of trying to fold first allocation to some other dominating allocation |
| + // because otherwise it will prevent write barrier optimization. |
|
Hannes Payer (out of office)
2013/12/04 08:27:22
I just discussed the wired concept with Danno. We
Igor Sheludko
2013/12/30 19:20:48
Ok, I'll revert wiring and implement explicit allo
|
| + if (wired_allocate_ != NULL && |
| + !wired_allocate_->size()->IsInteger32Constant()) { |
|
Hannes Payer (out of office)
2013/11/29 09:14:29
Can we not bail out here and check if the wired al
Igor Sheludko
2013/12/30 19:20:48
As we decided to revert wiring this note is no lon
|
| + return; |
| + } |
| + |
| 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 (!current_size->IsInteger32Constant() || |
| - !dominator_size->IsInteger32Constant()) { |
| + if (!dominator_size->IsInteger32Constant()) { |
| if (FLAG_trace_allocation_folding) { |
| - PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n", |
| + PrintF("#%d (%s) cannot fold into #%d (%s), " |
| + "dynamic allocation size in dominator\n", |
| id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| } |
| return; |
| @@ -3441,6 +3465,33 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
| return; |
| } |
| + if (!current_size->IsInteger32Constant()) { |
| + // Currently we allow folding of constant size allocation with dynamic |
| + // size allocation only if they are wired. |
| + if (dominator_allocate->wired_allocate_ != this) { |
| + if (FLAG_trace_allocation_folding) { |
| + PrintF("#%d (%s) cannot fold into #%d (%s), " |
| + "can't estimate total allocation size\n", |
| + id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| + } |
| + return; |
| + } |
| + |
| + // If it's not constant then it is a size_in_bytes calculation graph |
| + // like this: (const_header_size + const_element_size * size). |
| + ASSERT(current_size->IsInstruction()); |
| + |
| + HInstruction* current_instr = HInstruction::cast(current_size); |
| + if (!current_instr->Dominates(dominator_allocate)) { |
| + if (FLAG_trace_allocation_folding) { |
| + PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
| + "value does not dominate target allocation\n", |
| + id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| + } |
| + return; |
| + } |
| + } |
| + |
| ASSERT((IsNewSpaceAllocation() && |
| dominator_allocate->IsNewSpaceAllocation()) || |
| (IsOldDataSpaceAllocation() && |
| @@ -3453,36 +3504,64 @@ void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
| int32_t original_object_size = |
| HConstant::cast(dominator_size)->GetInteger32Constant(); |
| int32_t dominator_size_constant = original_object_size; |
| - int32_t current_size_constant = |
| - HConstant::cast(current_size)->GetInteger32Constant(); |
| - int32_t new_dominator_size = dominator_size_constant + current_size_constant; |
| if (MustAllocateDoubleAligned()) { |
| - if (!dominator_allocate->MustAllocateDoubleAligned()) { |
| - dominator_allocate->MakeDoubleAligned(); |
| - } |
| if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
| dominator_size_constant += kDoubleSize / 2; |
| - new_dominator_size += kDoubleSize / 2; |
| } |
| } |
| - if (new_dominator_size > isolate()->heap()->MaxRegularSpaceAllocationSize()) { |
| - 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); |
| + HInstruction* new_dominator_size_value; |
| + |
| + if (current_size->IsInteger32Constant()) { |
| + int32_t current_size_value = size()->GetInteger32Constant(); |
| + int32_t new_dominator_size = dominator_size_constant + current_size_value; |
| + |
| + if (new_dominator_size > |
| + isolate()->heap()->MaxRegularSpaceAllocationSize()) { |
| + if (FLAG_trace_allocation_folding) { |
| + PrintF("#%d (%s) cannot fold into #%d (%s), " |
| + "resulting allocation size is too big\n", |
| + id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| + } |
| + return; |
| } |
| - return; |
| + |
| + new_dominator_size_value = |
| + HConstant::CreateAndInsertBefore(zone, |
| + context(), |
| + new_dominator_size, |
| + Representation::None(), |
| + dominator_allocate); |
| + } else { |
| + ASSERT(dominator_allocate->wired_allocate_ == this); |
| + dominator_allocate->wired_allocate_ = NULL; |
| + |
| + HValue* new_dominator_size_constant = |
| + HConstant::CreateAndInsertBefore(zone, |
| + context(), |
| + dominator_size_constant, |
| + Representation::Integer32(), |
| + dominator_allocate); |
| + |
| + // Add old and new size together and insert |
| + 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_value->InsertBefore(dominator_allocate); |
| } |
| - HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore( |
| - zone, |
| - context(), |
| - new_dominator_size, |
| - Representation::None(), |
| - dominator_allocate); |
| - dominator_allocate->UpdateSize(new_dominator_size_constant); |
| + dominator_allocate->UpdateSize(new_dominator_size_value); |
| + |
| + if (MustAllocateDoubleAligned()) { |
| + if (!dominator_allocate->MustAllocateDoubleAligned()) { |
| + dominator_allocate->MakeDoubleAligned(); |
| + } |
| + } |
| #ifdef VERIFY_HEAP |
| if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) { |