Chromium Code Reviews| Index: src/hydrogen-instructions.h | 
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h | 
| index 0c3ee1dc081101e47646daa14e0c1beb464f9ceb..772185a7446054a3ea9f54382286f19e4d75eb87 100644 | 
| --- a/src/hydrogen-instructions.h | 
| +++ b/src/hydrogen-instructions.h | 
| @@ -5238,35 +5238,92 @@ class HStoreContextSlot: public HTemplateInstruction<2> { | 
| }; | 
| +// Represents an access (load or store) to a portion of an object for GVN. | 
| +// TODO(titzer): only represents non-array-element loads and stores for now | 
| +class ObjectAccess { | 
| + public: | 
| + enum Portion { | 
| + kElementsKind, | 
| 
 
danno
2013/04/26 09:39:38
The seems redundant to me. It seems like this is w
 
titzer
2013/04/30 15:56:47
As discussed in person, I think we can make this w
 
 | 
| + kArrayLengths, | 
| + kInobject, | 
| + kBackingStore, | 
| + kElementsPointer, | 
| + kMaps | 
| + }; | 
| + | 
| + ObjectAccess(Portion portion, int offset, bool may_allocate, | 
| + Handle<String> name = Handle<String>::null()) | 
| + : portion_(portion), offset_(offset), may_allocate_(may_allocate) { } | 
| + | 
| + void SetGVNFlags(HValue *instr, bool is_store) { | 
| 
 
danno
2013/04/26 09:39:38
Make this protected and add HLoadNamedFiled and HS
 
titzer
2013/04/30 15:56:47
Done.
 
 | 
| + // set the appropriate GVN flags for a given load or store instruction | 
| + if (!is_store) { | 
| + instr->SetFlag(HValue::kUseGVN); // try to GVN loads | 
| + instr->SetGVNFlag(kDependsOnMaps); // but don't hoist above map changes | 
| + } | 
| + | 
| + // if this instruction might trigger an allocation | 
| + if (may_allocate_) instr->SetGVNFlag(kChangesNewSpacePromotion); | 
| 
 
danno
2013/04/26 09:39:38
When does this actually happen? We should try to g
 
titzer
2013/04/30 15:56:47
Done.
 
 | 
| + | 
| + switch (portion_) { | 
| + case kElementsKind: | 
| + instr->SetGVNFlag( | 
| + is_store ? kChangesElementsKind : kDependsOnElementsKind); | 
| 
 
danno
2013/04/26 09:39:38
Don't know if it makes the code cleaner, but maybe
 
titzer
2013/04/30 15:56:47
That method takes a GVNFlagSet and does a shift. I
 
 | 
| + break; | 
| + case kArrayLengths: | 
| + instr->SetGVNFlag( | 
| + is_store ? kChangesArrayLengths : kDependsOnArrayLengths); | 
| + break; | 
| + case kInobject: | 
| + instr->SetGVNFlag( | 
| + is_store ? kChangesInobjectFields : kDependsOnInobjectFields); | 
| + break; | 
| + case kBackingStore: | 
| + instr->SetGVNFlag( | 
| + is_store ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); | 
| + break; | 
| + case kElementsPointer: | 
| + instr->SetGVNFlag( | 
| + is_store ? kChangesElementsPointer : kDependsOnElementsPointer); | 
| + break; | 
| + case kMaps: | 
| + instr->SetGVNFlag( | 
| + is_store ? kChangesMaps : kDependsOnMaps); | 
| + break; | 
| + } | 
| 
 
danno
2013/04/26 09:39:38
This guy really belongs in the .cc file.
 
titzer
2013/04/30 15:56:47
Done.
 
 | 
| + } | 
| + | 
| + inline bool IsInobject() { | 
| + return portion_ != kBackingStore; | 
| + } | 
| + | 
| + inline int offset() { | 
| + return offset_; | 
| + } | 
| + | 
| + inline Handle<String> name() { | 
| 
 
danno
2013/04/26 09:39:38
This can be calculated by looking in the map's fie
 
titzer
2013/04/30 15:56:47
I agree with that approach in the long run. We can
 
 | 
| + return name_; | 
| + } | 
| + | 
| + private: | 
| + Portion portion_; | 
| + int offset_; | 
| + bool may_allocate_; | 
| + Handle<String> name_; | 
| 
 
danno
2013/04/26 09:39:38
You don't need to store this it can be looked-up i
 
danno
2013/05/02 14:16:47
You didn't address this comment. Why not?
On 2013
 
 | 
| +}; | 
| + | 
| + | 
| class HLoadNamedField: public HTemplateInstruction<2> { | 
| public: | 
| - HLoadNamedField(HValue* object, bool is_in_object, int offset, | 
| - HValue* typecheck = NULL) | 
| - : is_in_object_(is_in_object), | 
| - offset_(offset) { | 
| + HLoadNamedField(HValue* object, ObjectAccess access, HValue* typecheck = NULL) | 
| 
 
danno
2013/04/26 09:39:38
Unless the objects is the size of intptr_t, then w
 
titzer
2013/04/30 15:56:47
Done.
 
 | 
| + : is_in_object_(access.IsInobject()), | 
| + offset_(access.offset()) { | 
| ASSERT(object != NULL); | 
| SetOperandAt(0, object); | 
| SetOperandAt(1, typecheck != NULL ? typecheck : object); | 
| set_representation(Representation::Tagged()); | 
| - SetFlag(kUseGVN); | 
| - SetGVNFlag(kDependsOnMaps); | 
| - if (is_in_object) { | 
| - SetGVNFlag(kDependsOnInobjectFields); | 
| - } else { | 
| - SetGVNFlag(kDependsOnBackingStoreFields); | 
| - } | 
| - } | 
| - | 
| - static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object, | 
| - HValue* typecheck, | 
| - HType type = HType::Tagged()) { | 
| - HLoadNamedField* result = new(zone) HLoadNamedField( | 
| - object, true, JSArray::kLengthOffset, typecheck); | 
| - result->set_type(type); | 
| - result->SetGVNFlag(kDependsOnArrayLengths); | 
| - result->ClearGVNFlag(kDependsOnInobjectFields); | 
| - return result; | 
| + access.SetGVNFlags(this, false); | 
| } | 
| HValue* object() { return OperandAt(0); } | 
| @@ -5590,24 +5647,17 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> { | 
| class HStoreNamedField: public HTemplateInstruction<2> { | 
| public: | 
| HStoreNamedField(HValue* obj, | 
| - Handle<String> name, | 
| - HValue* val, | 
| - bool in_object, | 
| - int offset) | 
| - : name_(name), | 
| - is_in_object_(in_object), | 
| - offset_(offset), | 
| + ObjectAccess access, | 
| + HValue* val) | 
| + : name_(access.name()), | 
| + is_in_object_(access.IsInobject()), | 
| + offset_(access.offset()), | 
| transition_unique_id_(), | 
| new_space_dominator_(NULL) { | 
| SetOperandAt(0, obj); | 
| SetOperandAt(1, val); | 
| SetFlag(kTrackSideEffectDominators); | 
| - SetGVNFlag(kDependsOnNewSpacePromotion); | 
| - if (is_in_object_) { | 
| - SetGVNFlag(kChangesInobjectFields); | 
| - } else { | 
| - SetGVNFlag(kChangesBackingStoreFields); | 
| - } | 
| + access.SetGVNFlags(this, true); | 
| } | 
| DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) |