Bug 1237445 - Use GCHashSet for BaseShapeSet and InitialShapeSet, r=terrence
authorSteve Fink <sfink@mozilla.com>
Fri, 13 Nov 2015 16:22:35 -0800
changeset 281928 d0b106a76c7f44f96aea815e7dfb74902d49b386
parent 281927 b86853e8d604ebe6ddb864c305092bf3d014ebb4
child 281929 c1153dc8ccd12858e6f0e2b3762e2331b9feee01
push id70974
push usersfink@mozilla.com
push dateWed, 27 Jan 2016 17:40:26 +0000
treeherdermozilla-inbound@d8f94c805684 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1237445
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1237445 - Use GCHashSet for BaseShapeSet and InitialShapeSet, r=terrence
js/src/vm/Shape.cpp
js/src/vm/Shape.h
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1311,28 +1311,17 @@ BaseShape::traceChildren(JSTracer* trc)
     JSObject* global = compartment()->unsafeUnbarrieredMaybeGlobal();
     if (global)
         TraceManuallyBarrieredEdge(trc, &global, "global");
 }
 
 void
 JSCompartment::sweepBaseShapeTable()
 {
-    if (!baseShapes.initialized())
-        return;
-
-    for (BaseShapeSet::Enum e(baseShapes); !e.empty(); e.popFront()) {
-        UnownedBaseShape* base = e.front().unbarrieredGet();
-        if (IsAboutToBeFinalizedUnbarriered(&base)) {
-            e.removeFront();
-        } else if (base != e.front().unbarrieredGet()) {
-            ReadBarriered<UnownedBaseShape*> b(base);
-            e.rekeyFront(base, b);
-        }
-    }
+    baseShapes.sweep();
 }
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 
 void
 JSCompartment::checkBaseShapeTableAfterMovingGC()
 {
     if (!baseShapes.initialized())
@@ -1607,34 +1596,17 @@ EmptyShape::insertInitialShape(Exclusive
         JSContext* ncx = cx->asJSContext();
         ncx->runtime()->newObjectCache.invalidateEntriesForShape(ncx, shape, proto);
     }
 }
 
 void
 JSCompartment::sweepInitialShapeTable()
 {
-    if (initialShapes.initialized()) {
-        for (InitialShapeSet::Enum e(initialShapes); !e.empty(); e.popFront()) {
-            const InitialShapeEntry& entry = e.front();
-            Shape* shape = entry.shape.unbarrieredGet();
-            JSObject* proto = entry.proto.raw();
-            if (IsAboutToBeFinalizedUnbarriered(&shape) ||
-                (entry.proto.isObject() && IsAboutToBeFinalizedUnbarriered(&proto)))
-            {
-                e.removeFront();
-            } else {
-                if (shape != entry.shape.unbarrieredGet() || proto != entry.proto.raw()) {
-                    ReadBarrieredShape readBarrieredShape(shape);
-                    InitialShapeEntry newKey(readBarrieredShape, TaggedProto(proto));
-                    e.rekeyFront(newKey.getLookup(), newKey);
-                }
-            }
-        }
-    }
+    initialShapes.sweep();
 }
 
 void
 JSCompartment::fixupInitialShapeTable()
 {
     if (!initialShapes.initialized())
         return;
 
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -515,20 +515,19 @@ struct StackBaseShape : public DefaultHa
             MOZ_ASSERT(!base->isOwned());
         }
     };
 
     static inline HashNumber hash(const Lookup& lookup);
     static inline bool match(ReadBarriered<UnownedBaseShape*> key, const Lookup& lookup);
 };
 
-typedef HashSet<ReadBarriered<UnownedBaseShape*>,
-                StackBaseShape,
-                SystemAllocPolicy> BaseShapeSet;
-
+using BaseShapeSet = js::GCHashSet<ReadBarriered<UnownedBaseShape*>,
+                                   StackBaseShape,
+                                   SystemAllocPolicy>;
 
 class Shape : public gc::TenuredCell
 {
     friend class ::JSObject;
     friend class ::JSFunction;
     friend class Bindings;
     friend class NativeObject;
     friend class PropertyTree;
@@ -1107,19 +1106,26 @@ struct InitialShapeEntry
     inline InitialShapeEntry();
     inline InitialShapeEntry(const ReadBarrieredShape& shape, TaggedProto proto);
 
     inline Lookup getLookup() const;
 
     static inline HashNumber hash(const Lookup& lookup);
     static inline bool match(const InitialShapeEntry& key, const Lookup& lookup);
     static void rekey(InitialShapeEntry& k, const InitialShapeEntry& newKey) { k = newKey; }
+
+    bool needsSweep() {
+        Shape* ushape = shape.unbarrieredGet();
+        JSObject* protoObj = proto.raw();
+        return (gc::IsAboutToBeFinalizedUnbarriered(&ushape) ||
+                (proto.isObject() && gc::IsAboutToBeFinalizedUnbarriered(&protoObj)));
+    }
 };
 
-typedef HashSet<InitialShapeEntry, InitialShapeEntry, SystemAllocPolicy> InitialShapeSet;
+using InitialShapeSet = js::GCHashSet<InitialShapeEntry, InitialShapeEntry, SystemAllocPolicy>;
 
 struct StackShape : public JS::Traceable
 {
     /* For performance, StackShape only roots when absolutely necessary. */
     UnownedBaseShape* base;
     jsid propid;
     GetterOp rawGetter;
     SetterOp rawSetter;