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 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
771 if (block->last() == previous) { | 771 if (block->last() == previous) { |
772 block->set_last(this); | 772 block->set_last(this); |
773 } | 773 } |
774 if (position() == RelocInfo::kNoPosition && | 774 if (position() == RelocInfo::kNoPosition && |
775 previous->position() != RelocInfo::kNoPosition) { | 775 previous->position() != RelocInfo::kNoPosition) { |
776 set_position(previous->position()); | 776 set_position(previous->position()); |
777 } | 777 } |
778 } | 778 } |
779 | 779 |
780 | 780 |
| 781 bool HInstruction::Dominates(HInstruction* other) { |
| 782 if (block() != other->block()) { |
| 783 return block()->Dominates(other->block()); |
| 784 } |
| 785 // Both instructions are in the same basic block. This instruction |
| 786 // should precede the other one in order to dominate it. |
| 787 for (HInstruction* instr = next(); instr != NULL; instr = instr->next()) { |
| 788 if (instr == other) { |
| 789 return true; |
| 790 } |
| 791 } |
| 792 return false; |
| 793 } |
| 794 |
| 795 |
781 #ifdef DEBUG | 796 #ifdef DEBUG |
782 void HInstruction::Verify() { | 797 void HInstruction::Verify() { |
783 // Verify that input operands are defined before use. | 798 // Verify that input operands are defined before use. |
784 HBasicBlock* cur_block = block(); | 799 HBasicBlock* cur_block = block(); |
785 for (int i = 0; i < OperandCount(); ++i) { | 800 for (int i = 0; i < OperandCount(); ++i) { |
786 HValue* other_operand = OperandAt(i); | 801 HValue* other_operand = OperandAt(i); |
787 if (other_operand == NULL) continue; | 802 if (other_operand == NULL) continue; |
788 HBasicBlock* other_block = other_operand->block(); | 803 HBasicBlock* other_block = other_operand->block(); |
789 if (cur_block == other_block) { | 804 if (cur_block == other_block) { |
790 if (!other_operand->IsPhi()) { | 805 if (!other_operand->IsPhi()) { |
(...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3332 } | 3347 } |
3333 | 3348 |
3334 | 3349 |
3335 void HLoadGlobalGeneric::PrintDataTo(StringStream* stream) { | 3350 void HLoadGlobalGeneric::PrintDataTo(StringStream* stream) { |
3336 stream->Add("%o ", *name()); | 3351 stream->Add("%o ", *name()); |
3337 } | 3352 } |
3338 | 3353 |
3339 | 3354 |
3340 void HInnerAllocatedObject::PrintDataTo(StringStream* stream) { | 3355 void HInnerAllocatedObject::PrintDataTo(StringStream* stream) { |
3341 base_object()->PrintNameTo(stream); | 3356 base_object()->PrintNameTo(stream); |
3342 stream->Add(" offset %d", offset()); | 3357 stream->Add(" offset "); |
| 3358 offset()->PrintNameTo(stream); |
3343 } | 3359 } |
3344 | 3360 |
3345 | 3361 |
3346 void HStoreGlobalCell::PrintDataTo(StringStream* stream) { | 3362 void HStoreGlobalCell::PrintDataTo(StringStream* stream) { |
3347 stream->Add("[%p] = ", *cell().handle()); | 3363 stream->Add("[%p] = ", *cell().handle()); |
3348 value()->PrintNameTo(stream); | 3364 value()->PrintNameTo(stream); |
3349 if (!details_.IsDontDelete()) stream->Add(" (deleteable)"); | 3365 if (!details_.IsDontDelete()) stream->Add(" (deleteable)"); |
3350 if (details_.IsReadOnly()) stream->Add(" (read-only)"); | 3366 if (details_.IsReadOnly()) stream->Add(" (read-only)"); |
3351 } | 3367 } |
3352 | 3368 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3420 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3436 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3421 } | 3437 } |
3422 return; | 3438 return; |
3423 } | 3439 } |
3424 | 3440 |
3425 HAllocate* dominator_allocate = HAllocate::cast(dominator); | 3441 HAllocate* dominator_allocate = HAllocate::cast(dominator); |
3426 HValue* dominator_size = dominator_allocate->size(); | 3442 HValue* dominator_size = dominator_allocate->size(); |
3427 HValue* current_size = size(); | 3443 HValue* current_size = size(); |
3428 | 3444 |
3429 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3445 // TODO(hpayer): Add support for non-constant allocation in dominator. |
3430 if (!current_size->IsInteger32Constant() || | 3446 if (!dominator_size->IsInteger32Constant()) { |
3431 !dominator_size->IsInteger32Constant()) { | |
3432 if (FLAG_trace_allocation_folding) { | 3447 if (FLAG_trace_allocation_folding) { |
3433 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic allocation size\n", | 3448 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3449 "dynamic allocation size in dominator\n", |
3434 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3450 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3435 } | 3451 } |
3436 return; | 3452 return; |
3437 } | 3453 } |
3438 | 3454 |
3439 dominator_allocate = GetFoldableDominator(dominator_allocate); | 3455 dominator_allocate = GetFoldableDominator(dominator_allocate); |
3440 if (dominator_allocate == NULL) { | 3456 if (dominator_allocate == NULL) { |
3441 return; | 3457 return; |
3442 } | 3458 } |
3443 | 3459 |
| 3460 if (!has_size_upper_bound()) { |
| 3461 if (FLAG_trace_allocation_folding) { |
| 3462 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3463 "can't estimate total allocation size\n", |
| 3464 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3465 } |
| 3466 return; |
| 3467 } |
| 3468 |
| 3469 if (!current_size->IsInteger32Constant()) { |
| 3470 // If it's not constant then it is a size_in_bytes calculation graph |
| 3471 // like this: (const_header_size + const_element_size * size). |
| 3472 ASSERT(current_size->IsInstruction()); |
| 3473 |
| 3474 HInstruction* current_instr = HInstruction::cast(current_size); |
| 3475 if (!current_instr->Dominates(dominator_allocate)) { |
| 3476 if (FLAG_trace_allocation_folding) { |
| 3477 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
| 3478 "value does not dominate target allocation\n", |
| 3479 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3480 } |
| 3481 return; |
| 3482 } |
| 3483 } |
| 3484 |
3444 ASSERT((IsNewSpaceAllocation() && | 3485 ASSERT((IsNewSpaceAllocation() && |
3445 dominator_allocate->IsNewSpaceAllocation()) || | 3486 dominator_allocate->IsNewSpaceAllocation()) || |
3446 (IsOldDataSpaceAllocation() && | 3487 (IsOldDataSpaceAllocation() && |
3447 dominator_allocate->IsOldDataSpaceAllocation()) || | 3488 dominator_allocate->IsOldDataSpaceAllocation()) || |
3448 (IsOldPointerSpaceAllocation() && | 3489 (IsOldPointerSpaceAllocation() && |
3449 dominator_allocate->IsOldPointerSpaceAllocation())); | 3490 dominator_allocate->IsOldPointerSpaceAllocation())); |
3450 | 3491 |
3451 // First update the size of the dominator allocate instruction. | 3492 // First update the size of the dominator allocate instruction. |
3452 dominator_size = dominator_allocate->size(); | 3493 dominator_size = dominator_allocate->size(); |
3453 int32_t original_object_size = | 3494 int32_t original_object_size = |
3454 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3495 HConstant::cast(dominator_size)->GetInteger32Constant(); |
3455 int32_t dominator_size_constant = original_object_size; | 3496 int32_t dominator_size_constant = original_object_size; |
3456 int32_t current_size_constant = | 3497 |
3457 HConstant::cast(current_size)->GetInteger32Constant(); | 3498 if (MustAllocateDoubleAligned()) { |
3458 int32_t new_dominator_size = dominator_size_constant + current_size_constant; | 3499 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
| 3500 dominator_size_constant += kDoubleSize / 2; |
| 3501 } |
| 3502 } |
| 3503 |
| 3504 int32_t current_size_max_value = size_upper_bound()->GetInteger32Constant(); |
| 3505 int32_t new_dominator_size = dominator_size_constant + current_size_max_value; |
| 3506 |
| 3507 if (new_dominator_size > isolate()->heap()->MaxRegularSpaceAllocationSize()) { |
| 3508 if (FLAG_trace_allocation_folding) { |
| 3509 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3510 "resulting allocation size is too big\n", |
| 3511 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3512 } |
| 3513 return; |
| 3514 } |
| 3515 |
| 3516 HInstruction* new_dominator_size_value; |
| 3517 |
| 3518 if (current_size->IsInteger32Constant()) { |
| 3519 new_dominator_size_value = |
| 3520 HConstant::CreateAndInsertBefore(zone, |
| 3521 context(), |
| 3522 new_dominator_size, |
| 3523 Representation::None(), |
| 3524 dominator_allocate); |
| 3525 } else { |
| 3526 HValue* new_dominator_size_constant = |
| 3527 HConstant::CreateAndInsertBefore(zone, |
| 3528 context(), |
| 3529 dominator_size_constant, |
| 3530 Representation::Integer32(), |
| 3531 dominator_allocate); |
| 3532 |
| 3533 // Add old and new size together and insert |
| 3534 current_size->ChangeRepresentation(Representation::Integer32()); |
| 3535 |
| 3536 new_dominator_size_value = HAdd::New(zone, context(), |
| 3537 new_dominator_size_constant, current_size); |
| 3538 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); |
| 3539 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); |
| 3540 |
| 3541 new_dominator_size_value->InsertBefore(dominator_allocate); |
| 3542 } |
| 3543 |
| 3544 dominator_allocate->UpdateSize(new_dominator_size_value); |
3459 | 3545 |
3460 if (MustAllocateDoubleAligned()) { | 3546 if (MustAllocateDoubleAligned()) { |
3461 if (!dominator_allocate->MustAllocateDoubleAligned()) { | 3547 if (!dominator_allocate->MustAllocateDoubleAligned()) { |
3462 dominator_allocate->MakeDoubleAligned(); | 3548 dominator_allocate->MakeDoubleAligned(); |
3463 } | 3549 } |
3464 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | |
3465 dominator_size_constant += kDoubleSize / 2; | |
3466 new_dominator_size += kDoubleSize / 2; | |
3467 } | |
3468 } | 3550 } |
3469 | 3551 |
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 | 3552 #ifdef VERIFY_HEAP |
3488 if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) { | 3553 if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) { |
3489 dominator_allocate->MakePrefillWithFiller(); | 3554 dominator_allocate->MakePrefillWithFiller(); |
3490 } else { | 3555 } else { |
3491 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3556 // TODO(hpayer): This is a short-term hack to make allocation mementos |
3492 // work again in new space. | 3557 // work again in new space. |
3493 dominator_allocate->ClearNextMapWord(original_object_size); | 3558 dominator_allocate->ClearNextMapWord(original_object_size); |
3494 } | 3559 } |
3495 #else | 3560 #else |
3496 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3561 // TODO(hpayer): This is a short-term hack to make allocation mementos |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4451 break; | 4516 break; |
4452 case kExternalMemory: | 4517 case kExternalMemory: |
4453 stream->Add("[external-memory]"); | 4518 stream->Add("[external-memory]"); |
4454 break; | 4519 break; |
4455 } | 4520 } |
4456 | 4521 |
4457 stream->Add("@%d", offset()); | 4522 stream->Add("@%d", offset()); |
4458 } | 4523 } |
4459 | 4524 |
4460 } } // namespace v8::internal | 4525 } } // namespace v8::internal |
OLD | NEW |