| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/v8.h" | 5 #include "src/v8.h" | 
| 6 | 6 | 
| 7 #include "src/double.h" | 7 #include "src/double.h" | 
| 8 #include "src/factory.h" | 8 #include "src/factory.h" | 
| 9 #include "src/hydrogen-infer-representation.h" | 9 #include "src/hydrogen-infer-representation.h" | 
| 10 #include "src/property-details-inl.h" | 10 #include "src/property-details-inl.h" | 
| (...skipping 3739 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3750   // Check whether we are folding within the same block for local folding. | 3750   // Check whether we are folding within the same block for local folding. | 
| 3751   if (FLAG_use_local_allocation_folding && dominator->block() != block()) { | 3751   if (FLAG_use_local_allocation_folding && dominator->block() != block()) { | 
| 3752     if (FLAG_trace_allocation_folding) { | 3752     if (FLAG_trace_allocation_folding) { | 
| 3753       PrintF("#%d (%s) cannot fold into #%d (%s), crosses basic blocks\n", | 3753       PrintF("#%d (%s) cannot fold into #%d (%s), crosses basic blocks\n", | 
| 3754           id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3754           id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 
| 3755     } | 3755     } | 
| 3756     return false; | 3756     return false; | 
| 3757   } | 3757   } | 
| 3758 | 3758 | 
| 3759   HAllocate* dominator_allocate = HAllocate::cast(dominator); | 3759   HAllocate* dominator_allocate = HAllocate::cast(dominator); | 
|  | 3760   HValue* dominator_size = dominator_allocate->size(); | 
|  | 3761   HValue* current_size = size(); | 
|  | 3762 | 
|  | 3763   // TODO(hpayer): Add support for non-constant allocation in dominator. | 
|  | 3764   if (!dominator_size->IsInteger32Constant()) { | 
|  | 3765     if (FLAG_trace_allocation_folding) { | 
|  | 3766       PrintF("#%d (%s) cannot fold into #%d (%s), " | 
|  | 3767              "dynamic allocation size in dominator\n", | 
|  | 3768           id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 
|  | 3769     } | 
|  | 3770     return false; | 
|  | 3771   } | 
| 3760 | 3772 | 
| 3761   dominator_allocate = GetFoldableDominator(dominator_allocate); | 3773   dominator_allocate = GetFoldableDominator(dominator_allocate); | 
| 3762   if (dominator_allocate == NULL) { | 3774   if (dominator_allocate == NULL) { | 
| 3763     return false; | 3775     return false; | 
| 3764   } | 3776   } | 
| 3765 | 3777 | 
| 3766   if (!has_size_upper_bound() || !dominator_allocate->has_size_upper_bound()) { | 3778   if (!has_size_upper_bound()) { | 
| 3767     if (FLAG_trace_allocation_folding) { | 3779     if (FLAG_trace_allocation_folding) { | 
| 3768       PrintF("#%d (%s) cannot fold into #%d (%s), " | 3780       PrintF("#%d (%s) cannot fold into #%d (%s), " | 
| 3769              "can't estimate total allocation size\n", | 3781              "can't estimate total allocation size\n", | 
| 3770           id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3782           id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 
| 3771     } | 3783     } | 
| 3772     return false; | 3784     return false; | 
| 3773   } | 3785   } | 
| 3774 | 3786 | 
| 3775   HValue* dominator_size = dominator_allocate->size(); |  | 
| 3776   // TODO(ishell): support folding of dynamic size allocation with |  | 
| 3777   // double aligned allocation. |  | 
| 3778   if (!dominator_size->IsInteger32Constant() && MustAllocateDoubleAligned()) { |  | 
| 3779     if (FLAG_trace_allocation_folding) { |  | 
| 3780       PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |  | 
| 3781              "in dominator and double aligned requirement\n", |  | 
| 3782           id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |  | 
| 3783     } |  | 
| 3784     return false; |  | 
| 3785   } |  | 
| 3786 |  | 
| 3787   HValue* current_size = size(); |  | 
| 3788   if (!current_size->IsInteger32Constant()) { | 3787   if (!current_size->IsInteger32Constant()) { | 
| 3789     // If it's not constant then it is a size_in_bytes calculation graph | 3788     // If it's not constant then it is a size_in_bytes calculation graph | 
| 3790     // like this: (const_header_size + const_element_size * size). | 3789     // like this: (const_header_size + const_element_size * size). | 
| 3791     ASSERT(current_size->IsInstruction()); | 3790     ASSERT(current_size->IsInstruction()); | 
| 3792 | 3791 | 
| 3793     HInstruction* current_instr = HInstruction::cast(current_size); | 3792     HInstruction* current_instr = HInstruction::cast(current_size); | 
| 3794     if (!current_instr->Dominates(dominator_allocate)) { | 3793     if (!current_instr->Dominates(dominator_allocate)) { | 
| 3795       if (FLAG_trace_allocation_folding) { | 3794       if (FLAG_trace_allocation_folding) { | 
| 3796         PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | 3795         PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | 
| 3797                "value does not dominate target allocation\n", | 3796                "value does not dominate target allocation\n", | 
| 3798             id(), Mnemonic(), dominator_allocate->id(), | 3797             id(), Mnemonic(), dominator_allocate->id(), | 
| 3799             dominator_allocate->Mnemonic()); | 3798             dominator_allocate->Mnemonic()); | 
| 3800       } | 3799       } | 
| 3801       return false; | 3800       return false; | 
| 3802     } | 3801     } | 
| 3803   } | 3802   } | 
| 3804 | 3803 | 
| 3805   ASSERT((IsNewSpaceAllocation() && | 3804   ASSERT((IsNewSpaceAllocation() && | 
| 3806          dominator_allocate->IsNewSpaceAllocation()) || | 3805          dominator_allocate->IsNewSpaceAllocation()) || | 
| 3807          (IsOldDataSpaceAllocation() && | 3806          (IsOldDataSpaceAllocation() && | 
| 3808          dominator_allocate->IsOldDataSpaceAllocation()) || | 3807          dominator_allocate->IsOldDataSpaceAllocation()) || | 
| 3809          (IsOldPointerSpaceAllocation() && | 3808          (IsOldPointerSpaceAllocation() && | 
| 3810          dominator_allocate->IsOldPointerSpaceAllocation())); | 3809          dominator_allocate->IsOldPointerSpaceAllocation())); | 
| 3811 | 3810 | 
| 3812   // First update the size and size upper bound of the dominator allocate | 3811   // First update the size of the dominator allocate instruction. | 
| 3813   // instruction. | 3812   dominator_size = dominator_allocate->size(); | 
| 3814   int32_t dominator_size_upper_bound_value = | 3813   int32_t original_object_size = | 
| 3815       dominator_allocate->size_upper_bound()->GetInteger32Constant(); | 3814       HConstant::cast(dominator_size)->GetInteger32Constant(); | 
|  | 3815   int32_t dominator_size_constant = original_object_size; | 
| 3816 | 3816 | 
| 3817   if (MustAllocateDoubleAligned()) { | 3817   if (MustAllocateDoubleAligned()) { | 
| 3818     if ((dominator_size_upper_bound_value & kDoubleAlignmentMask) != 0) { | 3818     if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | 
| 3819       dominator_size_upper_bound_value += kDoubleSize / 2; | 3819       dominator_size_constant += kDoubleSize / 2; | 
| 3820     } | 3820     } | 
| 3821   } | 3821   } | 
| 3822 | 3822 | 
| 3823   int32_t new_dominator_size_upper_bound_value = | 3823   int32_t current_size_max_value = size_upper_bound()->GetInteger32Constant(); | 
| 3824       dominator_size_upper_bound_value + | 3824   int32_t new_dominator_size = dominator_size_constant + current_size_max_value; | 
| 3825       size_upper_bound()->GetInteger32Constant(); |  | 
| 3826 | 3825 | 
| 3827   // Since we clear the first word after folded memory, we cannot use the | 3826   // Since we clear the first word after folded memory, we cannot use the | 
| 3828   // whole Page::kMaxRegularHeapObjectSize memory. | 3827   // whole Page::kMaxRegularHeapObjectSize memory. | 
| 3829   if (new_dominator_size_upper_bound_value > | 3828   if (new_dominator_size > Page::kMaxRegularHeapObjectSize - kPointerSize) { | 
| 3830       Page::kMaxRegularHeapObjectSize - kPointerSize) { |  | 
| 3831     if (FLAG_trace_allocation_folding) { | 3829     if (FLAG_trace_allocation_folding) { | 
| 3832       PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 3830       PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 
| 3833           id(), Mnemonic(), dominator_allocate->id(), | 3831           id(), Mnemonic(), dominator_allocate->id(), | 
| 3834           dominator_allocate->Mnemonic(), new_dominator_size_upper_bound_value); | 3832           dominator_allocate->Mnemonic(), new_dominator_size); | 
| 3835     } | 3833     } | 
| 3836     return false; | 3834     return false; | 
| 3837   } | 3835   } | 
| 3838 | 3836 | 
| 3839   HValue* aligned_dominator_size; | 3837   HInstruction* new_dominator_size_value; | 
| 3840   if (dominator_size->IsInteger32Constant()) { | 3838 | 
| 3841     aligned_dominator_size = | 3839   if (current_size->IsInteger32Constant()) { | 
|  | 3840     new_dominator_size_value = | 
| 3842         HConstant::CreateAndInsertBefore(zone, | 3841         HConstant::CreateAndInsertBefore(zone, | 
| 3843                                          context(), | 3842                                          context(), | 
| 3844                                          dominator_size_upper_bound_value, | 3843                                          new_dominator_size, | 
|  | 3844                                          Representation::None(), | 
|  | 3845                                          dominator_allocate); | 
|  | 3846   } else { | 
|  | 3847     HValue* new_dominator_size_constant = | 
|  | 3848         HConstant::CreateAndInsertBefore(zone, | 
|  | 3849                                          context(), | 
|  | 3850                                          dominator_size_constant, | 
| 3845                                          Representation::Integer32(), | 3851                                          Representation::Integer32(), | 
| 3846                                          dominator_allocate); | 3852                                          dominator_allocate); | 
| 3847 | 3853 | 
| 3848   } else { | 3854     // Add old and new size together and insert. | 
| 3849     aligned_dominator_size = dominator_size; | 3855     current_size->ChangeRepresentation(Representation::Integer32()); | 
|  | 3856 | 
|  | 3857     new_dominator_size_value = HAdd::New(zone, context(), | 
|  | 3858         new_dominator_size_constant, current_size); | 
|  | 3859     new_dominator_size_value->ClearFlag(HValue::kCanOverflow); | 
|  | 3860     new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); | 
|  | 3861 | 
|  | 3862     new_dominator_size_value->InsertBefore(dominator_allocate); | 
| 3850   } | 3863   } | 
| 3851 | 3864 | 
| 3852   HConstant* new_dominator_size_upper_bound = | 3865   dominator_allocate->UpdateSize(new_dominator_size_value); | 
| 3853       HConstant::CreateAndInsertBefore(zone, |  | 
| 3854                                        context(), |  | 
| 3855                                        new_dominator_size_upper_bound_value, |  | 
| 3856                                        Representation::None(), |  | 
| 3857                                        dominator_allocate); |  | 
| 3858 |  | 
| 3859   HInstruction* new_dominator_size; |  | 
| 3860   if (current_size->IsInteger32Constant() && |  | 
| 3861       dominator_size->IsInteger32Constant()) { |  | 
| 3862     new_dominator_size = new_dominator_size_upper_bound; |  | 
| 3863 |  | 
| 3864   } else { |  | 
| 3865     // Add old and new size together and insert. |  | 
| 3866     if (current_size->IsInteger32Constant()) { |  | 
| 3867       // Create a copy of constant and put it into the right place |  | 
| 3868       current_size = |  | 
| 3869           HConstant::CreateAndInsertBefore(zone, |  | 
| 3870                                            context(), |  | 
| 3871                                            current_size->GetInteger32Constant(), |  | 
| 3872                                            Representation::Integer32(), |  | 
| 3873                                            dominator_allocate); |  | 
| 3874     } else { |  | 
| 3875       current_size->ChangeRepresentation(Representation::Integer32()); |  | 
| 3876     } |  | 
| 3877 |  | 
| 3878     new_dominator_size = HAdd::New(zone, context(), |  | 
| 3879                                    aligned_dominator_size, current_size); |  | 
| 3880     new_dominator_size->ClearFlag(HValue::kCanOverflow); |  | 
| 3881     new_dominator_size->ChangeRepresentation(Representation::Integer32()); |  | 
| 3882 |  | 
| 3883     new_dominator_size->InsertBefore(dominator_allocate); |  | 
| 3884   } |  | 
| 3885 |  | 
| 3886   dominator_allocate->UpdateSize(new_dominator_size, |  | 
| 3887                                  new_dominator_size_upper_bound); |  | 
| 3888 | 3866 | 
| 3889   if (MustAllocateDoubleAligned()) { | 3867   if (MustAllocateDoubleAligned()) { | 
| 3890     if (!dominator_allocate->MustAllocateDoubleAligned()) { | 3868     if (!dominator_allocate->MustAllocateDoubleAligned()) { | 
| 3891       dominator_allocate->MakeDoubleAligned(); | 3869       dominator_allocate->MakeDoubleAligned(); | 
| 3892     } | 3870     } | 
| 3893   } | 3871   } | 
| 3894 | 3872 | 
| 3895   bool keep_new_space_iterable = FLAG_log_gc || FLAG_heap_stats; | 3873   bool keep_new_space_iterable = FLAG_log_gc || FLAG_heap_stats; | 
| 3896 #ifdef VERIFY_HEAP | 3874 #ifdef VERIFY_HEAP | 
| 3897   keep_new_space_iterable = keep_new_space_iterable || FLAG_verify_heap; | 3875   keep_new_space_iterable = keep_new_space_iterable || FLAG_verify_heap; | 
| 3898 #endif | 3876 #endif | 
| 3899 | 3877 | 
| 3900   if (keep_new_space_iterable && dominator_allocate->IsNewSpaceAllocation()) { | 3878   if (keep_new_space_iterable && dominator_allocate->IsNewSpaceAllocation()) { | 
| 3901     dominator_allocate->MakePrefillWithFiller(); | 3879     dominator_allocate->MakePrefillWithFiller(); | 
| 3902   } else { | 3880   } else { | 
| 3903     // TODO(hpayer): This is a short-term hack to make allocation mementos | 3881     // TODO(hpayer): This is a short-term hack to make allocation mementos | 
| 3904     // work again in new space. | 3882     // work again in new space. | 
| 3905     dominator_allocate->ClearNextMapWord(dominator_size); | 3883     dominator_allocate->ClearNextMapWord(original_object_size); | 
| 3906   } | 3884   } | 
| 3907 | 3885 | 
| 3908   dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); | 3886   dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); | 
| 3909 | 3887 | 
| 3910   // After that replace the dominated allocate instruction. | 3888   // After that replace the dominated allocate instruction. | 
|  | 3889   HInstruction* inner_offset = HConstant::CreateAndInsertBefore( | 
|  | 3890       zone, | 
|  | 3891       context(), | 
|  | 3892       dominator_size_constant, | 
|  | 3893       Representation::None(), | 
|  | 3894       this); | 
|  | 3895 | 
| 3911   HInstruction* dominated_allocate_instr = | 3896   HInstruction* dominated_allocate_instr = | 
| 3912       HInnerAllocatedObject::New(zone, | 3897       HInnerAllocatedObject::New(zone, | 
| 3913                                  context(), | 3898                                  context(), | 
| 3914                                  dominator_allocate, | 3899                                  dominator_allocate, | 
| 3915                                  aligned_dominator_size, | 3900                                  inner_offset, | 
| 3916                                  type()); | 3901                                  type()); | 
| 3917   dominated_allocate_instr->InsertBefore(this); | 3902   dominated_allocate_instr->InsertBefore(this); | 
| 3918   DeleteAndReplaceWith(dominated_allocate_instr); | 3903   DeleteAndReplaceWith(dominated_allocate_instr); | 
| 3919   if (FLAG_trace_allocation_folding) { | 3904   if (FLAG_trace_allocation_folding) { | 
| 3920     PrintF("#%d (%s) folded into #%d (%s)\n", | 3905     PrintF("#%d (%s) folded into #%d (%s)\n", | 
| 3921         id(), Mnemonic(), dominator_allocate->id(), | 3906         id(), Mnemonic(), dominator_allocate->id(), | 
| 3922         dominator_allocate->Mnemonic()); | 3907         dominator_allocate->Mnemonic()); | 
| 3923   } | 3908   } | 
| 3924   return true; | 3909   return true; | 
| 3925 } | 3910 } | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4032                                      FreeSpace::kSizeOffset, | 4017                                      FreeSpace::kSizeOffset, | 
| 4033                                      Representation::Smi()); | 4018                                      Representation::Smi()); | 
| 4034   HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), | 4019   HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), | 
| 4035       free_space_instr, access, filler_size); | 4020       free_space_instr, access, filler_size); | 
| 4036   store_size->SetFlag(HValue::kHasNoObservableSideEffects); | 4021   store_size->SetFlag(HValue::kHasNoObservableSideEffects); | 
| 4037   store_size->InsertAfter(filler_size); | 4022   store_size->InsertAfter(filler_size); | 
| 4038   filler_free_space_size_ = store_size; | 4023   filler_free_space_size_ = store_size; | 
| 4039 } | 4024 } | 
| 4040 | 4025 | 
| 4041 | 4026 | 
| 4042 void HAllocate::ClearNextMapWord(HValue* offset) { | 4027 void HAllocate::ClearNextMapWord(int offset) { | 
| 4043   if (MustClearNextMapWord()) { | 4028   if (MustClearNextMapWord()) { | 
| 4044     Zone* zone = block()->zone(); | 4029     Zone* zone = block()->zone(); | 
| 4045 | 4030     HObjectAccess access = | 
| 4046     HInstruction* clear_next_map; | 4031         HObjectAccess::ForObservableJSObjectOffset(offset); | 
| 4047     if (offset->IsInteger32Constant()) { | 4032     HStoreNamedField* clear_next_map = | 
| 4048       int offset_value = HConstant::cast(offset)->GetInteger32Constant(); | 4033         HStoreNamedField::New(zone, context(), this, access, | 
| 4049       HObjectAccess access = | 4034             block()->graph()->GetConstant0()); | 
| 4050           HObjectAccess::ForObservableJSObjectOffset(offset_value); |  | 
| 4051       clear_next_map = |  | 
| 4052           HStoreNamedField::New(zone, context(), this, access, |  | 
| 4053                                 block()->graph()->GetConstant0()); |  | 
| 4054     } else { |  | 
| 4055       clear_next_map = |  | 
| 4056           HStoreKeyed::New(zone, context(), |  | 
| 4057                            this, offset, |  | 
| 4058                            block()->graph()->GetConstant0(), |  | 
| 4059                            FAST_HOLEY_SMI_ELEMENTS); |  | 
| 4060     } |  | 
| 4061     clear_next_map->ClearAllSideEffects(); | 4035     clear_next_map->ClearAllSideEffects(); | 
| 4062     clear_next_map->InsertAfter(this); | 4036     clear_next_map->InsertAfter(this); | 
| 4063   } | 4037   } | 
| 4064 } | 4038 } | 
| 4065 | 4039 | 
| 4066 | 4040 | 
| 4067 void HAllocate::PrintDataTo(StringStream* stream) { | 4041 void HAllocate::PrintDataTo(StringStream* stream) { | 
| 4068   size()->PrintNameTo(stream); | 4042   size()->PrintNameTo(stream); | 
| 4069   stream->Add(" ("); | 4043   stream->Add(" ("); | 
| 4070   if (IsNewSpaceAllocation()) stream->Add("N"); | 4044   if (IsNewSpaceAllocation()) stream->Add("N"); | 
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4853       break; | 4827       break; | 
| 4854     case kExternalMemory: | 4828     case kExternalMemory: | 
| 4855       stream->Add("[external-memory]"); | 4829       stream->Add("[external-memory]"); | 
| 4856       break; | 4830       break; | 
| 4857   } | 4831   } | 
| 4858 | 4832 | 
| 4859   stream->Add("@%d", offset()); | 4833   stream->Add("@%d", offset()); | 
| 4860 } | 4834 } | 
| 4861 | 4835 | 
| 4862 } }  // namespace v8::internal | 4836 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|