зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1099152 - Separate out methods to start and continue incrmental GC r=terrence
This commit is contained in:
Родитель
3f910a70b0
Коммит
a1ea9b8f5a
|
@ -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 *)
|
||||
|
|
101
js/src/jsgc.cpp
101
js/src/jsgc.cpp
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче