Bug 653248 - Mark any weak references reachable from XPCOM gray, not black. r=gal
authorAndrew McCreight <amccreight@mozilla.com>
Wed, 15 Jun 2011 10:55:58 -0700
changeset 71887 0c1bdce6b0d2382ef4d9db730b62b0a352c3501a
parent 71886 d3daeb8ebbd678195d21065ddb49d16c055767dc
child 71888 16b6d006a3fe44a58ced44f4e9ed7882a80fc517
child 111157 fbecd8add6361dd0b059b10f7794b892202b8a6e
push idunknown
push userunknown
push dateunknown
reviewersgal
bugs653248
milestone7.0a1
Bug 653248 - Mark any weak references reachable from XPCOM gray, not black. r=gal
js/src/jsgc.cpp
js/src/jsgc.h
js/src/xpconnect/src/xpcjsruntime.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1803,16 +1803,24 @@ MarkContext(JSTracer *trc, JSContext *ac
         gcr->trace(trc);
 
     if (acx->sharpObjectMap.depth > 0)
         js_TraceSharpMap(trc, &acx->sharpObjectMap);
 
     MarkValue(trc, acx->iterValue, "iterValue");
 }
 
+void
+MarkWeakReferences(GCMarker *trc)
+{
+    trc->drainMarkStack();
+    while (js_TraceWatchPoints(trc) || WeakMapBase::markAllIteratively(trc))
+        trc->drainMarkStack();
+}
+
 JS_REQUIRES_STACK void
 MarkRuntime(JSTracer *trc)
 {
     JSRuntime *rt = trc->context->runtime;
 
     if (rt->state != JSRTS_LANDING)
         MarkConservativeStackRoots(trc);
 
@@ -1832,19 +1840,24 @@ MarkRuntime(JSTracer *trc)
 #ifdef JS_TRACER
     for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c)
         (*c)->traceMonitor.mark(trc);
 #endif
 
     for (ThreadDataIter i(rt); !i.empty(); i.popFront())
         i.threadData()->mark(trc);
 
+    if (IS_GC_MARKING_TRACER(trc)) {
+        GCMarker *gcmarker = static_cast<GCMarker *>(trc);
+        MarkWeakReferences(gcmarker);
+    }
+
     /*
-     * We mark extra roots at the last thing so it can use use additional
-     * colors to implement cycle collection.
+     * We mark extra roots at the end so additional colors can be used
+     * to implement cycle collection.
      */
     if (rt->gcExtraRootsTraceOp)
         rt->gcExtraRootsTraceOp(trc, rt->gcExtraRootsData);
 
 #ifdef DEBUG
     if (rt->functionMeterFilename) {
         for (int k = 0; k < 2; k++) {
             typedef JSRuntime::FunctionCountMap HM;
@@ -2274,25 +2287,16 @@ MarkAndSweep(JSContext *cx, JSCompartmen
     } else {
         js_MarkScriptFilenames(rt);
     }
 
     MarkRuntime(&gcmarker);
 
     gcmarker.drainMarkStack();
 
-    /*
-     * Mark weak roots.
-     */
-    while (true) {
-        if (!js_TraceWatchPoints(&gcmarker) && !WeakMapBase::markAllIteratively(&gcmarker))
-            break;
-        gcmarker.drainMarkStack();
-    }
-
     rt->gcMarkingTracer = NULL;
 
     if (rt->gcCallback)
         (void) rt->gcCallback(cx, JSGC_MARK_END);
 
 #ifdef DEBUG
     /* Make sure that we didn't mark an object in another compartment */
     if (comp) {
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -1229,16 +1229,19 @@ struct GCMarker : public JSTracer {
     }
 
     void pushXML(JSXML *xml) {
         if (!xmlStack.push(xml))
             delayMarkingChildren(xml);
     }
 };
 
+JS_FRIEND_API(void)
+MarkWeakReferences(GCMarker *trc);
+
 void
 MarkStackRangeConservatively(JSTracer *trc, Value *begin, Value *end);
 
 static inline uint64
 TraceKindMask(unsigned kind)
 {
     return uint64(1) << kind;
 }
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -368,18 +368,20 @@ void XPCJSRuntime::TraceJS(JSTracer* trc
     // Mark these roots as gray so the CC can walk them later.
     js::GCMarker *gcmarker = NULL;
     if (IS_GC_MARKING_TRACER(trc)) {
         gcmarker = static_cast<js::GCMarker *>(trc);
         JS_ASSERT(gcmarker->getMarkColor() == XPC_GC_COLOR_BLACK);
         gcmarker->setMarkColor(XPC_GC_COLOR_GRAY);
     }
     self->TraceXPConnectRoots(trc);
-    if (gcmarker)
+    if (gcmarker) {
+        js::MarkWeakReferences(gcmarker);
         gcmarker->setMarkColor(XPC_GC_COLOR_BLACK);
+    }
 }
 
 static void
 TraceJSObject(PRUint32 aLangID, void *aScriptThing, const char *name,
               void *aClosure)
 {
     if(aLangID == nsIProgrammingLanguage::JAVASCRIPT)
     {