bug 714545 - js_FinishGC should not race with the background thread. r=wmccloskey
authorIgor Bukanov <igor@mir2.org>
Sat, 31 Dec 2011 21:29:41 +0100
changeset 84859 9cf3968475006ca542e693eb56468f73c76e1f76
parent 84858 9152791a6f9039f1be5534b1ea5d88dbec21cb20
child 84860 b76de21ba602555dc09ab324834af9f705ca9eaa
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswmccloskey
bugs714545
milestone12.0a1
bug 714545 - js_FinishGC should not race with the background thread. r=wmccloskey
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1192,36 +1192,36 @@ js_IsAddressableGCThing(JSRuntime *rt, j
 #ifdef DEBUG
 static void
 CheckLeakedRoots(JSRuntime *rt);
 #endif
 
 void
 js_FinishGC(JSRuntime *rt)
 {
+    /*
+     * Wait until the background finalization stops and the helper thread
+     * shuts down before we forcefully release any remaining GC memory.
+     */
+#ifdef JS_THREADSAFE
+    rt->gcHelperThread.finish();
+#endif
+
     /* Delete all remaining Compartments. */
     for (CompartmentsIter c(rt); !c.done(); c.next())
         Foreground::delete_(c.get());
     rt->compartments.clear();
     rt->atomsCompartment = NULL;
 
     rt->gcSystemAvailableChunkListHead = NULL;
     rt->gcUserAvailableChunkListHead = NULL;
     for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront())
         Chunk::release(rt, r.front());
     rt->gcChunkSet.clear();
 
-#ifdef JS_THREADSAFE
-    rt->gcHelperThread.finish();
-#endif
-
-    /*
-     * Finish the pool after the background thread stops in case it was doing
-     * the background sweeping.
-     */
     rt->gcChunkPool.expireAndFree(rt, true);
 
 #ifdef DEBUG
     if (!rt->gcRootsHash.empty())
         CheckLeakedRoots(rt);
 #endif
     rt->gcRootsHash.clear();
     rt->gcLocksHash.clear();
@@ -2349,17 +2349,20 @@ GCHelperThread::init()
 
 void
 GCHelperThread::finish()
 {
     PRThread *join = NULL;
     {
         AutoLockGC lock(rt);
         if (thread && state != SHUTDOWN) {
-            /* The allocation should have been stopped during the last GC. */
+            /*
+             * We cannot be in the ALLOCATING or CANCEL_ALLOCATION states as
+             * the allocations should have been stopped during the last GC.
+             */
             JS_ASSERT(state == IDLE || state == SWEEPING);
             if (state == IDLE)
                 PR_NotifyCondVar(wakeup);
             state = SHUTDOWN;
             join = thread;
         }
     }
     if (join) {