| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index 138587c43f72b45b9be5193682174eb37b6896be..6d422e009d3fa01232830003223adcb6cd86b5ca 100644
|
| --- a/src/hydrogen-instructions.h
|
| +++ b/src/hydrogen-instructions.h
|
| @@ -203,7 +203,6 @@ class LChunkBuilder;
|
| V(Calls) \
|
| V(InobjectFields) \
|
| V(BackingStoreFields) \
|
| - V(DoubleFields) \
|
| V(ElementsKind) \
|
| V(ElementsPointer) \
|
| V(ArrayElements) \
|
| @@ -5183,14 +5182,113 @@ class HStoreContextSlot: public HTemplateInstruction<2> {
|
| };
|
|
|
|
|
| +// Represents an access to a portion of an object, such as the map pointer,
|
| +// array elements pointer, etc, but not accesses to array elements themselves.
|
| +class HObjectAccess {
|
| + public:
|
| + inline bool IsInobject() const {
|
| + return portion() != kBackingStore;
|
| + }
|
| +
|
| + inline int offset() const {
|
| + return OffsetField::decode(value_);
|
| + }
|
| +
|
| + inline Handle<String> name() const {
|
| + return name_;
|
| + }
|
| +
|
| + static HObjectAccess ForHeapNumberValue() {
|
| + return HObjectAccess(kInobject, HeapNumber::kValueOffset);
|
| + }
|
| +
|
| + static HObjectAccess ForElementsPointer() {
|
| + return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
|
| + }
|
| +
|
| + static HObjectAccess ForArrayLength() {
|
| + return HObjectAccess(kArrayLengths, JSArray::kLengthOffset);
|
| + }
|
| +
|
| + static HObjectAccess ForFixedArrayLength() {
|
| + return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset);
|
| + }
|
| +
|
| + static HObjectAccess ForPropertiesPointer() {
|
| + return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
|
| + }
|
| +
|
| + static HObjectAccess ForMap() {
|
| + return HObjectAccess(kMaps, JSObject::kMapOffset);
|
| + }
|
| +
|
| + static HObjectAccess ForAllocationSitePayload() {
|
| + return HObjectAccess(kInobject, AllocationSiteInfo::kPayloadOffset);
|
| + }
|
| +
|
| + // Create an access to an offset in a fixed array header.
|
| + static HObjectAccess ForFixedArrayHeader(int offset);
|
| +
|
| + // Create an access to an in-object property in a JSObject.
|
| + static HObjectAccess ForJSObjectOffset(int offset);
|
| +
|
| + // Create an access to an in-object property in a JSArray.
|
| + static HObjectAccess ForJSArrayOffset(int offset);
|
| +
|
| + // Create an access to the backing store of an object.
|
| + static HObjectAccess ForBackingStoreOffset(int offset);
|
| +
|
| + // Create an access to a resolved field (in-object or backing store).
|
| + static HObjectAccess ForField(Handle<Map> map,
|
| + LookupResult *lookup, Handle<String> name = Handle<String>::null());
|
| +
|
| + void PrintTo(StringStream* stream);
|
| +
|
| + protected:
|
| + void SetGVNFlags(HValue *instr, bool is_store);
|
| +
|
| + private:
|
| + // internal use only; different parts of an object or array
|
| + enum Portion {
|
| + kMaps, // map of an object
|
| + kArrayLengths, // the length of an array
|
| + kElementsPointer, // elements pointer
|
| + kBackingStore, // some field in the backing store
|
| + kInobject // some other in-object field
|
| + };
|
| +
|
| + HObjectAccess(Portion portion, int offset,
|
| + Handle<String> name = Handle<String>::null())
|
| + : value_(PortionField::encode(portion) | OffsetField::encode(offset)),
|
| + name_(name) {
|
| + ASSERT(this->offset() == offset); // offset should decode correctly
|
| + ASSERT(this->portion() == portion); // portion should decode correctly
|
| + }
|
| +
|
| + class PortionField : public BitField<Portion, 0, 3> {};
|
| + class OffsetField : public BitField<int, 3, 29> {};
|
| +
|
| + uint32_t value_; // encodes both portion and offset
|
| + Handle<String> name_;
|
| +
|
| + friend class HLoadNamedField;
|
| + friend class HStoreNamedField;
|
| +
|
| + inline Portion portion() const {
|
| + return PortionField::decode(value_);
|
| + }
|
| +};
|
| +
|
| +
|
| class HLoadNamedField: public HTemplateInstruction<2> {
|
| public:
|
| - HLoadNamedField(HValue* object, bool is_in_object,
|
| - Representation field_representation,
|
| - int offset, HValue* typecheck = NULL)
|
| - : is_in_object_(is_in_object),
|
| - field_representation_(field_representation),
|
| - offset_(offset) {
|
| + HLoadNamedField(HValue* object,
|
| + HObjectAccess access,
|
| + HValue* typecheck = NULL,
|
| + Representation field_representation
|
| + = Representation::Tagged())
|
| + : access_(access),
|
| + field_representation_(field_representation) {
|
| ASSERT(object != NULL);
|
| SetOperandAt(0, object);
|
| SetOperandAt(1, typecheck != NULL ? typecheck : object);
|
| @@ -5207,31 +5305,7 @@ class HLoadNamedField: public HTemplateInstruction<2> {
|
| } else {
|
| set_representation(Representation::Tagged());
|
| }
|
| - SetFlag(kUseGVN);
|
| - if (FLAG_track_double_fields && representation().IsDouble()) {
|
| - ASSERT(is_in_object);
|
| - ASSERT(offset == HeapNumber::kValueOffset);
|
| - SetGVNFlag(kDependsOnDoubleFields);
|
| - } else if (is_in_object) {
|
| - SetGVNFlag(kDependsOnInobjectFields);
|
| - SetGVNFlag(kDependsOnMaps);
|
| - } else {
|
| - SetGVNFlag(kDependsOnBackingStoreFields);
|
| - SetGVNFlag(kDependsOnMaps);
|
| - }
|
| - }
|
| -
|
| - static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object,
|
| - HValue* typecheck,
|
| - HType type = HType::Tagged()) {
|
| - Representation representation =
|
| - type.IsSmi() ? Representation::Smi() : Representation::Tagged();
|
| - HLoadNamedField* result = new(zone) HLoadNamedField(
|
| - object, true, representation, JSArray::kLengthOffset, typecheck);
|
| - result->set_type(type);
|
| - result->SetGVNFlag(kDependsOnArrayLengths);
|
| - result->ClearGVNFlag(kDependsOnInobjectFields);
|
| - return result;
|
| + access.SetGVNFlags(this, false);
|
| }
|
|
|
| HValue* object() { return OperandAt(0); }
|
| @@ -5241,9 +5315,10 @@ class HLoadNamedField: public HTemplateInstruction<2> {
|
| }
|
|
|
| bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
|
| - bool is_in_object() const { return is_in_object_; }
|
| + HObjectAccess access() const { return access_; }
|
| + bool is_in_object() const { return access_.IsInobject(); }
|
| Representation field_representation() const { return representation_; }
|
| - int offset() const { return offset_; }
|
| + int offset() const { return access_.offset(); }
|
|
|
| virtual Representation RequiredInputRepresentation(int index) {
|
| return Representation::Tagged();
|
| @@ -5255,15 +5330,14 @@ class HLoadNamedField: public HTemplateInstruction<2> {
|
| protected:
|
| virtual bool DataEquals(HValue* other) {
|
| HLoadNamedField* b = HLoadNamedField::cast(other);
|
| - return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
|
| + return is_in_object() == b->is_in_object() && offset() == b->offset();
|
| }
|
|
|
| private:
|
| virtual bool IsDeletable() const { return true; }
|
|
|
| - bool is_in_object_;
|
| + HObjectAccess access_;
|
| Representation field_representation_;
|
| - int offset_;
|
| };
|
|
|
|
|
| @@ -5558,29 +5632,17 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> {
|
| class HStoreNamedField: public HTemplateInstruction<2> {
|
| public:
|
| HStoreNamedField(HValue* obj,
|
| - Handle<Name> name,
|
| + HObjectAccess access,
|
| HValue* val,
|
| - bool in_object,
|
| - Representation field_representation,
|
| - int offset)
|
| - : name_(name),
|
| - is_in_object_(in_object),
|
| + Representation field_representation
|
| + = Representation::Tagged())
|
| + : access_(access),
|
| field_representation_(field_representation),
|
| - offset_(offset),
|
| transition_unique_id_(),
|
| new_space_dominator_(NULL) {
|
| SetOperandAt(0, obj);
|
| SetOperandAt(1, val);
|
| - SetFlag(kTrackSideEffectDominators);
|
| - if (FLAG_track_double_fields && field_representation.IsDouble()) {
|
| - SetGVNFlag(kChangesDoubleFields);
|
| - } else if (is_in_object_) {
|
| - SetGVNFlag(kChangesInobjectFields);
|
| - SetGVNFlag(kDependsOnNewSpacePromotion);
|
| - } else {
|
| - SetGVNFlag(kChangesBackingStoreFields);
|
| - SetGVNFlag(kDependsOnNewSpacePromotion);
|
| - }
|
| + access.SetGVNFlags(this, true);
|
| }
|
|
|
| DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
|
| @@ -5604,9 +5666,10 @@ class HStoreNamedField: public HTemplateInstruction<2> {
|
| HValue* object() { return OperandAt(0); }
|
| HValue* value() { return OperandAt(1); }
|
|
|
| - Handle<Name> name() const { return name_; }
|
| - bool is_in_object() const { return is_in_object_; }
|
| - int offset() const { return offset_; }
|
| + HObjectAccess access() const { return access_; }
|
| + Handle<String> name() const { return access_.name(); }
|
| + bool is_in_object() const { return access_.IsInobject(); }
|
| + int offset() const { return access_.offset(); }
|
| Handle<Map> transition() const { return transition_; }
|
| UniqueValueId transition_unique_id() const { return transition_unique_id_; }
|
| void set_transition(Handle<Map> map) { transition_ = map; }
|
| @@ -5635,10 +5698,8 @@ class HStoreNamedField: public HTemplateInstruction<2> {
|
| }
|
|
|
| private:
|
| - Handle<Name> name_;
|
| - bool is_in_object_;
|
| + HObjectAccess access_;
|
| Representation field_representation_;
|
| - int offset_;
|
| Handle<Map> transition_;
|
| UniqueValueId transition_unique_id_;
|
| HValue* new_space_dominator_;
|
|
|