OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
779 if (block->last() == previous) { | 779 if (block->last() == previous) { |
780 block->set_last(this); | 780 block->set_last(this); |
781 } | 781 } |
782 if (position() == RelocInfo::kNoPosition && | 782 if (position() == RelocInfo::kNoPosition && |
783 previous->position() != RelocInfo::kNoPosition) { | 783 previous->position() != RelocInfo::kNoPosition) { |
784 set_position(previous->position()); | 784 set_position(previous->position()); |
785 } | 785 } |
786 } | 786 } |
787 | 787 |
788 | 788 |
789 bool HInstruction::Dominates(HInstruction* other) { | |
790 if (block() != other->block()) { | |
791 return block()->Dominates(other->block()); | |
792 } | |
793 // Both instructions are in the same basic block. This instruction | |
794 // should precede the other one in order to dominate it. | |
795 for (HInstruction* instr = next(); instr != NULL; instr = instr->next()) { | |
796 if (instr == other) { | |
797 return true; | |
798 } | |
799 } | |
800 return false; | |
801 } | |
802 | |
803 | |
789 #ifdef DEBUG | 804 #ifdef DEBUG |
790 void HInstruction::Verify() { | 805 void HInstruction::Verify() { |
791 // Verify that input operands are defined before use. | 806 // Verify that input operands are defined before use. |
792 HBasicBlock* cur_block = block(); | 807 HBasicBlock* cur_block = block(); |
793 for (int i = 0; i < OperandCount(); ++i) { | 808 for (int i = 0; i < OperandCount(); ++i) { |
794 HValue* other_operand = OperandAt(i); | 809 HValue* other_operand = OperandAt(i); |
795 if (other_operand == NULL) continue; | 810 if (other_operand == NULL) continue; |
796 HBasicBlock* other_block = other_operand->block(); | 811 HBasicBlock* other_block = other_operand->block(); |
797 if (cur_block == other_block) { | 812 if (cur_block == other_block) { |
798 if (!other_operand->IsPhi()) { | 813 if (!other_operand->IsPhi()) { |
(...skipping 2616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3415 | 3430 |
3416 // Try to fold allocations together with their dominating allocations. | 3431 // Try to fold allocations together with their dominating allocations. |
3417 if (!dominator->IsAllocate()) { | 3432 if (!dominator->IsAllocate()) { |
3418 if (FLAG_trace_allocation_folding) { | 3433 if (FLAG_trace_allocation_folding) { |
3419 PrintF("#%d (%s) cannot fold into #%d (%s)\n", | 3434 PrintF("#%d (%s) cannot fold into #%d (%s)\n", |
3420 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3435 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3421 } | 3436 } |
3422 return; | 3437 return; |
3423 } | 3438 } |
3424 | 3439 |
3440 // This allocation has wired allocation with dynamic size | |
3441 // (JSArray + FixedArray). We want them to be allocated together instead | |
3442 // of trying to fold first allocation to some other dominating allocation | |
3443 // 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
| |
3444 if (wired_allocate_ != NULL && | |
3445 !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
| |
3446 return; | |
3447 } | |
3448 | |
3425 HAllocate* dominator_allocate = HAllocate::cast(dominator); | 3449 HAllocate* dominator_allocate = HAllocate::cast(dominator); |
3426 HValue* dominator_size = dominator_allocate->size(); | 3450 HValue* dominator_size = dominator_allocate->size(); |
3427 HValue* current_size = size(); | 3451 HValue* current_size = size(); |
3428 | 3452 |
3429 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3453 // TODO(hpayer): Add support for non-constant allocation in dominator. |
3430 if (!current_size->IsInteger32Constant() || | 3454 if (!dominator_size->IsInteger32Constant()) { |
3431 !dominator_size->IsInteger32Constant()) { | |
3432 if (FLAG_trace_allocation_folding) { | 3455 if (FLAG_trace_allocation_folding) { |
3433 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n", | 3456 PrintF("#%d (%s) cannot fold into #%d (%s), " |
3457 "dynamic allocation size in dominator\n", | |
3434 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3458 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3435 } | 3459 } |
3436 return; | 3460 return; |
3437 } | 3461 } |
3438 | 3462 |
3439 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3463 dominator_allocate = GetFoldableDominator(dominator_allocate); |
3440 if (dominator_allocate == NULL) { | 3464 if (dominator_allocate == NULL) { |
3441 return; | 3465 return; |
3442 } | 3466 } |
3443 | 3467 |
3468 if (!current_size->IsInteger32Constant()) { | |
3469 // Currently we allow folding of constant size allocation with dynamic | |
3470 // size allocation only if they are wired. | |
3471 if (dominator_allocate->wired_allocate_ != this) { | |
3472 if (FLAG_trace_allocation_folding) { | |
3473 PrintF("#%d (%s) cannot fold into #%d (%s), " | |
3474 "can't estimate total allocation size\n", | |
3475 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
3476 } | |
3477 return; | |
3478 } | |
3479 | |
3480 // If it's not constant then it is a size_in_bytes calculation graph | |
3481 // like this: (const_header_size + const_element_size * size). | |
3482 ASSERT(current_size->IsInstruction()); | |
3483 | |
3484 HInstruction* current_instr = HInstruction::cast(current_size); | |
3485 if (!current_instr->Dominates(dominator_allocate)) { | |
3486 if (FLAG_trace_allocation_folding) { | |
3487 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | |
3488 "value does not dominate target allocation\n", | |
3489 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
3490 } | |
3491 return; | |
3492 } | |
3493 } | |
3494 | |
3444 ASSERT((IsNewSpaceAllocation() && | 3495 ASSERT((IsNewSpaceAllocation() && |
3445 dominator_allocate->IsNewSpaceAllocation()) || | 3496 dominator_allocate->IsNewSpaceAllocation()) || |
3446 (IsOldDataSpaceAllocation() && | 3497 (IsOldDataSpaceAllocation() && |
3447 dominator_allocate->IsOldDataSpaceAllocation()) || | 3498 dominator_allocate->IsOldDataSpaceAllocation()) || |
3448 (IsOldPointerSpaceAllocation() && | 3499 (IsOldPointerSpaceAllocation() && |
3449 dominator_allocate->IsOldPointerSpaceAllocation())); | 3500 dominator_allocate->IsOldPointerSpaceAllocation())); |
3450 | 3501 |
3451 // First update the size of the dominator allocate instruction. | 3502 // First update the size of the dominator allocate instruction. |
3452 dominator_size = dominator_allocate->size(); | 3503 dominator_size = dominator_allocate->size(); |
3453 int32_t original_object_size = | 3504 int32_t original_object_size = |
3454 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3505 HConstant::cast(dominator_size)->GetInteger32Constant(); |
3455 int32_t dominator_size_constant = original_object_size; | 3506 int32_t dominator_size_constant = original_object_size; |
3456 int32_t current_size_constant = | 3507 |
3457 HConstant::cast(current_size)->GetInteger32Constant(); | 3508 if (MustAllocateDoubleAligned()) { |
3458 int32_t new_dominator_size = dominator_size_constant + current_size_constant; | 3509 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
3510 dominator_size_constant += kDoubleSize / 2; | |
3511 } | |
3512 } | |
3513 | |
3514 HInstruction* new_dominator_size_value; | |
3515 | |
3516 if (current_size->IsInteger32Constant()) { | |
3517 int32_t current_size_value = size()->GetInteger32Constant(); | |
3518 int32_t new_dominator_size = dominator_size_constant + current_size_value; | |
3519 | |
3520 if (new_dominator_size > | |
3521 isolate()->heap()->MaxRegularSpaceAllocationSize()) { | |
3522 if (FLAG_trace_allocation_folding) { | |
3523 PrintF("#%d (%s) cannot fold into #%d (%s), " | |
3524 "resulting allocation size is too big\n", | |
3525 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | |
3526 } | |
3527 return; | |
3528 } | |
3529 | |
3530 new_dominator_size_value = | |
3531 HConstant::CreateAndInsertBefore(zone, | |
3532 context(), | |
3533 new_dominator_size, | |
3534 Representation::None(), | |
3535 dominator_allocate); | |
3536 } else { | |
3537 ASSERT(dominator_allocate->wired_allocate_ == this); | |
3538 dominator_allocate->wired_allocate_ = NULL; | |
3539 | |
3540 HValue* new_dominator_size_constant = | |
3541 HConstant::CreateAndInsertBefore(zone, | |
3542 context(), | |
3543 dominator_size_constant, | |
3544 Representation::Integer32(), | |
3545 dominator_allocate); | |
3546 | |
3547 // Add old and new size together and insert | |
3548 current_size->ChangeRepresentation(Representation::Integer32()); | |
3549 | |
3550 new_dominator_size_value = HAdd::New(zone, context(), | |
3551 new_dominator_size_constant, current_size); | |
3552 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); | |
3553 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); | |
3554 | |
3555 new_dominator_size_value->InsertBefore(dominator_allocate); | |
3556 } | |
3557 | |
3558 dominator_allocate->UpdateSize(new_dominator_size_value); | |
3459 | 3559 |
3460 if (MustAllocateDoubleAligned()) { | 3560 if (MustAllocateDoubleAligned()) { |
3461 if (!dominator_allocate->MustAllocateDoubleAligned()) { | 3561 if (!dominator_allocate->MustAllocateDoubleAligned()) { |
3462 dominator_allocate->MakeDoubleAligned(); | 3562 dominator_allocate->MakeDoubleAligned(); |
3463 } | 3563 } |
3464 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | |
3465 dominator_size_constant += kDoubleSize / 2; | |
3466 new_dominator_size += kDoubleSize / 2; | |
3467 } | |
3468 } | 3564 } |
3469 | 3565 |
3470 if (new_dominator_size > isolate()->heap()->MaxRegularSpaceAllocationSize()) { | |
3471 if (FLAG_trace_allocation_folding) { | |
3472 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | |
3473 id(), Mnemonic(), dominator_allocate->id(), | |
3474 dominator_allocate->Mnemonic(), new_dominator_size); | |
3475 } | |
3476 return; | |
3477 } | |
3478 | |
3479 HInstruction* new_dominator_size_constant = HConstant::CreateAndInsertBefore( | |
3480 zone, | |
3481 context(), | |
3482 new_dominator_size, | |
3483 Representation::None(), | |
3484 dominator_allocate); | |
3485 dominator_allocate->UpdateSize(new_dominator_size_constant); | |
3486 | |
3487 #ifdef VERIFY_HEAP | 3566 #ifdef VERIFY_HEAP |
3488 if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) { | 3567 if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) { |
3489 dominator_allocate->MakePrefillWithFiller(); | 3568 dominator_allocate->MakePrefillWithFiller(); |
3490 } else { | 3569 } else { |
3491 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3570 // TODO(hpayer): This is a short-term hack to make allocation mementos |
3492 // work again in new space. | 3571 // work again in new space. |
3493 dominator_allocate->ClearNextMapWord(original_object_size); | 3572 dominator_allocate->ClearNextMapWord(original_object_size); |
3494 } | 3573 } |
3495 #else | 3574 #else |
3496 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3575 // TODO(hpayer): This is a short-term hack to make allocation mementos |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4413 break; | 4492 break; |
4414 case kExternalMemory: | 4493 case kExternalMemory: |
4415 stream->Add("[external-memory]"); | 4494 stream->Add("[external-memory]"); |
4416 break; | 4495 break; |
4417 } | 4496 } |
4418 | 4497 |
4419 stream->Add("@%d", offset()); | 4498 stream->Add("@%d", offset()); |
4420 } | 4499 } |
4421 | 4500 |
4422 } } // namespace v8::internal | 4501 } } // namespace v8::internal |
OLD | NEW |