| Index: src/hydrogen-instructions.h | 
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h | 
| index 9d262fc811724c985c6ddc96697c218e6daab976..4f21db7b405988cdb3caa8ea4e6505a4cadfad53 100644 | 
| --- a/src/hydrogen-instructions.h | 
| +++ b/src/hydrogen-instructions.h | 
| @@ -3946,15 +3946,27 @@ class HLoadFunctionPrototype: public HUnaryOperation { | 
| virtual bool DataEquals(HValue* other) { return true; } | 
| }; | 
|  | 
| +class ArrayInstructionInterface { | 
| + public: | 
| +  virtual HValue* GetKey() = 0; | 
| +  virtual void SetKey(HValue* key) = 0; | 
| +  virtual void SetIndexOffset(uint32_t index_offset) = 0; | 
| +  virtual bool IsDehoisted() = 0; | 
| +  virtual void SetDehoisted(bool is_dehoisted) = 0; | 
| +  virtual ~ArrayInstructionInterface() { }; | 
| +}; | 
|  | 
| -class HLoadKeyedFastElement: public HTemplateInstruction<2> { | 
| +class HLoadKeyedFastElement | 
| +    : public HTemplateInstruction<2>, public ArrayInstructionInterface { | 
| public: | 
| enum HoleCheckMode { PERFORM_HOLE_CHECK, OMIT_HOLE_CHECK }; | 
|  | 
| HLoadKeyedFastElement(HValue* obj, | 
| HValue* key, | 
| HoleCheckMode hole_check_mode = PERFORM_HOLE_CHECK) | 
| -      : hole_check_mode_(hole_check_mode) { | 
| +      : hole_check_mode_(hole_check_mode), | 
| +        index_offset_(0), | 
| +        is_dehoisted_(false) { | 
| SetOperandAt(0, obj); | 
| SetOperandAt(1, key); | 
| set_representation(Representation::Tagged()); | 
| @@ -3964,6 +3976,12 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> { | 
|  | 
| HValue* object() { return OperandAt(0); } | 
| HValue* key() { return OperandAt(1); } | 
| +  uint32_t index_offset() { return index_offset_; } | 
| +  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| +  HValue* GetKey() { return key(); } | 
| +  void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| +  bool IsDehoisted() { return is_dehoisted_; } | 
| +  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| // The key is supposed to be Integer32. | 
| @@ -3982,17 +4000,23 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> { | 
| virtual bool DataEquals(HValue* other) { | 
| if (!other->IsLoadKeyedFastElement()) return false; | 
| HLoadKeyedFastElement* other_load = HLoadKeyedFastElement::cast(other); | 
| +    if (is_dehoisted_ && index_offset_ != other_load->index_offset_) | 
| +      return false; | 
| return hole_check_mode_ == other_load->hole_check_mode_; | 
| } | 
|  | 
| private: | 
| HoleCheckMode hole_check_mode_; | 
| +  uint32_t index_offset_; | 
| +  bool is_dehoisted_; | 
| }; | 
|  | 
|  | 
| -class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { | 
| +class HLoadKeyedFastDoubleElement | 
| +    : public HTemplateInstruction<2>, public ArrayInstructionInterface { | 
| public: | 
| -  HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) { | 
| +  HLoadKeyedFastDoubleElement(HValue* elements, HValue* key) | 
| +      : index_offset_(0), is_dehoisted_(false) { | 
| SetOperandAt(0, elements); | 
| SetOperandAt(1, key); | 
| set_representation(Representation::Double()); | 
| @@ -4002,6 +4026,12 @@ class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { | 
|  | 
| HValue* elements() { return OperandAt(0); } | 
| HValue* key() { return OperandAt(1); } | 
| +  uint32_t index_offset() { return index_offset_; } | 
| +  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| +  HValue* GetKey() { return key(); } | 
| +  void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| +  bool IsDehoisted() { return is_dehoisted_; } | 
| +  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  | 
| virtual Representation RequiredInputRepresentation(int index) { | 
| // The key is supposed to be Integer32. | 
| @@ -4016,15 +4046,22 @@ class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { | 
|  | 
| protected: | 
| virtual bool DataEquals(HValue* other) { return true; } | 
| + | 
| + private: | 
| +  uint32_t index_offset_; | 
| +  bool is_dehoisted_; | 
| }; | 
|  | 
|  | 
| -class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { | 
| +class HLoadKeyedSpecializedArrayElement | 
| +    : public HTemplateInstruction<2>, public ArrayInstructionInterface { | 
| public: | 
| HLoadKeyedSpecializedArrayElement(HValue* external_elements, | 
| HValue* key, | 
| ElementsKind elements_kind) | 
| -      :  elements_kind_(elements_kind) { | 
| +      :  elements_kind_(elements_kind), | 
| +         index_offset_(0), | 
| +         is_dehoisted_(false) { | 
| SetOperandAt(0, external_elements); | 
| SetOperandAt(1, key); | 
| if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 
| @@ -4052,6 +4089,12 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { | 
| HValue* external_pointer() { return OperandAt(0); } | 
| HValue* key() { return OperandAt(1); } | 
| ElementsKind elements_kind() const { return elements_kind_; } | 
| +  uint32_t index_offset() { return index_offset_; } | 
| +  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| +  HValue* GetKey() { return key(); } | 
| +  void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| +  bool IsDehoisted() { return is_dehoisted_; } | 
| +  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  | 
| virtual Range* InferRange(Zone* zone); | 
|  | 
| @@ -4067,6 +4110,8 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { | 
|  | 
| private: | 
| ElementsKind elements_kind_; | 
| +  uint32_t index_offset_; | 
| +  bool is_dehoisted_; | 
| }; | 
|  | 
|  | 
| @@ -4188,11 +4233,12 @@ class HStoreNamedGeneric: public HTemplateInstruction<3> { | 
| }; | 
|  | 
|  | 
| -class HStoreKeyedFastElement: public HTemplateInstruction<3> { | 
| +class HStoreKeyedFastElement | 
| +    : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| public: | 
| HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val, | 
| ElementsKind elements_kind = FAST_ELEMENTS) | 
| -      : elements_kind_(elements_kind) { | 
| +      : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 
| SetOperandAt(0, obj); | 
| SetOperandAt(1, key); | 
| SetOperandAt(2, val); | 
| @@ -4212,6 +4258,12 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> { | 
| bool value_is_smi() { | 
| return elements_kind_ == FAST_SMI_ONLY_ELEMENTS; | 
| } | 
| +  uint32_t index_offset() { return index_offset_; } | 
| +  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| +  HValue* GetKey() { return key(); } | 
| +  void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| +  bool IsDehoisted() { return is_dehoisted_; } | 
| +  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  | 
| bool NeedsWriteBarrier() { | 
| if (value_is_smi()) { | 
| @@ -4227,14 +4279,18 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> { | 
|  | 
| private: | 
| ElementsKind elements_kind_; | 
| +  uint32_t index_offset_; | 
| +  bool is_dehoisted_; | 
| }; | 
|  | 
|  | 
| -class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { | 
| +class HStoreKeyedFastDoubleElement | 
| +    : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| public: | 
| HStoreKeyedFastDoubleElement(HValue* elements, | 
| HValue* key, | 
| -                               HValue* val) { | 
| +                               HValue* val) | 
| +      : index_offset_(0), is_dehoisted_(false) { | 
| SetOperandAt(0, elements); | 
| SetOperandAt(1, key); | 
| SetOperandAt(2, val); | 
| @@ -4254,6 +4310,12 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { | 
| HValue* elements() { return OperandAt(0); } | 
| HValue* key() { return OperandAt(1); } | 
| HValue* value() { return OperandAt(2); } | 
| +  uint32_t index_offset() { return index_offset_; } | 
| +  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| +  HValue* GetKey() { return key(); } | 
| +  void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| +  bool IsDehoisted() { return is_dehoisted_; } | 
| +  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  | 
| bool NeedsWriteBarrier() { | 
| return StoringValueNeedsWriteBarrier(value()); | 
| @@ -4264,16 +4326,21 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { | 
| virtual void PrintDataTo(StringStream* stream); | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement) | 
| + | 
| + private: | 
| +  uint32_t index_offset_; | 
| +  bool is_dehoisted_; | 
| }; | 
|  | 
|  | 
| -class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { | 
| +class HStoreKeyedSpecializedArrayElement | 
| +    : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| public: | 
| HStoreKeyedSpecializedArrayElement(HValue* external_elements, | 
| HValue* key, | 
| HValue* val, | 
| ElementsKind elements_kind) | 
| -      : elements_kind_(elements_kind) { | 
| +      : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 
| SetGVNFlag(kChangesSpecializedArrayElements); | 
| SetOperandAt(0, external_elements); | 
| SetOperandAt(1, key); | 
| @@ -4301,11 +4368,19 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { | 
| HValue* key() { return OperandAt(1); } | 
| HValue* value() { return OperandAt(2); } | 
| ElementsKind elements_kind() const { return elements_kind_; } | 
| +  uint32_t index_offset() { return index_offset_; } | 
| +  void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| +  HValue* GetKey() { return key(); } | 
| +  void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| +  bool IsDehoisted() { return is_dehoisted_; } | 
| +  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
|  | 
| DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) | 
|  | 
| private: | 
| ElementsKind elements_kind_; | 
| +  uint32_t index_offset_; | 
| +  bool is_dehoisted_; | 
| }; | 
|  | 
|  | 
|  |