Index: src/crankshaft/hydrogen-instructions.h |
diff --git a/src/crankshaft/hydrogen-instructions.h b/src/crankshaft/hydrogen-instructions.h |
index a98efe651b733c63e56dae14dd1328eb7fd37418..9567c309a2d2b6a952851e5f895a366bb2001c0c 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,28 @@ 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(HAllocate* dominator) { |
+ flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATION_FOLDED); |
+ ClearFlag(kTrackSideEffectDominators); |
+ ClearChangesFlag(kNewSpacePromotion); |
+ SetOperandAt(2, dominator); |
+ } |
+ |
+ bool IsAllocationFolded() { return (flags_ & ALLOCATION_FOLDED) != 0; } |
+ |
bool HandleSideEffectDominator(GVNFlag side_effect, |
HValue* dominator) override; |
@@ -5026,23 +5034,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 +5076,20 @@ 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); |
- |
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 +5161,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(); |
+ DCHECK(HAllocate::cast(dominator)->IsAllocationFoldingDominator()); |
+ object = dominator; |
+ } |
+ } |
+ |
if (object->IsConstant() && |
HConstant::cast(object)->HasExternalReferenceValue()) { |
// Stores to external references require no write barriers |