Chromium Code Reviews| Index: src/crankshaft/hydrogen-instructions.h |
| diff --git a/src/crankshaft/hydrogen-instructions.h b/src/crankshaft/hydrogen-instructions.h |
| index a98efe651b733c63e56dae14dd1328eb7fd37418..49e429fe7cb46a5bbc436f24fe1e2b5eb7b5c888 100644 |
| --- a/src/crankshaft/hydrogen-instructions.h |
| +++ b/src/crankshaft/hydrogen-instructions.h |
| @@ -4939,8 +4939,7 @@ class HLoadGlobalGeneric final : public HTemplateInstruction<2> { |
| FeedbackVectorSlot slot_; |
| }; |
| - |
| -class HAllocate final : public HTemplateInstruction<2> { |
| +class HAllocate final : public HTemplateInstruction<3> { |
| public: |
| static bool CompatibleInstanceTypes(InstanceType type1, |
| InstanceType type2) { |
| @@ -4951,9 +4950,10 @@ class HAllocate final : public HTemplateInstruction<2> { |
| static HAllocate* New( |
| Isolate* isolate, Zone* zone, HValue* context, HValue* size, HType type, |
| PretenureFlag pretenure_flag, InstanceType instance_type, |
| + HValue* dominator, |
| Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) { |
| - return new(zone) HAllocate(context, size, type, pretenure_flag, |
| - instance_type, allocation_site); |
| + return new (zone) HAllocate(context, size, type, pretenure_flag, |
| + instance_type, dominator, allocation_site); |
| } |
| // Maximum instance size for which allocations will be inlined. |
| @@ -4961,13 +4961,7 @@ class HAllocate final : public HTemplateInstruction<2> { |
| HValue* context() const { return OperandAt(0); } |
| HValue* size() const { return OperandAt(1); } |
| - |
| - bool has_size_upper_bound() { return size_upper_bound_ != NULL; } |
| - HConstant* size_upper_bound() { return size_upper_bound_; } |
| - void set_size_upper_bound(HConstant* value) { |
| - DCHECK(size_upper_bound_ == NULL); |
| - size_upper_bound_ = value; |
| - } |
| + HValue* allocation_folding_dominator() const { return OperandAt(2); } |
| Representation RequiredInputRepresentation(int index) override { |
| if (index == 0) { |
| @@ -5005,14 +4999,27 @@ class HAllocate final : public HTemplateInstruction<2> { |
| flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); |
| } |
| - bool MustClearNextMapWord() const { |
| - return (flags_ & CLEAR_NEXT_MAP_WORD) != 0; |
| - } |
| - |
| void MakeDoubleAligned() { |
| flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); |
| } |
| + void MakeAllocationFoldingDominator() { |
| + flags_ = |
| + static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDING_DOMINATOR); |
| + } |
| + |
| + bool IsAllocationFoldingDominator() { |
| + return (flags_ & ALLOCATION_FOLDING_DOMINATOR) != 0; |
| + } |
| + |
| + void MakeFoldedAllocation() { |
|
Michael Lippautz
2016/05/10 08:32:57
nit: It would probably make more sense to pass the
Hannes Payer (out of office)
2016/05/10 09:04:44
Done.
|
| + flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDED); |
| + ClearFlag(kTrackSideEffectDominators); |
| + ClearChangesFlag(kNewSpacePromotion); |
| + } |
| + |
| + bool IsAllocationFolded() { return (flags_ & ALLOCATION_FOLDED) != 0; } |
| + |
| bool HandleSideEffectDominator(GVNFlag side_effect, |
| HValue* dominator) override; |
| @@ -5026,23 +5033,19 @@ class HAllocate final : public HTemplateInstruction<2> { |
| ALLOCATE_IN_OLD_SPACE = 1 << 2, |
| ALLOCATE_DOUBLE_ALIGNED = 1 << 3, |
| PREFILL_WITH_FILLER = 1 << 4, |
| - CLEAR_NEXT_MAP_WORD = 1 << 5 |
| + ALLOCATION_FOLDING_DOMINATOR = 1 << 5, |
| + ALLOCATION_FOLDED = 1 << 6 |
| }; |
| - HAllocate(HValue* context, |
| - HValue* size, |
| - HType type, |
| - PretenureFlag pretenure_flag, |
| - InstanceType instance_type, |
| - Handle<AllocationSite> allocation_site = |
| - Handle<AllocationSite>::null()) |
| - : HTemplateInstruction<2>(type), |
| - flags_(ComputeFlags(pretenure_flag, instance_type)), |
| - dominating_allocate_(NULL), |
| - filler_free_space_size_(NULL), |
| - size_upper_bound_(NULL) { |
| + HAllocate( |
| + HValue* context, HValue* size, HType type, PretenureFlag pretenure_flag, |
| + InstanceType instance_type, HValue* dominator, |
| + Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null()) |
| + : HTemplateInstruction<3>(type), |
| + flags_(ComputeFlags(pretenure_flag, instance_type)) { |
| SetOperandAt(0, context); |
| UpdateSize(size); |
| + SetOperandAt(2, dominator); |
| set_representation(Representation::Tagged()); |
| SetFlag(kTrackSideEffectDominators); |
| SetChangesFlag(kNewSpacePromotion); |
| @@ -5072,46 +5075,24 @@ class HAllocate final : public HTemplateInstruction<2> { |
| if (!FLAG_use_gvn || !FLAG_use_allocation_folding) { |
| flags = static_cast<Flags>(flags | PREFILL_WITH_FILLER); |
| } |
| - if (pretenure_flag == NOT_TENURED && |
| - AllocationSite::CanTrack(instance_type)) { |
| - flags = static_cast<Flags>(flags | CLEAR_NEXT_MAP_WORD); |
| - } |
| return flags; |
| } |
| - void UpdateClearNextMapWord(bool clear_next_map_word) { |
| - flags_ = static_cast<Flags>(clear_next_map_word |
| - ? flags_ | CLEAR_NEXT_MAP_WORD |
| - : flags_ & ~CLEAR_NEXT_MAP_WORD); |
| - } |
| - |
| void UpdateSize(HValue* size) { |
| SetOperandAt(1, size); |
| - if (size->IsInteger32Constant()) { |
| - size_upper_bound_ = HConstant::cast(size); |
| - } else { |
| - size_upper_bound_ = NULL; |
| - } |
| } |
| - HAllocate* GetFoldableDominator(HAllocate* dominator); |
| - |
| - void UpdateFreeSpaceFiller(int32_t filler_size); |
| - |
| - void CreateFreeSpaceFiller(int32_t filler_size); |
| + void UpdateAllocationFoldingDominator(HAllocate* dominator) { |
| + SetOperandAt(2, dominator); |
| + } |
| bool IsFoldable(HAllocate* allocate) { |
| return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) || |
| (IsOldSpaceAllocation() && allocate->IsOldSpaceAllocation()); |
| } |
| - void ClearNextMapWord(int offset); |
| - |
| Flags flags_; |
| Handle<Map> known_initial_map_; |
| - HAllocate* dominating_allocate_; |
| - HStoreNamedField* filler_free_space_size_; |
| - HConstant* size_upper_bound_; |
| }; |
| @@ -5183,9 +5164,20 @@ inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
| inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
| HValue* value, |
| HValue* dominator) { |
| + // There may be multiple inner allocates dominated by one allocate. |
| while (object->IsInnerAllocatedObject()) { |
| object = HInnerAllocatedObject::cast(object)->base_object(); |
| } |
| + |
| + if (object->IsAllocate()) { |
| + HAllocate* allocate = HAllocate::cast(object); |
| + if (allocate->IsAllocationFolded()) { |
| + HValue* dominator = allocate->allocation_folding_dominator(); |
|
Michael Lippautz
2016/05/10 08:32:57
nit: If you make this a nullptr check and not use
Hannes Payer (out of office)
2016/05/10 09:04:44
This is not possible. The input has to be a valid
|
| + DCHECK(HAllocate::cast(dominator)->IsAllocationFoldingDominator()); |
| + object = dominator; |
| + } |
| + } |
| + |
| if (object->IsConstant() && |
| HConstant::cast(object)->HasExternalReferenceValue()) { |
| // Stores to external references require no write barriers |