| Index: src/hydrogen-instructions.h | 
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h | 
| index aa513e707b235c8a20a63a55acacfa78b6189e82..2d57537596b612ffff8aa628dac5b0bac9cb8027 100644 | 
| --- a/src/hydrogen-instructions.h | 
| +++ b/src/hydrogen-instructions.h | 
| @@ -673,6 +673,31 @@ class HValue: public ZoneObject { | 
| return NULL; | 
| } | 
|  | 
| +  // There are HInstructions that do not really change a value, they | 
| +  // only add pieces of information to it (like bounds checks, map checks, | 
| +  // smi checks...). | 
| +  // We call these instructions "informative definitions", or "iDef". | 
| +  // One of the iDef operands is special because it is the value that is | 
| +  // "transferred" to the output, we call it the "redefined operand". | 
| +  // If an HValue is an iDef it must override RedefinedOperandIndex() so that | 
| +  // it does not return kNoRedefinedOperand; | 
| +  static const int kNoRedefinedOperand = -1; | 
| +  virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } | 
| +  bool IsInformativeDefinition() { | 
| +    return RedefinedOperandIndex() != kNoRedefinedOperand; | 
| +  } | 
| +  HValue* RedefinedOperand() { | 
| +    ASSERT(IsInformativeDefinition()); | 
| +    return OperandAt(RedefinedOperandIndex()); | 
| +  } | 
| + | 
| +  // This method must always return the original HValue SSA definition | 
| +  // (regardless of any iDef of this value). | 
| +  HValue* ActualValue() { | 
| +    return IsInformativeDefinition() ? RedefinedOperand()->ActualValue() | 
| +                                     : this; | 
| +  } | 
| + | 
| bool IsDefinedAfter(HBasicBlock* other) const; | 
|  | 
| // Operands. | 
| @@ -3020,44 +3045,38 @@ enum BoundsCheckKeyMode { | 
| class HBoundsCheck: public HTemplateInstruction<2> { | 
| public: | 
| HBoundsCheck(HValue* index, HValue* length, | 
| -               BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) | 
| +               BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, | 
| +               Representation r = Representation::None()) | 
| : key_mode_(key_mode) { | 
| SetOperandAt(0, index); | 
| SetOperandAt(1, length); | 
| -    set_representation(Representation::Integer32()); | 
| +    if (r.IsNone()) { | 
| +      // In the normal compilation pipeline the representation is flexible | 
| +      // (see comment to RequiredInputRepresentation). | 
| +      SetFlag(kFlexibleRepresentation); | 
| +    } else { | 
| +      // When compiling stubs we want to set the representation explicitly | 
| +      // so the compilation pipeline can skip the HInferRepresentation phase. | 
| +      set_representation(r); | 
| +    } | 
| SetFlag(kUseGVN); | 
| } | 
|  | 
| virtual Representation RequiredInputRepresentation(int arg_index) { | 
| -    if (key_mode_ == DONT_ALLOW_SMI_KEY || | 
| -        !length()->representation().IsTagged()) { | 
| -      return Representation::Integer32(); | 
| -    } | 
| -    // If the index is tagged and isn't constant, then allow the length | 
| -    // to be tagged, since it is usually already tagged from loading it out of | 
| -    // the length field of a JSArray. This allows for direct comparison without | 
| -    // untagging. | 
| -    if (index()->representation().IsTagged() && !index()->IsConstant()) { | 
| -      return Representation::Tagged(); | 
| -    } | 
| -    // Also allow the length to be tagged if the index is constant, because | 
| -    // it can be tagged to allow direct comparison. | 
| -    if (index()->IsConstant() && | 
| -        index()->representation().IsInteger32() && | 
| -        arg_index == 1) { | 
| -      return Representation::Tagged(); | 
| -    } | 
| -    return Representation::Integer32(); | 
| +    return representation(); | 
| } | 
| virtual Representation observed_input_representation(int index) { | 
| return Representation::Integer32(); | 
| } | 
|  | 
| virtual void PrintDataTo(StringStream* stream); | 
| +  virtual void InferRepresentation(HInferRepresentation* h_infer); | 
|  | 
| HValue* index() { return OperandAt(0); } | 
| HValue* length() { return OperandAt(1); } | 
|  | 
| +  virtual int RedefinedOperandIndex() { return 0; } | 
| + | 
| DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 
|  | 
| protected: | 
| @@ -4433,6 +4452,11 @@ class ArrayInstructionInterface { | 
| virtual bool IsDehoisted() = 0; | 
| virtual void SetDehoisted(bool is_dehoisted) = 0; | 
| virtual ~ArrayInstructionInterface() { }; | 
| + | 
| +  static Representation KeyedAccessIndexRequirement(Representation r) { | 
| +    return r.IsInteger32() ? Representation::Integer32() | 
| +                           : Representation::Tagged(); | 
| +  } | 
| }; | 
|  | 
|  | 
| @@ -4516,7 +4540,10 @@ class HLoadKeyed | 
| return is_external() ? Representation::External() | 
| : Representation::Tagged(); | 
| } | 
| -    if (index == 1) return Representation::Integer32(); | 
| +    if (index == 1) { | 
| +      return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 
| +          OperandAt(1)->representation()); | 
| +    } | 
| return Representation::None(); | 
| } | 
|  | 
| @@ -4731,7 +4758,8 @@ class HStoreKeyed | 
| return is_external() ? Representation::External() | 
| : Representation::Tagged(); | 
| } else if (index == 1) { | 
| -      return Representation::Integer32(); | 
| +      return ArrayInstructionInterface::KeyedAccessIndexRequirement( | 
| +          OperandAt(1)->representation()); | 
| } | 
|  | 
| ASSERT_EQ(index, 2); | 
|  |