diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 1039a996eb8..a5d08f1bdd2 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -734,6 +734,7 @@ JSRuntime::JSRuntime() gcStats(thisFromCtor()), gcNumber(0), gcStartNumber(0), + gcIsFull(false), gcTriggerReason(gcreason::NO_REASON), gcStrictCompartmentChecking(false), gcIncrementalState(gc::NO_INCREMENTAL), diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 23b9543e5f0..f4aef744eaa 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -362,6 +362,9 @@ struct JSRuntime : js::RuntimeFriendFields /* The gcNumber at the time of the most recent GC's first slice. */ uint64_t gcStartNumber; + /* Whether all compartments are being collected in first GC slice. */ + bool gcIsFull; + /* The reason that an interrupt-triggered GC should be called. */ js::gcreason::Reason gcTriggerReason; diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 09212e872c7..10a99d169f1 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -2280,14 +2280,7 @@ MarkRuntime(JSTracer *trc, bool useSavedRoots = false) * atoms. Otherwise, the non-collected compartments could contain pointers * to atoms that we would miss. */ - bool isFullGC = true; - if (IS_GC_MARKING_TRACER(trc)) { - for (CompartmentsIter c(rt); !c.done(); c.next()) { - if (!c->isCollecting()) - isFullGC = false; - } - } - MarkAtomState(trc, rt->gcKeepAtoms || !isFullGC); + MarkAtomState(trc, rt->gcKeepAtoms || (IS_GC_MARKING_TRACER(trc) && !rt->gcIsFull)); rt->staticStrings.trace(trc); for (ContextIter acx(rt); !acx.done(); acx.next()) @@ -2903,6 +2896,12 @@ PurgeRuntime(JSTracer *trc) static void BeginMarkPhase(JSRuntime *rt) { + rt->gcIsFull = true; + for (CompartmentsIter c(rt); !c.done(); c.next()) { + if (!c->isCollecting()) + rt->gcIsFull = false; + } + rt->gcMarker.start(rt); JS_ASSERT(!rt->gcMarker.callback); JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker));