| Index: src/hydrogen-instructions.cc | 
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc | 
| index 43aeeed396400c12da23250289dd540f5887d314..a5f3a2476b738117779486bb8ea934adddcf3f06 100644 | 
| --- a/src/hydrogen-instructions.cc | 
| +++ b/src/hydrogen-instructions.cc | 
| @@ -786,6 +786,33 @@ void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 
| } | 
|  | 
|  | 
| +void HCheckMapValue::PrintDataTo(StringStream* stream) { | 
| +  value()->PrintNameTo(stream); | 
| +  stream->Add(" "); | 
| +  map()->PrintNameTo(stream); | 
| +} | 
| + | 
| + | 
| +void HForInPrepareMap::PrintDataTo(StringStream* stream) { | 
| +  enumerable()->PrintNameTo(stream); | 
| +} | 
| + | 
| + | 
| +void HForInCacheArray::PrintDataTo(StringStream* stream) { | 
| +  enumerable()->PrintNameTo(stream); | 
| +  stream->Add(" "); | 
| +  keys()->PrintNameTo(stream); | 
| +  stream->Add("[%d]", idx_); | 
| +} | 
| + | 
| + | 
| +void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { | 
| +  object()->PrintNameTo(stream); | 
| +  stream->Add(" "); | 
| +  index()->PrintNameTo(stream); | 
| +} | 
| + | 
| + | 
| HValue* HConstant::Canonicalize() { | 
| return HasNoUses() && !IsBlockEntry() ? NULL : this; | 
| } | 
| @@ -1519,10 +1546,15 @@ void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) { | 
|  | 
|  | 
| bool HLoadKeyedFastElement::RequiresHoleCheck() { | 
| +  if (hole_check_mode_ == OMIT_HOLE_CHECK) { | 
| +    return false; | 
| +  } | 
| + | 
| for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 
| HValue* use = it.value(); | 
| if (!use->IsChange()) return true; | 
| } | 
| + | 
| return false; | 
| } | 
|  | 
| @@ -1543,6 +1575,39 @@ void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) { | 
| } | 
|  | 
|  | 
| +HValue* HLoadKeyedGeneric::Canonicalize() { | 
| +  // Recognize generic keyed loads that use property name generated | 
| +  // by for-in statement as a key and rewrite them into fast property load | 
| +  // by index. | 
| +  if (key()->IsLoadKeyedFastElement()) { | 
| +    HLoadKeyedFastElement* key_load = HLoadKeyedFastElement::cast(key()); | 
| +    if (key_load->object()->IsForInCacheArray()) { | 
| +      HForInCacheArray* names_cache = | 
| +          HForInCacheArray::cast(key_load->object()); | 
| + | 
| +      if (names_cache->enumerable() == object()) { | 
| +        HForInCacheArray* index_cache = | 
| +            names_cache->index_cache(); | 
| +        HCheckMapValue* map_check = | 
| +            new(block()->zone()) HCheckMapValue(object(), names_cache->keys()); | 
| +        HInstruction* index = new(block()->zone()) HLoadKeyedFastElement( | 
| +            index_cache, | 
| +            key_load->key(), | 
| +            HLoadKeyedFastElement::OMIT_HOLE_CHECK); | 
| +        HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex( | 
| +            object(), index); | 
| +        map_check->InsertBefore(this); | 
| +        index->InsertBefore(this); | 
| +        load->InsertBefore(this); | 
| +        return load; | 
| +      } | 
| +    } | 
| +  } | 
| + | 
| +  return this; | 
| +} | 
| + | 
| + | 
| void HLoadKeyedSpecializedArrayElement::PrintDataTo( | 
| StringStream* stream) { | 
| external_pointer()->PrintNameTo(stream); | 
|  |