Revision: 21133
Author:   [email protected]
Date:     Mon May  5 06:53:19 2014 UTC
Log:      Various cleanups in check elimination.

- Move IsMapAccess() to HObjectAccess.
- Collect the actual objects instead of HStoreNamedFields in
  effects, and also consider HTransitionElementsKind.
- Fix ownership of HCheckMaps::maps() and HLoadNamedField::maps().
- Avoid heavy copying of the same map sets all the time during
  check elimination, and do something useful with the memory
  instead by slightly bumping the maximum number of tracked
  objects.
- Slightly optimize UniqueSet::Contains().

[email protected]

Review URL: https://codereview.chromium.org/264693011
http://code.google.com/p/v8/source/detail?r=21133

Modified:
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc
 /branches/bleeding_edge/src/hydrogen-check-elimination.cc
 /branches/bleeding_edge/src/hydrogen-escape-analysis.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen-load-elimination.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/unique.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri May 2 08:08:23 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon May 5 06:53:19 2014 UTC
@@ -5155,15 +5155,15 @@
     __ bind(deferred->check_maps());
   }

-  const UniqueSet<Map>* map_set = instr->hydrogen()->map_set();
+  const UniqueSet<Map>* maps = instr->hydrogen()->maps();
   Label success;
-  for (int i = 0; i < map_set->size() - 1; i++) {
-    Handle<Map> map = map_set->at(i).handle();
+  for (int i = 0; i < maps->size() - 1; i++) {
+    Handle<Map> map = maps->at(i).handle();
     __ CompareMap(map_reg, map, &success);
     __ b(eq, &success);
   }

-  Handle<Map> map = map_set->at(map_set->size() - 1).handle();
+  Handle<Map> map = maps->at(maps->size() - 1).handle();
   __ CompareMap(map_reg, map, &success);
   if (instr->hydrogen()->has_migration_target()) {
     __ b(ne, deferred->entry());
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Fri May 2 08:08:23 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Mon May 5 06:53:19 2014 UTC
@@ -2132,14 +2132,14 @@
     __ Bind(deferred->check_maps());
   }

-  const UniqueSet<Map>* map_set = instr->hydrogen()->map_set();
+  const UniqueSet<Map>* maps = instr->hydrogen()->maps();
   Label success;
-  for (int i = 0; i < map_set->size() - 1; i++) {
-    Handle<Map> map = map_set->at(i).handle();
+  for (int i = 0; i < maps->size() - 1; i++) {
+    Handle<Map> map = maps->at(i).handle();
     __ CompareMap(map_reg, map);
     __ B(eq, &success);
   }
-  Handle<Map> map = map_set->at(map_set->size() - 1).handle();
+  Handle<Map> map = maps->at(maps->size() - 1).handle();
   __ CompareMap(map_reg, map);

   // We didn't match a map.
=======================================
--- /branches/bleeding_edge/src/hydrogen-check-elimination.cc Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-check-elimination.cc Mon May 5 06:53:19 2014 UTC
@@ -21,7 +21,7 @@
 namespace v8 {
 namespace internal {

-typedef UniqueSet<Map>* MapSet;
+typedef const UniqueSet<Map>* MapSet;

 struct HCheckTableEntry {
HValue* object_; // The object being approximated. NULL => invalid entry.
@@ -34,7 +34,7 @@
 // set of known maps for each object.
 class HCheckTable : public ZoneObject {
  public:
-  static const int kMaxTrackedObjects = 10;
+  static const int kMaxTrackedObjects = 16;

   explicit HCheckTable(HCheckEliminationPhase* phase)
     : phase_(phase),
@@ -80,7 +80,8 @@
       }
       default: {
         // If the instruction changes maps uncontrollably, drop everything.
-        if (instr->CheckChangesFlag(kMaps) ||
+        if (instr->CheckChangesFlag(kElementsKind) ||
+            instr->CheckChangesFlag(kMaps) ||
             instr->CheckChangesFlag(kOsrEntries)) {
           Kill();
         }
@@ -127,13 +128,13 @@
  private:
   // Copy state to successor block.
HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone* zone) {
-    HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_);
+    HCheckTable* copy = new(zone) HCheckTable(phase_);
     for (int i = 0; i < size_; i++) {
       HCheckTableEntry* old_entry = &entries_[i];
       ASSERT(old_entry->maps_->size() > 0);
       HCheckTableEntry* new_entry = &copy->entries_[i];
       new_entry->object_ = old_entry->object_;
-      new_entry->maps_ = old_entry->maps_->Copy(phase_->zone());
+      new_entry->maps_ = old_entry->maps_;
// Keep the check if the existing check's block dominates the successor.
       if (old_entry->check_ != NULL &&
           old_entry->check_->block()->Dominates(succ)) {
@@ -159,7 +160,7 @@
         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()));
+          copy->Insert(phi, NULL, pred_entry->maps_);
         }
       }
     }
@@ -179,15 +180,15 @@
           if (entry == NULL) {
             copy->Insert(object, cmp, cmp->map());
           } else {
-            MapSet list = new(phase_->zone()) UniqueSet<Map>();
-            list->Add(cmp->map(), phase_->zone());
-            entry->maps_ = list;
+            entry->maps_ = new(zone) UniqueSet<Map>(cmp->map(), zone);
             entry->check_ = cmp;
           }
         } else {
           // Learn on the false branch of if(CompareMap(x)).
           if (entry != NULL) {
-            entry->maps_->Remove(cmp->map());
+            UniqueSet<Map>* maps = entry->maps_->Copy(zone);
+            maps->Remove(cmp->map());
+            entry->maps_ = maps;
           }
         }
         learned = true;
@@ -201,14 +202,12 @@
         HCheckTableEntry* re = copy->Find(right);
         if (le == NULL) {
           if (re != NULL) {
-            copy->Insert(left, NULL, re->maps_->Copy(zone));
+            copy->Insert(left, NULL, re->maps_);
           }
         } else if (re == NULL) {
-          copy->Insert(right, NULL, le->maps_->Copy(zone));
+          copy->Insert(right, NULL, le->maps_);
         } else {
-          MapSet intersect = le->maps_->Intersect(re->maps_, zone);
-          le->maps_ = intersect;
-          re->maps_ = intersect->Copy(zone);
+          le->maps_ = re->maps_ = le->maps_->Intersect(re->maps_, zone);
         }
         learned = true;
       }
@@ -254,7 +253,7 @@
           compact = true;
         } else {
           this_entry->maps_ =
-              this_entry->maps_->Union(that_entry->maps_, phase_->zone());
+              this_entry->maps_->Union(that_entry->maps_, zone);
           if (this_entry->check_ != that_entry->check_) {
             this_entry->check_ = NULL;
           }
@@ -278,7 +277,7 @@
     if (entry != NULL) {
       // entry found;
       MapSet a = entry->maps_;
-      const UniqueSet<Map>* i = instr->map_set();
+      const UniqueSet<Map>* i = instr->maps();
       if (a->IsSubset(i)) {
         // The first check is more strict; the second is redundant.
         if (entry->check_ != NULL) {
@@ -297,7 +296,8 @@
         }
         return;
       }
-      MapSet intersection = i->Intersect(a, phase_->zone());
+      HGraph* graph = instr->block()->graph();
+      MapSet intersection = i->Intersect(a, graph->zone());
       if (intersection->size() == 0) {
         // Intersection is empty; probably megamorphic, which is likely to
         // deopt anyway, so just leave things as they are.
@@ -307,7 +307,6 @@
         entry->maps_ = intersection;
         if (intersection->size() != i->size()) {
           // Narrow set of maps in the second check maps instruction.
-          HGraph* graph = instr->block()->graph();
           if (entry->check_ != NULL &&
               entry->check_->block() == instr->block() &&
               entry->check_->IsCheckMaps()) {
@@ -317,7 +316,7 @@
             TRACE(("CheckMaps #%d at B%d narrowed\n", check->id(),
                 check->block()->block_id()));
             // Update map set and ensure that the check is alive.
-            check->set_map_set(intersection, graph->zone());
+            check->set_maps(intersection);
             check->ClearFlag(HValue::kIsDead);
             TRACE(("Replacing redundant CheckMaps #%d at B%d with #%d\n",
instr->id(), instr->block()->block_id(), entry->check_->id()));
@@ -325,7 +324,7 @@
           } else {
             TRACE(("CheckMaps #%d at B%d narrowed\n", instr->id(),
                 instr->block()->block_id()));
-            instr->set_map_set(intersection, graph->zone());
+            instr->set_maps(intersection);
             entry->check_ = instr;
           }

@@ -337,16 +336,16 @@
       }
     } else {
       // No entry; insert a new one.
-      Insert(object, instr, instr->map_set()->Copy(phase_->zone()));
+      Insert(object, instr, instr->maps());
     }
   }

   void ReduceLoadNamedField(HLoadNamedField* instr) {
     // Reduce a load of the map field when it is known to be a constant.
-    if (!IsMapAccess(instr->access())) {
+    if (!instr->access().IsMap()) {
       // Check if we introduce field maps here.
-      if (instr->map_set()->size() != 0) {
-        Insert(instr, instr, instr->map_set()->Copy(phase_->zone()));
+      if (instr->maps()->size() != 0) {
+        Insert(instr, instr, instr->maps());
       }
       return;
     }
@@ -371,9 +370,8 @@

     HCheckTableEntry* entry = Find(object);
     if (entry != NULL) {
-      MapSet maps = entry->maps_;
-      if (maps->Contains(map)) {
-        if (maps->size() == 1) {
+      if (entry->maps_->Contains(map)) {
+        if (entry->maps_->size() == 1) {
           // Object is known to have exactly this map.
           if (entry->check_ != NULL) {
             instr->DeleteAndReplaceWith(entry->check_);
@@ -386,8 +384,7 @@
           INC_STAT(removed_);
         } else {
           // Only one map survives the check.
-          maps->Clear();
-          maps->Add(map, phase_->zone());
+          entry->maps_ = new(zone()) UniqueSet<Map>(map, zone());
           entry->check_ = instr;
         }
       }
@@ -411,7 +408,7 @@
       // This store transitions the object to a new map.
       Kill(object);
       Insert(object, NULL, MapConstant(instr->transition()));
-    } else if (IsMapAccess(instr->access())) {
+    } else if (instr->access().IsMap()) {
       // This is a store directly to the map field of the object.
       Kill(object);
       if (!instr->value()->IsConstant()) return;
@@ -455,7 +452,7 @@
     if (maps_left == NULL) return;
     MapSet maps_right = FindMaps(instr->right()->ActualValue());
     if (maps_right == NULL) return;
-    MapSet intersection = maps_left->Intersect(maps_right, phase_->zone());
+    MapSet intersection = maps_left->Intersect(maps_right, zone());
     if (intersection->size() > 0) return;

TRACE(("Marking redundant CompareObjectEqAndBranch #%d at B%d as false\n",
@@ -468,13 +465,15 @@
   }

   void ReduceTransitionElementsKind(HTransitionElementsKind* instr) {
-    MapSet maps = FindMaps(instr->object()->ActualValue());
+    HCheckTableEntry* entry = Find(instr->object()->ActualValue());
// Can only learn more about an object that already has a known set of maps.
-    if (maps == NULL) return;
-    if (maps->Contains(instr->original_map())) {
+    if (entry == NULL) return;
+    if (entry->maps_->Contains(instr->original_map())) {
       // If the object has the original map, it will be transitioned.
+      UniqueSet<Map>* maps = entry->maps_->Copy(zone());
       maps->Remove(instr->original_map());
-      maps->Add(instr->transitioned_map(), phase_->zone());
+      maps->Add(instr->transitioned_map(), zone());
+      entry->maps_ = maps;
     } else {
// Object does not have the given map, thus the transition is redundant.
       instr->DeleteAndReplaceWith(instr->object());
@@ -575,9 +574,7 @@
   }

   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);
+    Insert(object, check, new(zone()) UniqueSet<Map>(map, zone()));
   }

   void Insert(HValue* object, HInstruction* check, MapSet maps) {
@@ -589,14 +586,12 @@
     if (cursor_ == kMaxTrackedObjects) cursor_ = 0;
     if (size_ < kMaxTrackedObjects) size_++;
   }
-
-  bool IsMapAccess(HObjectAccess access) {
-    return access.IsInobject() && access.offset() == JSObject::kMapOffset;
-  }

   Unique<Map> MapConstant(HValue* value) {
     return Unique<Map>::cast(HConstant::cast(value)->GetUnique());
   }
+
+  Zone* zone() const { return phase_->zone(); }

   friend class HCheckMapsEffects;
   friend class HCheckEliminationPhase;
@@ -614,26 +609,28 @@
 class HCheckMapsEffects : public ZoneObject {
  public:
   explicit HCheckMapsEffects(Zone* zone)
-    : maps_stored_(false),
-      stores_(5, zone) { }
+      : objects_(0, zone), maps_stored_(false) {}

-  inline bool Disabled() {
-    return false;  // Effects are _not_ disabled.
-  }
+  // Effects are _not_ disabled.
+  inline bool Disabled() const { return false; }

   // Process a possibly side-effecting instruction.
   void Process(HInstruction* instr, Zone* zone) {
     switch (instr->opcode()) {
       case HValue::kStoreNamedField: {
-        stores_.Add(HStoreNamedField::cast(instr), zone);
+        HStoreNamedField* store = HStoreNamedField::cast(instr);
+        if (store->access().IsMap() && store->has_transition()) {
+          objects_.Add(store->object(), zone);
+        }
         break;
       }
-      case HValue::kOsrEntry: {
-        // Kill everything. Loads must not be hoisted past the OSR entry.
-        maps_stored_ = true;
+      case HValue::kTransitionElementsKind: {
+        objects_.Add(HTransitionElementsKind::cast(instr)->object(), zone);
+        break;
       }
       default: {
         maps_stored_ |= (instr->CheckChangesFlag(kMaps) |
+                         instr->CheckChangesFlag(kOsrEntries) |
                          instr->CheckChangesFlag(kElementsKind));
       }
     }
@@ -647,26 +644,23 @@
       return;
     }

-    // Kill maps for each store contained in these effects.
-    for (int i = 0; i < stores_.length(); i++) {
-      HStoreNamedField* s = stores_[i];
-      if (table->IsMapAccess(s->access()) || s->has_transition()) {
-        table->Kill(s->object()->ActualValue());
-      }
+    // Kill maps for each object contained in these effects.
+    for (int i = 0; i < objects_.length(); ++i) {
+      table->Kill(objects_[i]->ActualValue());
     }
   }

   // Union these effects with the other effects.
   void Union(HCheckMapsEffects* that, Zone* zone) {
     maps_stored_ |= that->maps_stored_;
-    for (int i = 0; i < that->stores_.length(); i++) {
-      stores_.Add(that->stores_[i], zone);
+    for (int i = 0; i < that->objects_.length(); ++i) {
+      objects_.Add(that->objects_[i], zone);
     }
   }

  private:
+  ZoneList<HValue*> objects_;
   bool maps_stored_ : 1;
-  ZoneList<HStoreNamedField*> stores_;
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Mon May 5 06:53:19 2014 UTC
@@ -132,7 +132,7 @@
   // TODO(mstarzinger): This will narrow a map check against a set of maps
   // down to the first element in the set. Revisit and fix this.
   HCheckValue* check = HCheckValue::New(
-      zone, NULL, value, mapcheck->first_map(), false);
+      zone, NULL, value, mapcheck->maps()->at(0), false);
   check->InsertBefore(mapcheck);
   return check;
 }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Fri May 2 05:59:07 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Mon May 5 06:53:19 2014 UTC
@@ -1671,9 +1671,9 @@

 void HCheckMaps::PrintDataTo(StringStream* stream) {
   value()->PrintNameTo(stream);
-  stream->Add(" [%p", *map_set_.at(0).handle());
-  for (int i = 1; i < map_set_.size(); ++i) {
-    stream->Add(",%p", *map_set_.at(i).handle());
+  stream->Add(" [%p", *maps()->at(0).handle());
+  for (int i = 1; i < maps()->size(); ++i) {
+    stream->Add(",%p", *maps()->at(i).handle());
   }
   stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : "");
 }
@@ -3362,10 +3362,10 @@
   object()->PrintNameTo(stream);
   access_.PrintTo(stream);

-  if (map_set_.size() != 0) {
-    stream->Add(" [%p", *map_set_.at(0).handle());
-    for (int i = 1; i < map_set_.size(); ++i) {
-      stream->Add(",%p", *map_set_.at(i).handle());
+  if (maps()->size() != 0) {
+    stream->Add(" [%p", *maps()->at(0).handle());
+    for (int i = 1; i < maps()->size(); ++i) {
+      stream->Add(",%p", *maps()->at(i).handle());
     }
     stream->Add("]");
   }
@@ -3383,8 +3383,9 @@
                             Handle<Map> map,
                             CompilationInfo* info,
                             HValue* typecheck) {
-  HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
-  check_map->Add(map, zone);
+ HCheckMaps* check_map = new(zone) HCheckMaps(value, new(zone) UniqueSet<Map>(
+          Unique<Map>::CreateImmovable(map), zone), typecheck);
+  // TODO(bmeurer): Get rid of this shit!
   if (map->CanOmitMapChecks() &&
       value->IsConstant() &&
       HConstant::cast(value)->HasMap(map)) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 2 06:37:54 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon May 5 06:53:19 2014 UTC
@@ -2747,13 +2747,13 @@
                          Handle<Map> map, CompilationInfo* info,
                          HValue* typecheck = NULL);
   static HCheckMaps* New(Zone* zone, HValue* context,
-                         HValue* value, SmallMapList* maps,
+                         HValue* value, SmallMapList* map_list,
                          HValue* typecheck = NULL) {
-    HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
-    for (int i = 0; i < maps->length(); i++) {
-      check_map->Add(maps->at(i), zone);
+ UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone);
+    for (int i = 0; i < map_list->length(); ++i) {
+      maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone);
     }
-    return check_map;
+    return new(zone) HCheckMaps(value, maps, typecheck);
   }

   bool CanOmitMapChecks() { return omit_; }
@@ -2767,15 +2767,8 @@
   HValue* value() { return OperandAt(0); }
   HValue* typecheck() { return OperandAt(1); }

-  Unique<Map> first_map() const { return map_set_.at(0); }
-  const UniqueSet<Map>* map_set() const { return &map_set_; }
-
-  void set_map_set(UniqueSet<Map>* maps, Zone *zone) {
-    map_set_.Clear();
-    for (int i = 0; i < maps->size(); i++) {
-      map_set_.Add(maps->at(i), zone);
-    }
-  }
+  const UniqueSet<Map>* maps() const { return maps_; }
+  void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }

   bool has_migration_target() const {
     return has_migration_target_;
@@ -2785,37 +2778,36 @@

  protected:
   virtual bool DataEquals(HValue* other) V8_OVERRIDE {
-    return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_);
+    return this->maps()->Equals(HCheckMaps::cast(other)->maps());
   }

   virtual int RedefinedOperandIndex() { return 0; }

  private:
-  void Add(Handle<Map> map, Zone* zone) {
-    map_set_.Add(Unique<Map>(map), zone);
-    SetDependsOnFlag(kMaps);
-    SetDependsOnFlag(kElementsKind);
-
-    if (!has_migration_target_ && map->is_migration_target()) {
-      has_migration_target_ = true;
-      SetChangesFlag(kNewSpacePromotion);
-    }
-  }
-
   // Clients should use one of the static New* methods above.
-  HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
-      : HTemplateInstruction<2>(value->type()),
+  HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
+      : HTemplateInstruction<2>(value->type()), maps_(maps),
         omit_(false), has_migration_target_(false) {
+    ASSERT_NE(0, maps->size());
     SetOperandAt(0, value);
     // Use the object value for the dependency if NULL is passed.
-    SetOperandAt(1, typecheck != NULL ? typecheck : value);
+    SetOperandAt(1, typecheck ? typecheck : value);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
+    SetDependsOnFlag(kMaps);
+    SetDependsOnFlag(kElementsKind);
+    for (int i = 0; i < maps->size(); ++i) {
+      if (maps->at(i).handle()->is_migration_target()) {
+        SetChangesFlag(kNewSpacePromotion);
+        has_migration_target_ = true;
+        break;
+      }
+    }
   }

-  bool omit_;
-  bool has_migration_target_;
-  UniqueSet<Map> map_set_;
+  const UniqueSet<Map>* maps_;
+  bool omit_ : 1;
+  bool has_migration_target_ : 1;
 };


@@ -5829,6 +5821,10 @@
   inline bool IsStringLength() const {
     return portion() == kStringLengths;
   }
+
+  inline bool IsMap() const {
+    return portion() == kMaps;
+  }

   inline int offset() const {
     return OffsetField::decode(value_);
@@ -6142,23 +6138,27 @@

 class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
  public:
-  DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HValue*,
-                                 HObjectAccess);
+  static HLoadNamedField* New(Zone* zone, HValue* context,
+                              HValue* object, HValue* dependency,
+                              HObjectAccess access) {
+    return new(zone) HLoadNamedField(
+        object, dependency, access, new(zone) UniqueSet<Map>());
+  }
   static HLoadNamedField* New(Zone* zone, HValue* context,
                               HValue* object, HValue* dependency,
-                              HObjectAccess access, SmallMapList* maps,
+                              HObjectAccess access, SmallMapList* map_list,
                               CompilationInfo* info) {
-    HLoadNamedField* load_named_field = HLoadNamedField::New(
-        zone, context, object, dependency, access);
-    for (int i = 0; i < maps->length(); ++i) {
-      Handle<Map> map(maps->at(i));
-      load_named_field->map_set_.Add(Unique<Map>(map), zone);
+ UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone);
+    for (int i = 0; i < map_list->length(); ++i) {
+      Handle<Map> map = map_list->at(i);
+      maps->Add(Unique<Map>::CreateImmovable(map), zone);
+      // TODO(bmeurer): Get rid of this shit!
       if (map->CanTransition()) {
         Map::AddDependentCompilationInfo(
             map, DependentCode::kPrototypeCheckGroup, info);
       }
     }
-    return load_named_field;
+    return new(zone) HLoadNamedField(object, dependency, access, maps);
   }

   HValue* object() { return OperandAt(0); }
@@ -6172,7 +6172,7 @@
       return access_.representation();
   }

-  const UniqueSet<Map>* map_set() const { return &map_set_; }
+  const UniqueSet<Map>* maps() const { return maps_; }

virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
   virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
@@ -6193,15 +6193,15 @@
  protected:
   virtual bool DataEquals(HValue* other) V8_OVERRIDE {
     HLoadNamedField* b = HLoadNamedField::cast(other);
- return access_.Equals(b->access_) && this->map_set_.Equals(&b->map_set_);
+    return access_.Equals(b->access_) && this->maps()->Equals(b->maps());
   }

  private:
   HLoadNamedField(HValue* object,
                   HValue* dependency,
                   HObjectAccess access,
-                  Handle<Map> map = Handle<Map>::null())
-      : access_(access) {
+                  const UniqueSet<Map>* maps)
+      : access_(access), maps_(maps) {
     ASSERT(object != NULL);
     SetOperandAt(0, object);
     SetOperandAt(1, dependency != NULL ? dependency : object);
@@ -6235,7 +6235,7 @@
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }

   HObjectAccess access_;
-  UniqueSet<Map> map_set_;
+  const UniqueSet<Map>* maps_;
 };


=======================================
--- /branches/bleeding_edge/src/hydrogen-load-elimination.cc Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-load-elimination.cc Mon May 5 06:53:19 2014 UTC
@@ -57,8 +57,8 @@
             result->type().Equals(instr->type()) &&
             result->representation().Equals(instr->representation()) &&
             (!result->IsLoadNamedField() ||
-             HLoadNamedField::cast(instr)->map_set()->IsSubset(
-                 HLoadNamedField::cast(result)->map_set()))) {
+             HLoadNamedField::cast(instr)->maps()->IsSubset(
+                 HLoadNamedField::cast(result)->maps()))) {
           // The load can be replaced with a previous load or a value.
           TRACE(("  replace L%d -> v%d\n", instr->id(), result->id()));
           instr->DeleteAndReplaceWith(result);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri May 2 08:08:23 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon May 5 06:53:19 2014 UTC
@@ -5606,15 +5606,15 @@
     __ bind(deferred->check_maps());
   }

-  const UniqueSet<Map>* map_set = instr->hydrogen()->map_set();
+  const UniqueSet<Map>* maps = instr->hydrogen()->maps();
   Label success;
-  for (int i = 0; i < map_set->size() - 1; i++) {
-    Handle<Map> map = map_set->at(i).handle();
+  for (int i = 0; i < maps->size() - 1; i++) {
+    Handle<Map> map = maps->at(i).handle();
     __ CompareMap(reg, map);
     __ j(equal, &success, Label::kNear);
   }

-  Handle<Map> map = map_set->at(map_set->size() - 1).handle();
+  Handle<Map> map = maps->at(maps->size() - 1).handle();
   __ CompareMap(reg, map);
   if (instr->hydrogen()->has_migration_target()) {
     __ j(not_equal, deferred->entry());
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Fri May 2 08:08:23 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Mon May 5 06:53:19 2014 UTC
@@ -5177,13 +5177,13 @@
     __ bind(deferred->check_maps());
   }

-  const UniqueSet<Map>* map_set = instr->hydrogen()->map_set();
+  const UniqueSet<Map>* maps = instr->hydrogen()->maps();
   Label success;
-  for (int i = 0; i < map_set->size() - 1; i++) {
-    Handle<Map> map = map_set->at(i).handle();
+  for (int i = 0; i < maps->size() - 1; i++) {
+    Handle<Map> map = maps->at(i).handle();
     __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
   }
-  Handle<Map> map = map_set->at(map_set->size() - 1).handle();
+  Handle<Map> map = maps->at(maps->size() - 1).handle();
   // Do the CompareMap() directly within the Branch() and DeoptimizeIf().
   if (instr->hydrogen()->has_migration_target()) {
     __ Branch(deferred->entry(), ne, map_reg, Operand(map));
=======================================
--- /branches/bleeding_edge/src/unique.h        Tue Apr 29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/unique.h        Mon May  5 06:53:19 2014 UTC
@@ -133,6 +133,19 @@
  public:
   // Constructor. A new set will be empty.
   UniqueSet() : size_(0), capacity_(0), array_(NULL) { }
+
+  // Capacity constructor. A new set will be empty.
+  UniqueSet(int capacity, Zone* zone)
+      : size_(0), capacity_(capacity),
+        array_(zone->NewArray<Unique<T> >(capacity)) {
+    ASSERT(capacity <= kMaxCapacity);
+  }
+
+  // Singleton constructor.
+  UniqueSet(Unique<T> uniq, Zone* zone)
+      : size_(1), capacity_(1), array_(zone->NewArray<Unique<T> >(1)) {
+    array_[0] = uniq;
+  }

   // Add a new element to this unique set. Mutates this set. O(|this|).
   void Add(Unique<T> uniq, Zone* zone) {
@@ -178,8 +191,11 @@
// TODO(titzer): use binary search for large sets to make this O(log| this|)
   template <typename U>
   bool Contains(const Unique<U> elem) const {
-    for (int i = 0; i < size_; i++) {
-      if (this->array_[i] == elem) return true;
+    for (int i = 0; i < this->size_; ++i) {
+      Unique<T> cand = this->array_[i];
+      if (cand.raw_address_ >= elem.raw_address_) {
+        return cand.raw_address_ == elem.raw_address_;
+      }
     }
     return false;
   }
@@ -201,11 +217,11 @@

// Returns a new set representing the intersection of this set and the other.
   // O(|this| + |that|).
-  UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) const {
+  UniqueSet<T>* Intersect(const UniqueSet<T>* that, Zone* zone) const {
if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>();

-    UniqueSet<T>* out = new(zone) UniqueSet<T>();
-    out->Grow(Min(this->size_, that->size_), zone);
+    UniqueSet<T>* out = new(zone) UniqueSet<T>(
+        Min(this->size_, that->size_), zone);

     int i = 0, j = 0, k = 0;
     while (i < this->size_ && j < that->size_) {
@@ -228,12 +244,12 @@

   // Returns a new set representing the union of this set and the other.
   // O(|this| + |that|).
-  UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) const {
+  UniqueSet<T>* Union(const UniqueSet<T>* that, Zone* zone) const {
     if (that->size_ == 0) return this->Copy(zone);
     if (this->size_ == 0) return that->Copy(zone);

-    UniqueSet<T>* out = new(zone) UniqueSet<T>();
-    out->Grow(this->size_ + that->size_, zone);
+    UniqueSet<T>* out = new(zone) UniqueSet<T>(
+        this->size_ + that->size_, zone);

     int i = 0, j = 0, k = 0;
     while (i < this->size_ && j < that->size_) {
@@ -261,10 +277,8 @@

   // Makes an exact copy of this set. O(|this|).
   UniqueSet<T>* Copy(Zone* zone) const {
-    UniqueSet<T>* copy = new(zone) UniqueSet<T>();
+    UniqueSet<T>* copy = new(zone) UniqueSet<T>(this->size_, zone);
     copy->size_ = this->size_;
-    copy->capacity_ = this->size_;
-    copy->array_ = zone->NewArray<Unique<T> >(this->size_);
     memcpy(copy->array_, this->array_, this->size_ * sizeof(Unique<T>));
     return copy;
   }
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri May 2 08:08:23 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Mon May 5 06:53:19 2014 UTC
@@ -5025,15 +5025,15 @@
     __ bind(deferred->check_maps());
   }

-  const UniqueSet<Map>* map_set = instr->hydrogen()->map_set();
+  const UniqueSet<Map>* maps = instr->hydrogen()->maps();
   Label success;
-  for (int i = 0; i < map_set->size() - 1; i++) {
-    Handle<Map> map = map_set->at(i).handle();
+  for (int i = 0; i < maps->size() - 1; i++) {
+    Handle<Map> map = maps->at(i).handle();
     __ CompareMap(reg, map);
     __ j(equal, &success, Label::kNear);
   }

-  Handle<Map> map = map_set->at(map_set->size() - 1).handle();
+  Handle<Map> map = maps->at(maps->size() - 1).handle();
   __ CompareMap(reg, map);
   if (instr->hydrogen()->has_migration_target()) {
     __ j(not_equal, deferred->entry());

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to