| Index: src/hydrogen-check-elimination.cc | 
| diff --git a/src/hydrogen-check-elimination.cc b/src/hydrogen-check-elimination.cc | 
| index d5715a61ecce5059ded5b5bae02d7368b9c0235a..5fdb3e3f3c48fa1260005eeeab7ec7e6ae537ebd 100644 | 
| --- a/src/hydrogen-check-elimination.cc | 
| +++ b/src/hydrogen-check-elimination.cc | 
| @@ -50,7 +50,6 @@ struct HCheckTableEntry { | 
| HValue* object_;  // The object being approximated. NULL => invalid entry. | 
| HInstruction* check_;  // The last check instruction. | 
| MapSet maps_;          // The set of known maps for the object. | 
| -  bool is_stable_; | 
| }; | 
|  | 
|  | 
| @@ -104,10 +103,9 @@ class HCheckTable : public ZoneObject { | 
| } | 
| default: { | 
| // If the instruction changes maps uncontrollably, drop everything. | 
| -        if (instr->CheckChangesFlag(kOsrEntries)) { | 
| -          Reset(); | 
| -        } else if (instr->CheckChangesFlag(kMaps)) { | 
| -          KillUnstableEntries(); | 
| +        if (instr->CheckChangesFlag(kMaps) || | 
| +            instr->CheckChangesFlag(kOsrEntries)) { | 
| +          Kill(); | 
| } | 
| } | 
| // Improvements possible: | 
| @@ -156,7 +154,6 @@ class HCheckTable : public ZoneObject { | 
| if (old_entry->check_ != NULL && | 
| old_entry->check_->block()->Dominates(succ)) { | 
| new_entry->check_ = old_entry->check_; | 
| -        new_entry->is_stable_ = old_entry->is_stable_; | 
| } else { | 
| // Leave it NULL till we meet a new check instruction for this object | 
| // in the control flow. | 
| @@ -178,8 +175,7 @@ class HCheckTable : public ZoneObject { | 
| HCheckTableEntry* pred_entry = copy->Find(phi_operand); | 
| if (pred_entry != NULL) { | 
| // Create an entry for a phi in the table. | 
| -          copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone()), | 
| -                       pred_entry->is_stable_); | 
| +          copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone())); | 
| } | 
| } | 
| } | 
| @@ -197,13 +193,12 @@ class HCheckTable : public ZoneObject { | 
| if (is_true_branch) { | 
| // Learn on the true branch of if(CompareMap(x)). | 
| if (entry == NULL) { | 
| -            copy->Insert(object, cmp, cmp->map(), cmp->is_stable()); | 
| +            copy->Insert(object, cmp, cmp->map()); | 
| } else { | 
| MapSet list = new(phase_->zone()) UniqueSet<Map>(); | 
| list->Add(cmp->map(), phase_->zone()); | 
| entry->maps_ = list; | 
| entry->check_ = cmp; | 
| -            entry->is_stable_ = cmp->is_stable(); | 
| } | 
| } else { | 
| // Learn on the false branch of if(CompareMap(x)). | 
| @@ -222,10 +217,10 @@ class HCheckTable : public ZoneObject { | 
| HCheckTableEntry* re = copy->Find(right); | 
| if (le == NULL) { | 
| if (re != NULL) { | 
| -            copy->Insert(left, NULL, re->maps_->Copy(zone), re->is_stable_); | 
| +            copy->Insert(left, NULL, re->maps_->Copy(zone)); | 
| } | 
| } else if (re == NULL) { | 
| -          copy->Insert(right, NULL, le->maps_->Copy(zone), le->is_stable_); | 
| +          copy->Insert(right, NULL, le->maps_->Copy(zone)); | 
| } else { | 
| MapSet intersect = le->maps_->Intersect(re->maps_, zone); | 
| le->maps_ = intersect; | 
| @@ -252,7 +247,8 @@ class HCheckTable : public ZoneObject { | 
| HBasicBlock* pred_block, Zone* zone) { | 
| if (that->size_ == 0) { | 
| // If the other state is empty, simply reset. | 
| -      Reset(); | 
| +      size_ = 0; | 
| +      cursor_ = 0; | 
| } else { | 
| int pred_index = succ->PredecessorIndexOf(pred_block); | 
| bool compact = false; | 
| @@ -275,8 +271,6 @@ class HCheckTable : public ZoneObject { | 
| } else { | 
| this_entry->maps_ = | 
| this_entry->maps_->Union(that_entry->maps_, phase_->zone()); | 
| -          this_entry->is_stable_ = | 
| -              this_entry->is_stable_ && that_entry->is_stable_; | 
| if (this_entry->check_ != that_entry->check_) { | 
| this_entry->check_ = NULL; | 
| } | 
| @@ -357,8 +351,7 @@ class HCheckTable : public ZoneObject { | 
| } | 
| } else { | 
| // No entry; insert a new one. | 
| -      Insert(object, instr, instr->map_set().Copy(phase_->zone()), | 
| -             instr->is_stable()); | 
| +      Insert(object, instr, instr->map_set().Copy(phase_->zone())); | 
| } | 
| } | 
|  | 
| @@ -420,8 +413,7 @@ class HCheckTable : public ZoneObject { | 
| } | 
| } else { | 
| // No prior information. | 
| -      // TODO(verwaest): Tag map constants with stability. | 
| -      Insert(object, instr, map, false); | 
| +      Insert(object, instr, map); | 
| } | 
| } | 
|  | 
| @@ -438,14 +430,12 @@ class HCheckTable : public ZoneObject { | 
| if (instr->has_transition()) { | 
| // This store transitions the object to a new map. | 
| Kill(object); | 
| -      Insert(object, NULL, MapConstant(instr->transition()), | 
| -             instr->is_stable()); | 
| +      Insert(object, NULL, MapConstant(instr->transition())); | 
| } else if (IsMapAccess(instr->access())) { | 
| // This is a store directly to the map field of the object. | 
| Kill(object); | 
| if (!instr->value()->IsConstant()) return; | 
| -      // TODO(verwaest): Tag with stability. | 
| -      Insert(object, NULL, MapConstant(instr->value()), false); | 
| +      Insert(object, NULL, MapConstant(instr->value())); | 
| } else { | 
| // If the instruction changes maps, it should be handled above. | 
| CHECK(!instr->CheckChangesFlag(kMaps)); | 
| @@ -495,26 +485,12 @@ class HCheckTable : public ZoneObject { | 
| } | 
| } | 
|  | 
| -  // Reset the table. | 
| -  void Reset() { | 
| +  // Kill everything in the table. | 
| +  void Kill() { | 
| size_ = 0; | 
| cursor_ = 0; | 
| } | 
|  | 
| -  // Kill everything in the table. | 
| -  void KillUnstableEntries() { | 
| -    bool compact = false; | 
| -    for (int i = 0; i < size_; i++) { | 
| -      HCheckTableEntry* entry = &entries_[i]; | 
| -      ASSERT(entry->object_ != NULL); | 
| -      if (!entry->is_stable_) { | 
| -        entry->object_ = NULL; | 
| -        compact = true; | 
| -      } | 
| -    } | 
| -    if (compact) Compact(); | 
| -  } | 
| - | 
| // Kill everything in the table that may alias {object}. | 
| void Kill(HValue* object) { | 
| bool compact = false; | 
| @@ -596,24 +572,17 @@ class HCheckTable : public ZoneObject { | 
| return entry == NULL ? NULL : entry->maps_; | 
| } | 
|  | 
| -  void Insert(HValue* object, | 
| -              HInstruction* check, | 
| -              Unique<Map> map, | 
| -              bool is_stable) { | 
| +  void Insert(HValue* object, HInstruction* check, Unique<Map> map) { | 
| MapSet list = new(phase_->zone()) UniqueSet<Map>(); | 
| list->Add(map, phase_->zone()); | 
| -    Insert(object, check, list, is_stable); | 
| +    Insert(object, check, list); | 
| } | 
|  | 
| -  void Insert(HValue* object, | 
| -              HInstruction* check, | 
| -              MapSet maps, | 
| -              bool is_stable) { | 
| +  void Insert(HValue* object, HInstruction* check, MapSet maps) { | 
| HCheckTableEntry* entry = &entries_[cursor_++]; | 
| entry->object_ = object; | 
| entry->check_ = check; | 
| entry->maps_ = maps; | 
| -    entry->is_stable_ = is_stable; | 
| // If the table becomes full, wrap around and overwrite older entries. | 
| if (cursor_ == kMaxTrackedObjects) cursor_ = 0; | 
| if (size_ < kMaxTrackedObjects) size_++; | 
| @@ -643,7 +612,8 @@ class HCheckTable : public ZoneObject { | 
| class HCheckMapsEffects : public ZoneObject { | 
| public: | 
| explicit HCheckMapsEffects(Zone* zone) | 
| -    : stores_(5, zone) { } | 
| +    : maps_stored_(false), | 
| +      stores_(5, zone) { } | 
|  | 
| inline bool Disabled() { | 
| return false;  // Effects are _not_ disabled. | 
| @@ -651,22 +621,27 @@ class HCheckMapsEffects : public ZoneObject { | 
|  | 
| // Process a possibly side-effecting instruction. | 
| void Process(HInstruction* instr, Zone* zone) { | 
| -    if (instr->IsStoreNamedField()) { | 
| -      stores_.Add(HStoreNamedField::cast(instr), zone); | 
| -    } else { | 
| -      flags_.Add(instr->ChangesFlags()); | 
| +    switch (instr->opcode()) { | 
| +      case HValue::kStoreNamedField: { | 
| +        stores_.Add(HStoreNamedField::cast(instr), zone); | 
| +        break; | 
| +      } | 
| +      case HValue::kOsrEntry: { | 
| +        // Kill everything. Loads must not be hoisted past the OSR entry. | 
| +        maps_stored_ = true; | 
| +      } | 
| +      default: { | 
| +        maps_stored_ |= (instr->CheckChangesFlag(kMaps) | | 
| +                         instr->CheckChangesFlag(kElementsKind)); | 
| +      } | 
| } | 
| } | 
|  | 
| // Apply these effects to the given check elimination table. | 
| void Apply(HCheckTable* table) { | 
| -    if (flags_.Contains(kOsrEntries)) { | 
| -      table->Reset(); | 
| -      return; | 
| -    } | 
| -    if (flags_.Contains(kMaps) || flags_.Contains(kElementsKind)) { | 
| +    if (maps_stored_) { | 
| // Uncontrollable map modifications; kill everything. | 
| -      table->KillUnstableEntries(); | 
| +      table->Kill(); | 
| return; | 
| } | 
|  | 
| @@ -681,14 +656,14 @@ class HCheckMapsEffects : public ZoneObject { | 
|  | 
| // Union these effects with the other effects. | 
| void Union(HCheckMapsEffects* that, Zone* zone) { | 
| -    flags_.Add(that->flags_); | 
| +    maps_stored_ |= that->maps_stored_; | 
| for (int i = 0; i < that->stores_.length(); i++) { | 
| stores_.Add(that->stores_[i], zone); | 
| } | 
| } | 
|  | 
| private: | 
| -  GVNFlagSet flags_; | 
| +  bool maps_stored_ : 1; | 
| ZoneList<HStoreNamedField*> stores_; | 
| }; | 
|  | 
| @@ -705,7 +680,7 @@ void HCheckEliminationPhase::Run() { | 
| } else { | 
| // Perform only local analysis. | 
| for (int i = 0; i < graph()->blocks()->length(); i++) { | 
| -      table->Reset(); | 
| +      table->Kill(); | 
| engine.AnalyzeOneBlock(graph()->blocks()->at(i), table); | 
| } | 
| } | 
|  |