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
Родитель 3f910a70b0
Коммит a1ea9b8f5a
4 изменённых файлов: 74 добавлений и 48 удалений

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

@ -160,7 +160,7 @@ function loadCallgraph(file)
suppressedFunctions[name] = true;
}
for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, js::SliceBudget*, uint32, uint32)',
for (var gcName of [ 'void js::gc::GCRuntime::collect(uint8, js::SliceBudget, uint32)',
'void js::gc::GCRuntime::minorGC(uint32)',
'void js::gc::GCRuntime::minorGC(uint32)' ])
{

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

@ -326,8 +326,9 @@ class GCRuntime
}
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();
@ -567,10 +568,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 *)

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

@ -5785,9 +5785,16 @@ GCRuntime::resetIncrementalGC(const char *reason)
/* Finish sweeping the current zone group, then abort. */
abortSweepAfterCurrentGroup = true;
/* Don't perform any compaction after sweeping. */
JSGCInvocationKind oldInvocationKind = invocationKind;
invocationKind = GC_NORMAL;
SliceBudget budget;
incrementalCollectSlice(budget, JS::gcreason::RESET);
invocationKind = oldInvocationKind;
{
gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD);
rt->gc.waitBackgroundSweepOrAllocEnd();
@ -6110,8 +6117,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)
{
evictNursery(reason);
@ -6174,10 +6180,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
@ -6262,8 +6264,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());
@ -6290,9 +6291,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 {
@ -6307,7 +6308,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);
@ -6349,34 +6350,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
@ -6400,9 +6415,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;
@ -6422,12 +6437,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. */
@ -6546,10 +6563,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;
}
@ -6714,7 +6735,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
@ -6726,9 +6749,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