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 140981 d449bcecd71eab5a0d0714157fc049d6679d780a
parent 140980 ab3c575381b2f1d831b8552f8bbad7a80e107108
child 140982 70ac9672075b7376aa60445bb5d5e6946e4826b0
push id31952
push userwmccloskey@mozilla.com
push dateThu, 01 Aug 2013 23:46:55 +0000
treeherdermozilla-inbound@70ac9672075b [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;