Bug 1118044, part 2 - Use GCCellPtr in NoteJSChild. r=smaug,terrence
authorAndrew McCreight <continuation@gmail.com>
Thu, 08 Jan 2015 15:30:54 -0800
changeset 248650 eabd210312f998169d13681891a30680d170b88d
parent 248649 3941c5858c22c5ffc83c74ad9b4c7afb28c9ed97
child 248651 977aab16aad322fb4bd1cd0901ca07bd0ebf3035
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, terrence
bugs1118044
milestone37.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 1118044, part 2 - Use GCCellPtr in NoteJSChild. r=smaug,terrence Also, strongly type the JS_TraceShapeCycleCollectorChildren function, and add an isShape() method to GCCellPtr.
js/public/HeapAPI.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
xpcom/base/CycleCollectedJSRuntime.cpp
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -188,16 +188,17 @@ class JS_FRIEND_API(GCCellPtr)
         return asCell() ? &GCCellPtr::nonNull : 0;
     }
 
     // Simplify checks to the kind.
     bool isObject() const { return kind() == JSTRACE_OBJECT; }
     bool isScript() const { return kind() == JSTRACE_SCRIPT; }
     bool isString() const { return kind() == JSTRACE_STRING; }
     bool isSymbol() const { return kind() == JSTRACE_SYMBOL; }
+    bool isShape() const { return kind() == JSTRACE_SHAPE; }
 
     // Conversions to more specific types must match the kind. Access to
     // further refined types is not allowed directly from a GCCellPtr.
     JSObject *toObject() const {
         MOZ_ASSERT(kind() == JSTRACE_OBJECT);
         return reinterpret_cast<JSObject *>(asCell());
     }
     JSString *toString() const {
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -206,19 +206,20 @@ JS_ScriptHasMutedErrors(JSScript *script
 
 JS_FRIEND_API(bool)
 JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<js::PropertyDescriptor> desc)
 {
     return cx->compartment()->wrap(cx, desc);
 }
 
 JS_FRIEND_API(void)
-JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape)
+JS_TraceShapeCycleCollectorChildren(JSTracer *trc, JS::GCCellPtr shape)
 {
-    MarkCycleCollectorChildren(trc, static_cast<Shape *>(shape));
+    MOZ_ASSERT(shape.isShape());
+    MarkCycleCollectorChildren(trc, static_cast<Shape *>(shape.asCell()));
 }
 
 static bool
 DefineHelpProperty(JSContext *cx, HandleObject obj, const char *prop, const char *value)
 {
     RootedAtom atom(cx, Atomize(cx, value, strlen(value)));
     if (!atom)
         return false;
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -87,17 +87,17 @@ extern JS_FRIEND_API(bool)
 JS_IsDeadWrapper(JSObject *obj);
 
 /*
  * Used by the cycle collector to trace through the shape and all
  * shapes it reaches, marking all non-shape children found in the
  * process. Uses bounded stack space.
  */
 extern JS_FRIEND_API(void)
-JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape);
+JS_TraceShapeCycleCollectorChildren(JSTracer *trc, JS::GCCellPtr shape);
 
 enum {
     JS_TELEMETRY_GC_REASON,
     JS_TELEMETRY_GC_IS_COMPARTMENTAL,
     JS_TELEMETRY_GC_MS,
     JS_TELEMETRY_GC_MAX_PAUSE_MS,
     JS_TELEMETRY_GC_MARK_MS,
     JS_TELEMETRY_GC_SWEEP_MS,
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -377,74 +377,74 @@ struct TraversalTracer : public JSTracer
   TraversalTracer(JSRuntime* aRt, nsCycleCollectionTraversalCallback& aCb)
     : JSTracer(aRt, NoteJSChildTracerShim, DoNotTraceWeakMaps), mCb(aCb)
   {
   }
   nsCycleCollectionTraversalCallback& mCb;
 };
 
 static void
-NoteJSChild(JSTracer* aTrc, void* aThing, JSGCTraceKind aTraceKind)
+NoteJSChild(JSTracer* aTrc, JS::GCCellPtr aThing)
 {
-  JS::GCCellPtr thing(aThing, aTraceKind);
   TraversalTracer* tracer = static_cast<TraversalTracer*>(aTrc);
 
   // Don't traverse non-gray objects, unless we want all traces.
-  if (!JS::GCThingIsMarkedGray(thing) && !tracer->mCb.WantAllTraces()) {
+  if (!JS::GCThingIsMarkedGray(aThing) && !tracer->mCb.WantAllTraces()) {
     return;
   }
 
   /*
    * This function needs to be careful to avoid stack overflow. Normally, when
    * AddToCCKind is true, the recursion terminates immediately as we just add
    * |thing| to the CC graph. So overflow is only possible when there are long
    * chains of non-AddToCCKind GC things. Currently, this only can happen via
    * shape parent pointers. The special JSTRACE_SHAPE case below handles
    * parent pointers iteratively, rather than recursively, to avoid overflow.
    */
-  if (AddToCCKind(aTraceKind)) {
+  if (AddToCCKind(aThing.kind())) {
     if (MOZ_UNLIKELY(tracer->mCb.WantDebugInfo())) {
       // based on DumpNotify in jsapi.cpp
       if (tracer->debugPrinter()) {
         char buffer[200];
         tracer->debugPrinter()(aTrc, buffer, sizeof(buffer));
         tracer->mCb.NoteNextEdgeName(buffer);
       } else if (tracer->debugPrintIndex() != (size_t)-1) {
         char buffer[200];
         JS_snprintf(buffer, sizeof(buffer), "%s[%lu]",
                     static_cast<const char*>(tracer->debugPrintArg()),
                     tracer->debugPrintIndex());
         tracer->mCb.NoteNextEdgeName(buffer);
       } else {
         tracer->mCb.NoteNextEdgeName(static_cast<const char*>(tracer->debugPrintArg()));
       }
     }
-    if (thing.isObject()) {
-      tracer->mCb.NoteJSObject(thing.toObject());
+    if (aThing.isObject()) {
+      tracer->mCb.NoteJSObject(aThing.toObject());
     } else {
-      tracer->mCb.NoteJSScript(thing.toScript());
+      tracer->mCb.NoteJSScript(aThing.toScript());
     }
-  } else if (aTraceKind == JSTRACE_SHAPE) {
+  } else if (aThing.isShape()) {
     JS_TraceShapeCycleCollectorChildren(aTrc, aThing);
-  } else if (aTraceKind != JSTRACE_STRING) {
-    JS_TraceChildren(aTrc, aThing, aTraceKind);
+  } else if (!aThing.isString()) {
+    JS_TraceChildren(aTrc, aThing.asCell(), aThing.kind());
   }
 }
 
 static void
 NoteJSChildTracerShim(JSTracer* aTrc, void** aThingp, JSGCTraceKind aTraceKind)
 {
-  NoteJSChild(aTrc, *aThingp, aTraceKind);
+  JS::GCCellPtr thing(*aThingp, aTraceKind);
+  NoteJSChild(aTrc, thing);
 }
 
 static void
 NoteJSChildGrayWrapperShim(void* aData, JS::GCCellPtr aThing)
 {
   TraversalTracer* trc = static_cast<TraversalTracer*>(aData);
-  NoteJSChild(trc, aThing.asCell(), aThing.kind());
+  NoteJSChild(trc, aThing);
 }
 
 /*
  * The cycle collection participant for a Zone is intended to produce the same
  * results as if all of the gray GCthings in a zone were merged into a single node,
  * except for self-edges. This avoids the overhead of representing all of the GCthings in
  * the zone in the cycle collector graph, which should be much faster if many of
  * the GCthings in the zone are gray.