Chromium Code Reviews| Index: src/hydrogen-instructions.h |
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
| index d0dd5680c0485555b013113e97cf0ea9e8d59701..ebd4f2272ea6e35a5c73a003c7649ce69fe50347 100644 |
| --- a/src/hydrogen-instructions.h |
| +++ b/src/hydrogen-instructions.h |
| @@ -188,7 +188,10 @@ class LChunkBuilder; |
| V(DateField) \ |
| V(WrapReceiver) |
| -#define GVN_FLAG_LIST(V) \ |
| +#define GVN_TRACKED_FLAG_LIST(V) \ |
| + V(NewSpace) |
| + |
| +#define GVN_UNTRACKED_FLAG_LIST(V) \ |
| V(Calls) \ |
| V(InobjectFields) \ |
| V(BackingStoreFields) \ |
| @@ -506,14 +509,18 @@ class HUseIterator BASE_EMBEDDED { |
| // There must be one corresponding kDepends flag for every kChanges flag and |
| // the order of the kChanges flags must be exactly the same as of the kDepends |
| -// flags. |
| +// flags. All tracked flags should appear before untracked ones. |
| enum GVNFlag { |
| // Declare global value numbering flags. |
| #define DECLARE_FLAG(type) kChanges##type, kDependsOn##type, |
| - GVN_FLAG_LIST(DECLARE_FLAG) |
| + GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) |
| + GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) |
| #undef DECLARE_FLAG |
| kAfterLastFlag, |
| - kLastFlag = kAfterLastFlag - 1 |
| + kLastFlag = kAfterLastFlag - 1, |
| +#define COUNT_FLAG(type) + 1 |
| + kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG) |
| +#undef COUNT_FLAG |
|
Erik Corry
2012/04/10 12:06:52
I think it would be nice to provide functions:
GV
Michael Starzinger
2012/04/11 09:53:08
Done.
|
| }; |
| typedef EnumSet<GVNFlag> GVNFlagSet; |
| @@ -530,6 +537,10 @@ class HValue: public ZoneObject { |
| // implement DataEquals(), which will be used to determine if other |
| // occurrences of the instruction are indeed the same. |
| kUseGVN, |
| + // Track instructions that are dominating side effects. If an instruction |
| + // sets this flag, it must implement SetSideEffectDominator() and should |
| + // indicate which side effects to track by setting GVN flags. |
| + kTrackSideEffectDominators, |
| kCanOverflow, |
| kBailoutOnMinusZero, |
| kCanBeDivByZero, |
| @@ -726,6 +737,13 @@ class HValue: public ZoneObject { |
| virtual HType CalculateInferredType(); |
| + // This function must be overridden for instructions which have the |
| + // kTrackSideEffectDominators flag set, to track instructions that are |
| + // dominating side effects. |
| + virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
| + UNREACHABLE(); |
| + } |
| + |
| #ifdef DEBUG |
| virtual void Verify() = 0; |
| #endif |
| @@ -756,7 +774,8 @@ class HValue: public ZoneObject { |
| GVNFlagSet result; |
| // Create changes mask. |
| #define ADD_FLAG(type) result.Add(kDependsOn##type); |
| - GVN_FLAG_LIST(ADD_FLAG) |
| + GVN_TRACKED_FLAG_LIST(ADD_FLAG) |
| + GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) |
| #undef ADD_FLAG |
| return result; |
| } |
| @@ -765,7 +784,8 @@ class HValue: public ZoneObject { |
| GVNFlagSet result; |
| // Create changes mask. |
| #define ADD_FLAG(type) result.Add(kChanges##type); |
| - GVN_FLAG_LIST(ADD_FLAG) |
| + GVN_TRACKED_FLAG_LIST(ADD_FLAG) |
| + GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) |
| #undef ADD_FLAG |
| return result; |
| } |
| @@ -781,6 +801,7 @@ class HValue: public ZoneObject { |
| // an executing program (i.e. are not safe to repeat, move or remove); |
| static GVNFlagSet AllObservableSideEffectsFlagSet() { |
| GVNFlagSet result = AllChangesFlagSet(); |
| + result.Remove(kChangesNewSpace); |
|
Erik Corry
2012/04/10 12:06:52
The name makes it sound like any write to new spac
Michael Starzinger
2012/04/11 09:53:08
Done.
|
| result.Remove(kChangesElementsKind); |
| result.Remove(kChangesElementsPointer); |
| result.Remove(kChangesMaps); |
| @@ -3557,6 +3578,12 @@ inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
| } |
| +inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
| + HValue* new_space_dominator) { |
| + return !object->IsAllocateObject() || (object != new_space_dominator); |
| +} |
| + |
| + |
| class HStoreGlobalCell: public HUnaryOperation { |
| public: |
| HStoreGlobalCell(HValue* value, |
| @@ -4026,6 +4053,8 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
| offset_(offset) { |
|
Erik Corry
2012/04/10 12:06:52
Should you not initialize new_space_dominator_ her
Michael Starzinger
2012/04/11 09:53:08
Done.
|
| SetOperandAt(0, obj); |
| SetOperandAt(1, val); |
| + SetFlag(kTrackSideEffectDominators); |
| + SetGVNFlag(kDependsOnNewSpace); |
| if (is_in_object_) { |
| SetGVNFlag(kChangesInobjectFields); |
| } else { |
| @@ -4038,6 +4067,10 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
| virtual Representation RequiredInputRepresentation(int index) { |
| return Representation::Tagged(); |
| } |
| + virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) { |
| + ASSERT(side_effect == kChangesNewSpace); |
| + new_space_dominator_ = dominator; |
| + } |
| virtual void PrintDataTo(StringStream* stream); |
| HValue* object() { return OperandAt(0); } |
| @@ -4048,9 +4081,11 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
| int offset() const { return offset_; } |
| Handle<Map> transition() const { return transition_; } |
| void set_transition(Handle<Map> map) { transition_ = map; } |
| + HValue* new_space_dominator() const { return new_space_dominator_; } |
| bool NeedsWriteBarrier() { |
| - return StoringValueNeedsWriteBarrier(value()); |
| + return StoringValueNeedsWriteBarrier(value()) && |
| + ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
| } |
| private: |
| @@ -4058,6 +4093,7 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
| bool is_in_object_; |
| int offset_; |
| Handle<Map> transition_; |
| + HValue* new_space_dominator_; |
| }; |
| @@ -4404,6 +4440,7 @@ class HAllocateObject: public HTemplateInstruction<1> { |
| : constructor_(constructor) { |
| SetOperandAt(0, context); |
| set_representation(Representation::Tagged()); |
| + SetGVNFlag(kChangesNewSpace); |
| } |
| // Maximum instance size for which allocations will be inlined. |