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. |