Bug 770110: GC: gcIncrementalState is now used by non-incremental GCs r=billm
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 04 Jul 2012 12:15:18 +0100
changeset 98302 df79a01137c1a02a50600f4a561a46446acdcd1b
parent 98301 9a492f7908211a6ed989312fcdd1fdc0a8430ae0
child 98303 2eb2d4b9a0ef582362c3e17103f57752efee3c33
push id11442
push userjcoppeard@mozilla.com
push dateWed, 04 Jul 2012 11:37:55 +0000
treeherdermozilla-inbound@ed582ea30746 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs770110
milestone16.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 770110: GC: gcIncrementalState is now used by non-incremental GCs r=billm
js/src/jsgc.cpp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -3023,34 +3023,34 @@ ShouldPreserveJITCode(JSCompartment *c, 
         return true;
     }
 
     c->lastCodeRelease = currentTime;
     return false;
 }
 
 static void
-BeginMarkPhase(JSRuntime *rt)
+BeginMarkPhase(JSRuntime *rt, bool isIncremental)
 {
     int64_t currentTime = PRMJ_Now();
 
     rt->gcIsFull = true;
     for (CompartmentsIter c(rt); !c.done(); c.next()) {
         if (!c->isCollecting())
             rt->gcIsFull = false;
 
         c->setPreservingCode(ShouldPreserveJITCode(c, currentTime));
     }
 
     rt->gcMarker.start(rt);
     JS_ASSERT(!rt->gcMarker.callback);
     JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker));
 
     /* For non-incremental GC the following sweep discards the jit code. */
-    if (rt->gcIncrementalState != NO_INCREMENTAL) {
+    if (isIncremental) {
         for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
             gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DISCARD_CODE);
             c->discardJitCode(rt->defaultFreeOp());
         }
     }
 
     GCMarker *gcmarker = &rt->gcMarker;
 
@@ -3122,28 +3122,28 @@ MarkGrayAndWeak(JSRuntime *rt)
 }
 
 #ifdef DEBUG
 static void
 ValidateIncrementalMarking(JSRuntime *rt);
 #endif
 
 static void
-EndMarkPhase(JSRuntime *rt)
+EndMarkPhase(JSRuntime *rt, bool isIncremental)
 {
     {
         gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_MARK);
         gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_MARK_OTHER);
         MarkGrayAndWeak(rt);
     }
 
     JS_ASSERT(rt->gcMarker.isDrained());
 
 #ifdef DEBUG
-    if (rt->gcIncrementalState != NO_INCREMENTAL)
+    if (isIncremental)
         ValidateIncrementalMarking(rt);
 #endif
 
     /*
      * Having black->gray edges violates our promise to the cycle
      * collector. This can happen if we're collecting a compartment and it has
      * an edge to an uncollected compartment: it's possible that the source and
      * destination of the cross-compartment edge should be gray, but the source
@@ -3209,30 +3209,31 @@ ValidateIncrementalMarking(JSRuntime *rt
 
     /*
      * After this point, the function should run to completion, so we shouldn't
      * do anything fallible.
      */
 
     /* Re-do all the marking, but non-incrementally. */
     js::gc::State state = rt->gcIncrementalState;
-    rt->gcIncrementalState = NO_INCREMENTAL;
+    rt->gcIncrementalState = MARK_ROOTS;
 
     /* As we're re-doing marking, we need to reset the weak map list. */
     WeakMapBase::resetWeakMapList(rt);
 
     JS_ASSERT(gcmarker->isDrained());
     gcmarker->reset();
 
     for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront())
         r.front()->bitmap.clear();
 
     MarkRuntime(gcmarker, true);
 
     SliceBudget budget;
+    rt->gcIncrementalState = MARK;
     rt->gcMarker.drainMarkStack(budget);
     MarkGrayAndWeak(rt);
 
     /* Now verify that we have the same mark bits as before. */
     for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
         Chunk *chunk = r.front();
         ChunkBitmap *bitmap = &chunk->bitmap;
         uintptr_t *entry = map.lookup(r.front())->value;
@@ -3576,23 +3577,28 @@ IncrementalMarkSlice(JSRuntime *rt, int6
 #ifdef JS_GC_ZEAL
     if (reason == gcreason::DEBUG_GC) {
         // Do the collection type specified by zeal mode only if the collection
         // was triggered by RunDebugGC().
         zeal = rt->gcZeal();
     }
 #endif
 
+    bool isIncremental = rt->gcIncrementalState != NO_INCREMENTAL ||
+                         budget != SliceBudget::Unlimited ||
+                         zeal == ZealIncrementalRootsThenFinish ||
+                         zeal == ZealIncrementalMarkAllThenFinish;
+
     if (rt->gcIncrementalState == NO_INCREMENTAL) {
         rt->gcIncrementalState = MARK_ROOTS;
         rt->gcLastMarkSlice = false;
     }
 
     if (rt->gcIncrementalState == MARK_ROOTS) {
-        BeginMarkPhase(rt);
+        BeginMarkPhase(rt, isIncremental);
         rt->gcIncrementalState = MARK;
 
         if (zeal == ZealIncrementalRootsThenFinish)
             return;
     }
 
     if (rt->gcIncrementalState == MARK) {
         SliceBudget sliceBudget(budget);
@@ -3620,17 +3626,17 @@ IncrementalMarkSlice(JSRuntime *rt, int6
             JS_ASSERT(rt->gcMarker.isDrained());
 
             if (!rt->gcLastMarkSlice &&
                 ((initialState == MARK && budget != SliceBudget::Unlimited) ||
                  zeal == ZealIncrementalMarkAllThenFinish))
             {
                 rt->gcLastMarkSlice = true;
             } else {
-                EndMarkPhase(rt);
+                EndMarkPhase(rt, isIncremental);
                 rt->gcIncrementalState = NO_INCREMENTAL;
                 *shouldSweep = true;
             }
         }
     }
 }
 
 class IncrementalSafety