Bug 1147180 - Replace the generic Mark functions with TraceEdge; r=jonco
☠☠ backed out by 99415fbccf83 ☠ ☠
authorTerrence Cole <terrence@mozilla.com>
Tue, 24 Mar 2015 14:37:16 -0700
changeset 266632 6bbd529bd995bc89ac9b064bf33b81d3ce6cd342
parent 266631 853e3ad56dadff940baea514c999b9fb055755fb
child 266633 be4138f208bad246fac8a198a56c2aec1e27dacc
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1147180
milestone39.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 1147180 - Replace the generic Mark functions with TraceEdge; r=jonco
js/src/gc/Marking.h
js/src/gc/StoreBuffer.h
js/src/jscompartment.cpp
js/src/jspropertytree.cpp
js/src/jsweakmap.h
js/src/vm/Debugger.h
js/src/vm/ObjectGroup.cpp
js/src/vm/Shape.cpp
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -281,66 +281,16 @@ MarkCrossCompartmentSlot(JSTracer *trc, 
 void
 MarkCycleCollectorChildren(JSTracer *trc, Shape *shape);
 
 void
 PushArena(GCMarker *gcmarker, ArenaHeader *aheader);
 
 /*** Generic ***/
 
-/*
- * The Mark() functions interface should only be used by code that must be
- * templated.  Other uses should use the more specific, type-named functions.
- */
-
-inline void
-Mark(JSTracer *trc, BarrieredBase<Value> *v, const char *name)
-{
-    MarkValue(trc, v, name);
-}
-
-inline void
-Mark(JSTracer *trc, BarrieredBase<JSObject*> *o, const char *name)
-{
-    MarkObject(trc, o, name);
-}
-
-inline void
-Mark(JSTracer *trc, BarrieredBase<JSScript*> *o, const char *name)
-{
-    MarkScript(trc, o, name);
-}
-
-inline void
-Mark(JSTracer *trc, HeapPtrJitCode *code, const char *name)
-{
-    MarkJitCode(trc, code, name);
-}
-
-/* For use by WeakMap's HashKeyRef instantiation. */
-inline void
-Mark(JSTracer *trc, JSObject **objp, const char *name)
-{
-    MarkObjectUnbarriered(trc, objp, name);
-}
-
-/* For use by Debugger::WeakMap's missingScopes HashKeyRef instantiation. */
-inline void
-Mark(JSTracer *trc, NativeObject **obj, const char *name)
-{
-    MarkObjectUnbarriered(trc, obj, name);
-}
-
-/* For use by Debugger::WeakMap's liveScopes HashKeyRef instantiation. */
-inline void
-Mark(JSTracer *trc, ScopeObject **obj, const char *name)
-{
-    MarkObjectUnbarriered(trc, obj, name);
-}
-
 inline bool
 IsMarked(BarrieredBase<Value> *v)
 {
     if (!v->isMarkable())
         return true;
     return IsValueMarked(v->unsafeGet());
 }
 
@@ -401,16 +351,40 @@ ToMarkable(const Value &v)
 }
 
 inline Cell *
 ToMarkable(Cell *cell)
 {
     return cell;
 }
 
+/*
+ * HashKeyRef represents a reference to a HashMap key. This should normally
+ * be used through the HashTableWriteBarrierPost function.
+ */
+template <typename Map, typename Key>
+class HashKeyRef : public BufferableRef
+{
+    Map *map;
+    Key key;
+
+  public:
+    HashKeyRef(Map *m, const Key &k) : map(m), key(k) {}
+
+    void mark(JSTracer *trc) {
+        Key prior = key;
+        typename Map::Ptr p = map->lookup(key);
+        if (!p)
+            return;
+        trc->setTracingLocation(&*p);
+        TraceManuallyBarrieredEdge(trc, &key, "HashKeyRef");
+        map->rekeyIfMoved(prior, key);
+    }
+};
+
 } /* namespace gc */
 
 void
 TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind);
 
 bool
 UnmarkGrayShapeRecursively(Shape *shape);
 
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -29,40 +29,16 @@ namespace gc {
  */
 class BufferableRef
 {
   public:
     virtual void mark(JSTracer *trc) = 0;
     bool maybeInRememberedSet(const Nursery &) const { return true; }
 };
 
-/*
- * HashKeyRef represents a reference to a HashMap key. This should normally
- * be used through the HashTableWriteBarrierPost function.
- */
-template <typename Map, typename Key>
-class HashKeyRef : public BufferableRef
-{
-    Map *map;
-    Key key;
-
-  public:
-    HashKeyRef(Map *m, const Key &k) : map(m), key(k) {}
-
-    void mark(JSTracer *trc) {
-        Key prior = key;
-        typename Map::Ptr p = map->lookup(key);
-        if (!p)
-            return;
-        trc->setTracingLocation(&*p);
-        Mark(trc, &key, "HashKeyRef");
-        map->rekeyIfMoved(prior, key);
-    }
-};
-
 typedef HashSet<void *, PointerHasher<void *, 3>, SystemAllocPolicy> EdgeSet;
 
 /* The size of a single block of store buffer storage space. */
 static const size_t LifoAllocBlockSize = 1 << 16; /* 64KiB */
 
 /*
  * The StoreBuffer observes all writes that occur in the system and performs
  * efficient filtering of them to derive a remembered set for nursery GC.
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -202,25 +202,26 @@ class WrapperMapRef : public BufferableR
 
   public:
     WrapperMapRef(WrapperMap *map, const CrossCompartmentKey &key)
       : map(map), key(key) {}
 
     void mark(JSTracer *trc) {
         CrossCompartmentKey prior = key;
         if (key.debugger)
-            Mark(trc, &key.debugger, "CCW debugger");
+            TraceManuallyBarrieredEdge(trc, &key.debugger, "CCW debugger");
         if (key.kind == CrossCompartmentKey::ObjectWrapper ||
             key.kind == CrossCompartmentKey::DebuggerObject ||
             key.kind == CrossCompartmentKey::DebuggerEnvironment ||
             key.kind == CrossCompartmentKey::DebuggerSource)
         {
             MOZ_ASSERT(IsInsideNursery(key.wrapped) ||
                        key.wrapped->asTenured().getTraceKind() == JSTRACE_OBJECT);
-            Mark(trc, reinterpret_cast<JSObject**>(&key.wrapped), "CCW wrapped object");
+            TraceManuallyBarrieredEdge(trc, reinterpret_cast<JSObject**>(&key.wrapped),
+                                       "CCW wrapped object");
         }
         if (key.debugger == prior.debugger && key.wrapped == prior.wrapped)
             return;
 
         /* Look for the original entry, which might have been removed. */
         WrapperMap::Ptr p = map->lookup(prior);
         if (!p)
             return;
--- a/js/src/jspropertytree.cpp
+++ b/js/src/jspropertytree.cpp
@@ -317,17 +317,17 @@ ShapeGetterSetterRef::mark(JSTracer *trc
     // pointers.
 
     JSObject *obj = *objp;
     JSObject *prior = obj;
     if (!prior)
         return;
 
     trc->setTracingLocation(&*prior);
-    gc::Mark(trc, &obj, "AccessorShape getter or setter");
+    TraceManuallyBarrieredEdge(trc, &obj, "AccessorShape getter or setter");
     if (obj == *objp)
         return;
 
     Shape *parent = shape->parent;
     if (shape->inDictionary() || !parent->kids.isHash()) {
         *objp = obj;
         return;
     }
--- a/js/src/jsweakmap.h
+++ b/js/src/jsweakmap.h
@@ -156,33 +156,33 @@ class WeakMap : public HashMap<Key, Valu
 
   private:
     void exposeGCThingToActiveJS(const JS::Value &v) const { JS::ExposeValueToActiveJS(v); }
     void exposeGCThingToActiveJS(JSObject *obj) const { JS::ExposeObjectToActiveJS(obj); }
 
     bool markValue(JSTracer *trc, Value *x) {
         if (gc::IsMarked(x))
             return false;
-        gc::Mark(trc, x, "WeakMap entry value");
+        TraceEdge(trc, x, "WeakMap entry value");
         MOZ_ASSERT(gc::IsMarked(x));
         return true;
     }
 
     void nonMarkingTraceKeys(JSTracer *trc) {
         for (Enum e(*this); !e.empty(); e.popFront()) {
             Key key(e.front().key());
-            gc::Mark(trc, &key, "WeakMap entry key");
+            TraceEdge(trc, &key, "WeakMap entry key");
             if (key != e.front().key())
                 entryMoved(e, key);
         }
     }
 
     void nonMarkingTraceValues(JSTracer *trc) {
         for (Range r = Base::all(); !r.empty(); r.popFront())
-            gc::Mark(trc, &r.front().value(), "WeakMap entry value");
+            TraceEdge(trc, &r.front().value(), "WeakMap entry value");
     }
 
     bool keyNeedsMark(JSObject *key) {
         if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) {
             JSObject *delegate = op(key);
             /*
              * Check if the delegate is marked with any color to properly handle
              * gray marking when the key's delegate is black and the map is
@@ -203,18 +203,18 @@ class WeakMap : public HashMap<Key, Valu
             /* If the entry is live, ensure its key and value are marked. */
             Key key(e.front().key());
             if (gc::IsMarked(const_cast<Key *>(&key))) {
                 if (markValue(trc, &e.front().value()))
                     markedAny = true;
                 if (e.front().key() != key)
                     entryMoved(e, key);
             } else if (keyNeedsMark(key)) {
-                gc::Mark(trc, &e.front().value(), "WeakMap entry value");
-                gc::Mark(trc, &key, "proxy-preserved WeakMap entry key");
+                TraceEdge(trc, &e.front().value(), "WeakMap entry value");
+                TraceEdge(trc, &key, "proxy-preserved WeakMap entry key");
                 if (e.front().key() != key)
                     entryMoved(e, key);
                 markedAny = true;
             }
             key.unsafeSet(nullptr);
         }
         return markedAny;
     }
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -119,17 +119,17 @@ class DebuggerWeakMap : private WeakMap<
     }
 
   public:
     template <void (traceValueEdges)(JSTracer *, JSObject *)>
     void markCrossCompartmentEdges(JSTracer *tracer) {
         for (Enum e(*static_cast<Base *>(this)); !e.empty(); e.popFront()) {
             traceValueEdges(tracer, e.front().value());
             Key key = e.front().key();
-            gc::Mark(tracer, &key, "Debugger WeakMap key");
+            TraceEdge(tracer, &key, "Debugger WeakMap key");
             if (key != e.front().key())
                 e.rekeyFront(key);
             key.unsafeSet(nullptr);
         }
     }
 
     bool hasKeyInZone(JS::Zone *zone) {
         CountMap::Ptr p = zoneCounts.lookup(zone);
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -412,17 +412,17 @@ class ObjectGroupCompartment::NewTableRe
   public:
     NewTableRef(NewTable *table, const Class *clasp, JSObject *proto, JSObject *associated)
         : table(table), clasp(clasp), proto(proto), associated(associated)
     {}
 
     void mark(JSTracer *trc) {
         JSObject *prior = proto;
         trc->setTracingLocation(&*prior);
-        Mark(trc, &proto, "newObjectGroups set prototype");
+        TraceManuallyBarrieredEdge(trc, &proto, "newObjectGroups set prototype");
         if (prior == proto)
             return;
 
         NewTable::Ptr p = table->lookup(NewTable::Lookup(clasp, TaggedProto(prior),
                                                          TaggedProto(proto),
                                                          associated));
         if (!p)
             return;
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1346,18 +1346,20 @@ class InitialShapeSetRef : public Buffer
           clasp(clasp),
           proto(proto),
           nfixed(nfixed),
           objectFlags(objectFlags)
     {}
 
     void mark(JSTracer *trc) {
         TaggedProto priorProto = proto;
-        if (proto.isObject())
-            Mark(trc, reinterpret_cast<JSObject**>(&proto), "initialShapes set proto");
+        if (proto.isObject()) {
+            TraceManuallyBarrieredEdge(trc, reinterpret_cast<JSObject**>(&proto),
+                                       "initialShapes set proto");
+        }
         if (proto == priorProto)
             return;
 
         /* Find the original entry, which must still be present. */
         InitialShapeEntry::Lookup lookup(clasp, priorProto, nfixed, objectFlags);
         InitialShapeSet::Ptr p = set->lookup(lookup);
         MOZ_ASSERT(p);