Bug 900598 - Make sure not to collect the atoms compartment when exclusive threads are present (r=bhackett)
authorBill McCloskey <wmccloskey@mozilla.com>
Thu, 01 Aug 2013 16:45:11 -0700
changeset 141025 d449bcecd71eab5a0d0714157fc049d6679d780a
parent 141024 ab3c575381b2f1d831b8552f8bbad7a80e107108
child 141026 70ac9672075b7376aa60445bb5d5e6946e4826b0
push id25046
push useremorley@mozilla.com
push dateFri, 02 Aug 2013 12:29:51 +0000
treeherdermozilla-central@04dd60bdbc04 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs900598
milestone25.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 900598 - Make sure not to collect the atoms compartment when exclusive threads are present (r=bhackett)
js/src/jsgc.cpp
js/src/vm/Runtime.h
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2768,16 +2768,25 @@ BeginMarkPhase(JSRuntime *rt)
      * to atoms that we would miss.
      */
     Zone *atomsZone = rt->atomsCompartment->zone();
 
     bool keepAtoms = false;
     for (ThreadDataIter iter(rt); !iter.done(); iter.next())
         keepAtoms |= iter->gcKeepAtoms;
 
+    /*
+     * We don't scan the stacks of exclusive threads, so we need to avoid
+     * collecting their objects in another way. The only GC thing pointers they
+     * have are to their exclusive compartment (which is not collected) or to
+     * the atoms compartment. Therefore, we avoid collecting the atoms
+     * compartment when exclusive threads are running.
+     */
+    keepAtoms |= rt->exclusiveThreadsPresent();
+
     if (atomsZone->isGCScheduled() && rt->gcIsFull && !keepAtoms) {
         JS_ASSERT(!atomsZone->isCollecting());
         atomsZone->setGCState(Zone::Mark);
     }
 
     /*
      * At the end of each incremental slice, we call prepareForIncrementalGC,
      * which marks objects in all arenas that we're currently allocating
@@ -4347,16 +4356,18 @@ IncrementalSafety
 gc::IsIncrementalGCSafe(JSRuntime *rt)
 {
     JS_ASSERT(!rt->mainThread.suppressGC);
 
     bool keepAtoms = false;
     for (ThreadDataIter iter(rt); !iter.done(); iter.next())
         keepAtoms |= iter->gcKeepAtoms;
 
+    keepAtoms |= rt->exclusiveThreadsPresent();
+
     if (keepAtoms)
         return IncrementalSafety::Unsafe("gcKeepAtoms set");
 
     if (!rt->gcIncrementalEnabled)
         return IncrementalSafety::Unsafe("incremental permanently disabled");
 
     return IncrementalSafety::Safe();
 }
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -760,16 +760,24 @@ struct JSRuntime : public JS::shadow::Ru
 #if defined(JS_THREADSAFE) && defined(DEBUG)
         return (!numExclusiveThreads && mainThreadHasExclusiveAccess) ||
             exclusiveAccessOwner == PR_GetCurrentThread();
 #else
         return true;
 #endif
     }
 
+    bool exclusiveThreadsPresent() const {
+#ifdef JS_THREADSAFE
+        return numExclusiveThreads > 0;
+#else
+        return false;
+#endif
+    }
+
     /* Default compartment. */
     JSCompartment       *atomsCompartment;
 
     /* Embedders can use this zone however they wish. */
     JS::Zone            *systemZone;
 
     /* List of compartments and zones (protected by the GC lock). */
     js::ZoneVector      zones;