diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 40dcb3ea045d..23429319ed29 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -3879,22 +3879,26 @@ IncrementalCollectSlice(JSRuntime *rt, int zeal = 0; #ifdef JS_GC_ZEAL - if (reason == gcreason::DEBUG_GC) { + if (reason == gcreason::DEBUG_GC && budget != SliceBudget::Unlimited) { /* - * Do the collection type specified by zeal mode only if the collection - * was triggered by RunDebugGC(). + * Do the incremental collection type specified by zeal mode if the + * collection was triggered by RunDebugGC() and incremental GC has not + * been cancelled by ResetIncrementalGC. */ zeal = rt->gcZeal(); - JS_ASSERT_IF(zeal == ZealIncrementalMarkAllThenFinish || - zeal == ZealIncrementalRootsThenFinish, - budget == SliceBudget::Unlimited); } #endif bool isIncremental = rt->gcIncrementalState != NO_INCREMENTAL || - budget != SliceBudget::Unlimited || - zeal == ZealIncrementalRootsThenFinish || - zeal == ZealIncrementalMarkAllThenFinish; + budget != SliceBudget::Unlimited; + + if (zeal == ZealIncrementalRootsThenFinish || zeal == ZealIncrementalMarkAllThenFinish) { + /* + * Yields between slices occurs at predetermined points in these + * modes. sliceBudget is not used. + */ + sliceBudget.reset(); + } if (rt->gcIncrementalState == NO_INCREMENTAL) { rt->gcIncrementalState = MARK_ROOTS; @@ -4504,7 +4508,8 @@ RunDebugGC(JSContext *cx) rt->gcIncrementalLimit *= 2; budget = SliceBudget::WorkBudget(rt->gcIncrementalLimit); } else { - budget = SliceBudget::Unlimited; + // This triggers incremental GC but is actually ignored by IncrementalMarkSlice. + budget = SliceBudget::WorkBudget(1); } Collect(rt, true, budget, GC_NORMAL, gcreason::DEBUG_GC);