Bug 1099152 - Separate out methods to start and continue incrmental GC r=terrence

This commit is contained in:
Jon Coppeard 2015-01-02 17:19:43 +00:00
Родитель e4ab51b4a6
Коммит 868306e7f4
3 изменённых файлов: 66 добавлений и 47 удалений

Просмотреть файл

@ -320,8 +320,9 @@ class GCRuntime
void evictNursery(JS::gcreason::Reason reason = JS::gcreason::EVICT_NURSERY) { minorGC(reason); }
bool gcIfNeeded(JSContext *cx = nullptr);
void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
void gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
void gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
void startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
void gcSlice(JS::gcreason::Reason reason, int64_t millis = 0);
void finishGC(JS::gcreason::Reason reason);
void gcDebugSlice(SliceBudget &budget);
void runDebugGC();
@ -558,10 +559,9 @@ class GCRuntime
void startBackgroundAllocTaskIfIdle();
void requestMajorGC(JS::gcreason::Reason reason);
void collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason);
bool gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason);
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis);
void collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason);
bool gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason reason);
gcstats::ZoneGCStats scanZonesBeforeGC();
void budgetIncrementalGC(SliceBudget &budget);
void resetIncrementalGC(const char *reason);

Просмотреть файл

@ -210,13 +210,16 @@ JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
JS_FRIEND_API(void)
JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
{
rt->gc.gcSlice(GC_NORMAL, reason, millis);
if (!rt->gc.isIncrementalGCInProgress())
rt->gc.startGC(GC_NORMAL, reason, millis);
else
rt->gc.gcSlice(reason, millis);
}
JS_FRIEND_API(void)
JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason)
{
rt->gc.gcFinalSlice(GC_NORMAL, reason);
rt->gc.finishGC(reason);
}
JS_FRIEND_API(JSPrincipals *)

Просмотреть файл

@ -6088,8 +6088,7 @@ class AutoDisableStoreBuffer
* to run another cycle.
*/
MOZ_NEVER_INLINE bool
GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason)
GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JS::gcreason::Reason reason)
{
minorGC(reason);
@ -6152,10 +6151,6 @@ GCRuntime::gcCycle(bool incremental, SliceBudget &budget, JSGCInvocationKind gck
TraceMajorGCStart();
/* Set the invocation kind in the first slice. */
if (!isIncrementalGCInProgress())
invocationKind = gckind;
incrementalCollectSlice(budget, reason);
#ifndef JS_MORE_DETERMINISTIC
@ -6240,8 +6235,7 @@ GCRuntime::scanZonesBeforeGC()
}
void
GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gckind,
JS::gcreason::Reason reason)
GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason)
{
/* GC shouldn't be running in parallel execution mode */
MOZ_ALWAYS_TRUE(!InParallelSection());
@ -6268,9 +6262,9 @@ GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gck
AutoStopVerifyingBarriers av(rt, reason == JS::gcreason::SHUTDOWN_CC ||
reason == JS::gcreason::DESTROY_RUNTIME);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), gckind, reason);
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, reason);
cleanUpEverything = ShouldCleanUpEverything(reason, gckind);
cleanUpEverything = ShouldCleanUpEverything(reason, invocationKind);
bool repeat = false;
do {
@ -6285,7 +6279,7 @@ GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gck
}
poked = false;
bool wasReset = gcCycle(incremental, budget, gckind, reason);
bool wasReset = gcCycle(incremental, budget, reason);
if (!isIncrementalGCInProgress()) {
gcstats::AutoPhase ap(stats, gcstats::PHASE_GC_END);
@ -6327,34 +6321,48 @@ GCRuntime::collect(bool incremental, SliceBudget &budget, JSGCInvocationKind gck
EnqueuePendingParseTasksAfterGC(rt);
}
SliceBudget
GCRuntime::defaultBudget(JS::gcreason::Reason reason, int64_t millis)
{
if (millis == 0) {
if (reason == JS::gcreason::ALLOC_TRIGGER)
millis = sliceBudget;
else if (schedulingState.inHighFrequencyGCMode() && tunables.isDynamicMarkSliceEnabled())
millis = sliceBudget * IGC_MARK_SLICE_MULTIPLIER;
else
millis = sliceBudget;
}
return SliceBudget(TimeBudget(millis));
}
void
GCRuntime::gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason)
{
SliceBudget budget;
collect(false, budget, gckind, reason);
invocationKind = gckind;
collect(false, SliceBudget(), reason);
}
void
GCRuntime::gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis)
GCRuntime::startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis)
{
SliceBudget budget;
if (millis)
budget = SliceBudget(TimeBudget(millis));
else if (reason == JS::gcreason::ALLOC_TRIGGER)
budget = SliceBudget(TimeBudget(sliceBudget));
else if (schedulingState.inHighFrequencyGCMode() && tunables.isDynamicMarkSliceEnabled())
budget = SliceBudget(TimeBudget(sliceBudget * IGC_MARK_SLICE_MULTIPLIER));
else
budget = SliceBudget(TimeBudget(sliceBudget));
collect(true, budget, gckind, reason);
MOZ_ASSERT(!isIncrementalGCInProgress());
invocationKind = gckind;
collect(true, defaultBudget(reason, millis), reason);
}
void
GCRuntime::gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason)
GCRuntime::gcSlice(JS::gcreason::Reason reason, int64_t millis)
{
SliceBudget budget;
collect(true, budget, gckind, reason);
MOZ_ASSERT(isIncrementalGCInProgress());
collect(true, defaultBudget(reason, millis), reason);
}
void
GCRuntime::finishGC(JS::gcreason::Reason reason)
{
MOZ_ASSERT(isIncrementalGCInProgress());
collect(true, SliceBudget(), reason);
}
void
@ -6378,9 +6386,9 @@ GCRuntime::notifyDidPaint()
}
#endif
if (JS::IsIncrementalGCInProgress(rt) && !interFrameGC) {
if (isIncrementalGCInProgress() && !interFrameGC) {
JS::PrepareForIncrementalGC(rt);
gcSlice(GC_NORMAL, JS::gcreason::REFRESH_FRAME);
gcSlice(JS::gcreason::REFRESH_FRAME);
}
interFrameGC = false;
@ -6400,12 +6408,14 @@ void
GCRuntime::gcDebugSlice(SliceBudget &budget)
{
if (!ZonesSelected(rt)) {
if (JS::IsIncrementalGCInProgress(rt))
if (isIncrementalGCInProgress())
JS::PrepareForIncrementalGC(rt);
else
JS::PrepareForFullGC(rt);
}
collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
if (!isIncrementalGCInProgress())
invocationKind = GC_NORMAL;
collect(true, budget, JS::gcreason::DEBUG_GC);
}
/* Schedule a full GC unless a zone will already be collected. */
@ -6526,10 +6536,14 @@ GCRuntime::gcIfNeeded(JSContext *cx /* = nullptr */)
}
if (majorGCRequested) {
if (rt->gc.majorGCTriggerReason == JS::gcreason::INCREMENTAL_ALLOC_TRIGGER)
gcSlice(GC_NORMAL, rt->gc.majorGCTriggerReason);
else
gc(GC_NORMAL, rt->gc.majorGCTriggerReason);
if (majorGCTriggerReason == JS::gcreason::INCREMENTAL_ALLOC_TRIGGER) {
if (!isIncrementalGCInProgress())
startGC(GC_NORMAL, majorGCTriggerReason);
else
gcSlice(majorGCTriggerReason);
} else {
gc(GC_NORMAL, majorGCTriggerReason);
}
return true;
}
@ -6694,7 +6708,9 @@ GCRuntime::runDebugGC()
budget = SliceBudget(WorkBudget(1));
}
collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
if (!isIncrementalGCInProgress())
invocationKind = GC_NORMAL;
collect(true, budget, JS::gcreason::DEBUG_GC);
/*
* For multi-slice zeal, reset the slice size when we get to the sweep
@ -6706,9 +6722,9 @@ GCRuntime::runDebugGC()
incrementalLimit = zealFrequency / 2;
}
} else if (type == ZealCompactValue) {
collect(false, budget, GC_SHRINK, JS::gcreason::DEBUG_GC);
gc(GC_SHRINK, JS::gcreason::DEBUG_GC);
} else {
collect(false, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
gc(GC_NORMAL, JS::gcreason::DEBUG_GC);
}
#endif