Bug 961077 - Take marking function as template parameter in PersistentRootedMarker r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 23 Jan 2014 09:53:42 +0000
changeset 180844 00b51ce701ff71d9190d839927352cd505c6b8d6
parent 180843 1f76c5ce073633ae5083d09a50b874140dfb3ed5
child 180845 e6197abbed3ab7da83018816159a3fda2736c690
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs961077
milestone29.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 961077 - Take marking function as template parameter in PersistentRootedMarker r=sfink
js/public/RootingAPI.h
js/src/gc/RootMarking.cpp
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -133,16 +133,17 @@ class HeapBase {};
  */
 struct NullPtr
 {
     static void * const constNullValue;
 };
 
 namespace gc {
 struct Cell;
+template<typename T>
 struct PersistentRootedMarker;
 } /* namespace gc */
 
 } /* namespace js */
 
 namespace JS {
 
 template <typename T> class Rooted;
@@ -1185,17 +1186,18 @@ MutableHandle<T>::MutableHandle(Persiste
  * TenuredHeap<T> would be better types. It's up to the implementor of the type
  * containing Heap<T> or TenuredHeap<T> members to make sure their referents get
  * marked when the object itself is marked.
  */
 template<typename T>
 class PersistentRooted : private mozilla::LinkedListElement<PersistentRooted<T> > {
     friend class mozilla::LinkedList<PersistentRooted>;
     friend class mozilla::LinkedListElement<PersistentRooted>;
-    friend class js::gc::PersistentRootedMarker;
+
+    friend class js::gc::PersistentRootedMarker<T>;
 
     void registerWithRuntime(JSRuntime *rt) {
         JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt);
         srt->getPersistentRootedList<T>().insertBack(this);
     }
 
   public:
     PersistentRooted(JSContext *cx) : ptr(js::GCMethods<T>::initial())
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -622,65 +622,65 @@ JSPropertyDescriptor::trace(JSTracer *tr
         JSObject *tmp = JS_FUNC_TO_DATA_PTR(JSObject *, setter);
         MarkObjectRoot(trc, &tmp, "Descriptor::set");
         setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, tmp);
     }
 }
 
 namespace js {
 namespace gc {
+
+template<typename T>
 struct PersistentRootedMarker
 {
-    template<typename Referent>
+    typedef PersistentRooted<T> Element;
+    typedef mozilla::LinkedList<Element> List;
+    typedef void (*MarkFunc)(JSTracer *trc, T *ref, const char *name);
+
+    template <MarkFunc Mark>
     static void
-    markChainIfNotNull(JSTracer *trc,
-                       mozilla::LinkedList<PersistentRooted<Referent *> > &list,
-                       void (*marker)(JSTracer *trc, Referent **ref, const char *name),
-                       const char *name)
+    markChainIfNotNull(JSTracer *trc, List &list, const char *name)
     {
-        for (PersistentRooted<Referent *> *r = list.getFirst(); r; r = r->getNext()) {
+        for (Element *r = list.getFirst(); r; r = r->getNext()) {
             if (r->get())
-                marker(trc, r->address(), name);
+                Mark(trc, r->address(), name);
         }
     }
 
-    template<typename Referent>
+    template <MarkFunc Mark>
     static void
-    markChain(JSTracer *trc,
-              mozilla::LinkedList<PersistentRooted<Referent> > &list,
-              void (*marker)(JSTracer *trc, Referent *ref, const char *name),
-              const char *name)
+    markChain(JSTracer *trc, List &list, const char *name)
     {
-        for (PersistentRooted<Referent> *r = list.getFirst(); r; r = r->getNext())
-            marker(trc, r->address(), name);
+        for (Element *r = list.getFirst(); r; r = r->getNext())
+            Mark(trc, r->address(), name);
     }
 };
 }
 }
 
 void
 js::gc::MarkPersistentRootedChains(JSTracer *trc)
 {
     JSRuntime *rt = trc->runtime;
 
     // Mark the PersistentRooted chains of types that may be null.
-    PersistentRootedMarker::markChainIfNotNull(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
-                                               "PersistentRooted<JSFunction *>");
-    PersistentRootedMarker::markChainIfNotNull(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
-                                               "PersistentRooted<JSObject *>");
-    PersistentRootedMarker::markChainIfNotNull(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
-                                               "PersistentRooted<JSScript *>");
-    PersistentRootedMarker::markChainIfNotNull(trc, rt->stringPersistentRooteds, &MarkStringRoot,
-                                               "PersistentRooted<JSString *>");
+    PersistentRootedMarker<JSFunction*>::markChainIfNotNull<MarkObjectRoot>(
+        trc, rt->functionPersistentRooteds, "PersistentRooted<JSFunction *>");
+    PersistentRootedMarker<JSObject*>::markChainIfNotNull<MarkObjectRoot>(
+        trc, rt->objectPersistentRooteds, "PersistentRooted<JSObject *>");
+    PersistentRootedMarker<JSScript*>::markChainIfNotNull<MarkScriptRoot>(
+        trc, rt->scriptPersistentRooteds, "PersistentRooted<JSScript *>");
+    PersistentRootedMarker<JSString*>::markChainIfNotNull<MarkStringRoot>(
+        trc, rt->stringPersistentRooteds, "PersistentRooted<JSString *>");
 
     // Mark the PersistentRooted chains of types that are never null.
-    PersistentRootedMarker::markChain(trc, rt->idPersistentRooteds, &MarkIdRoot,
-                                      "PersistentRooted<jsid>");
-    PersistentRootedMarker::markChain(trc, rt->valuePersistentRooteds, &MarkValueRoot,
-                                      "PersistentRooted<Value>");
+    PersistentRootedMarker<jsid>::markChain<MarkIdRoot>(trc, rt->idPersistentRooteds,
+                                                        "PersistentRooted<jsid>");
+    PersistentRootedMarker<Value>::markChain<MarkValueRoot>(trc, rt->valuePersistentRooteds,
+                                                            "PersistentRooted<Value>");
 }
 
 void
 js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
 {
     JSRuntime *rt = trc->runtime;
     JS_ASSERT(trc->callback != GCMarker::GrayCallback);