зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1453028 - Rename GC zeal modes that run in two slices and refactor r=sfink
This commit is contained in:
Родитель
5bae58b082
Коммит
f69380bdd2
119
js/src/gc/GC.cpp
119
js/src/gc/GC.cpp
|
@ -1020,30 +1020,34 @@ const char* gc::ZealModeHelpText =
|
|||
" both modes 2 and 4. Modes can be specified by name or number.\n"
|
||||
" \n"
|
||||
" Values:\n"
|
||||
" 0: (None) Normal amount of collection (resets all modes)\n"
|
||||
" 1: (RootsChange) Collect when roots are added or removed\n"
|
||||
" 2: (Alloc) Collect when every N allocations (default: 100)\n"
|
||||
" 4: (VerifierPre) Verify pre write barriers between instructions\n"
|
||||
" 7: (GenerationalGC) Collect the nursery every N nursery allocations\n"
|
||||
" 8: (IncrementalRootsThenFinish) Incremental GC in two slices: 1) mark roots 2) finish collection\n"
|
||||
" 9: (IncrementalMarkAllThenFinish) Incremental GC in two slices: 1) mark all 2) new marking and finish\n"
|
||||
" 10: (IncrementalMultipleSlices) Incremental GC in multiple slices\n"
|
||||
" 11: (IncrementalMarkingValidator) Verify incremental marking\n"
|
||||
" 12: (ElementsBarrier) Always use the individual element post-write barrier, regardless of elements size\n"
|
||||
" 13: (CheckHashTablesOnMinorGC) Check internal hashtables on minor GC\n"
|
||||
" 14: (Compact) Perform a shrinking collection every N allocations\n"
|
||||
" 15: (CheckHeapAfterGC) Walk the heap to check its integrity after every GC\n"
|
||||
" 16: (CheckNursery) Check nursery integrity on minor GC\n"
|
||||
" 17: (IncrementalSweepThenFinish) Incremental GC in two slices: 1) start sweeping 2) finish collection\n"
|
||||
" 18: (CheckGrayMarking) Check gray marking invariants after every GC\n";
|
||||
" 0: (None) Normal amount of collection (resets all modes)\n"
|
||||
" 1: (RootsChange) Collect when roots are added or removed\n"
|
||||
" 2: (Alloc) Collect when every N allocations (default: 100)\n"
|
||||
" 4: (VerifierPre) Verify pre write barriers between instructions\n"
|
||||
" 7: (GenerationalGC) Collect the nursery every N nursery allocations\n"
|
||||
" 8: (YieldBeforeMarking) Incremental GC in two slices that yields between\n"
|
||||
" the root marking and marking phases\n"
|
||||
" 9: (YieldBeforeSweeping) Incremental GC in two slices that yields between\n"
|
||||
" the marking and sweeping phases\n"
|
||||
" 10: (IncrementalMultipleSlices) Incremental GC in many slices\n"
|
||||
" 11: (IncrementalMarkingValidator) Verify incremental marking\n"
|
||||
" 12: (ElementsBarrier) Use the individual element post-write barrier\n"
|
||||
" regardless of elements size\n"
|
||||
" 13: (CheckHashTablesOnMinorGC) Check internal hashtables on minor GC\n"
|
||||
" 14: (Compact) Perform a shrinking collection every N allocations\n"
|
||||
" 15: (CheckHeapAfterGC) Walk the heap to check its integrity after every GC\n"
|
||||
" 16: (CheckNursery) Check nursery integrity on minor GC\n"
|
||||
" 17: (YieldBeforeSweepingAtoms) Incremental GC in two slices that yields\n"
|
||||
" before sweeping the atoms table\n"
|
||||
" 18: (CheckGrayMarking) Check gray marking invariants after every GC\n";
|
||||
|
||||
// The set of zeal modes that control incremental slices. These modes are
|
||||
// mutually exclusive.
|
||||
static const mozilla::EnumSet<ZealMode> IncrementalSliceZealModes = {
|
||||
ZealMode::IncrementalRootsThenFinish,
|
||||
ZealMode::IncrementalMarkAllThenFinish,
|
||||
ZealMode::YieldBeforeMarking,
|
||||
ZealMode::YieldBeforeSweeping,
|
||||
ZealMode::IncrementalMultipleSlices,
|
||||
ZealMode::IncrementalSweepThenFinish
|
||||
ZealMode::YieldBeforeSweepingAtoms
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -4987,9 +4991,9 @@ GCRuntime::groupZonesForSweeping(JS::gcreason::Reason reason)
|
|||
finder.useOneComponent();
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Use one component for IncrementalSweepThenFinish zeal mode.
|
||||
// Use one component for YieldBeforeSweepingAtoms zeal mode.
|
||||
if (isIncremental && reason == JS::gcreason::DEBUG_GC &&
|
||||
hasZealMode(ZealMode::IncrementalSweepThenFinish))
|
||||
hasZealMode(ZealMode::YieldBeforeSweepingAtoms))
|
||||
{
|
||||
finder.useOneComponent();
|
||||
}
|
||||
|
@ -5741,7 +5745,7 @@ GCRuntime::maybeYieldForSweepingZeal(FreeOp* fop, SliceBudget& budget)
|
|||
*/
|
||||
if (isIncremental && useZeal && initialState != State::Sweep &&
|
||||
(hasZealMode(ZealMode::IncrementalMultipleSlices) ||
|
||||
hasZealMode(ZealMode::IncrementalSweepThenFinish)))
|
||||
hasZealMode(ZealMode::YieldBeforeSweepingAtoms)))
|
||||
{
|
||||
return NotFinished;
|
||||
}
|
||||
|
@ -6987,10 +6991,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
|
|||
|
||||
isIncremental = !budget.isUnlimited();
|
||||
|
||||
if (useZeal && (hasZealMode(ZealMode::IncrementalRootsThenFinish) ||
|
||||
hasZealMode(ZealMode::IncrementalMarkAllThenFinish) ||
|
||||
hasZealMode(ZealMode::IncrementalSweepThenFinish)))
|
||||
{
|
||||
if (useZeal && hasIncrementalTwoSliceZealMode()) {
|
||||
/*
|
||||
* Yields between slices occurs at predetermined points in these modes;
|
||||
* the budget is not used.
|
||||
|
@ -7021,7 +7022,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
|
|||
|
||||
incrementalState = State::Mark;
|
||||
|
||||
if (isIncremental && useZeal && hasZealMode(ZealMode::IncrementalRootsThenFinish))
|
||||
if (isIncremental && useZeal && hasZealMode(ZealMode::YieldBeforeMarking))
|
||||
break;
|
||||
|
||||
MOZ_FALLTHROUGH;
|
||||
|
@ -7047,16 +7048,16 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
|
|||
* the next slice, since the first slice of sweeping can be expensive.
|
||||
*
|
||||
* This is modified by the various zeal modes. We don't yield in
|
||||
* IncrementalRootsThenFinish mode and we always yield in
|
||||
* IncrementalMarkAllThenFinish mode.
|
||||
* YieldBeforeMarking mode and we always yield in YieldBeforeSweeping
|
||||
* mode.
|
||||
*
|
||||
* We will need to mark anything new on the stack when we resume, so
|
||||
* we stay in Mark state.
|
||||
*/
|
||||
if (!lastMarkSlice && isIncremental &&
|
||||
((initialState == State::Mark &&
|
||||
!(useZeal && hasZealMode(ZealMode::IncrementalRootsThenFinish))) ||
|
||||
(useZeal && hasZealMode(ZealMode::IncrementalMarkAllThenFinish))))
|
||||
!(useZeal && hasZealMode(ZealMode::YieldBeforeMarking))) ||
|
||||
(useZeal && hasZealMode(ZealMode::YieldBeforeSweeping))))
|
||||
{
|
||||
lastMarkSlice = true;
|
||||
break;
|
||||
|
@ -8067,43 +8068,37 @@ GCRuntime::runDebugGC()
|
|||
PrepareForDebugGC(rt);
|
||||
|
||||
auto budget = SliceBudget::unlimited();
|
||||
if (hasZealMode(ZealMode::IncrementalRootsThenFinish) ||
|
||||
hasZealMode(ZealMode::IncrementalMarkAllThenFinish) ||
|
||||
hasZealMode(ZealMode::IncrementalMultipleSlices) ||
|
||||
hasZealMode(ZealMode::IncrementalSweepThenFinish))
|
||||
{
|
||||
js::gc::State initialState = incrementalState;
|
||||
if (hasZealMode(ZealMode::IncrementalMultipleSlices)) {
|
||||
/*
|
||||
* Start with a small slice limit and double it every slice. This
|
||||
* ensure that we get multiple slices, and collection runs to
|
||||
* completion.
|
||||
*/
|
||||
if (!isIncrementalGCInProgress())
|
||||
incrementalLimit = zealFrequency / 2;
|
||||
else
|
||||
incrementalLimit *= 2;
|
||||
budget = SliceBudget(WorkBudget(incrementalLimit));
|
||||
} else {
|
||||
// This triggers incremental GC but is actually ignored by IncrementalMarkSlice.
|
||||
budget = SliceBudget(WorkBudget(1));
|
||||
}
|
||||
if (hasZealMode(ZealMode::IncrementalMultipleSlices)) {
|
||||
/*
|
||||
* Start with a small slice limit and double it every slice. This
|
||||
* ensure that we get multiple slices, and collection runs to
|
||||
* completion.
|
||||
*/
|
||||
if (!isIncrementalGCInProgress())
|
||||
incrementalLimit = zealFrequency / 2;
|
||||
else
|
||||
incrementalLimit *= 2;
|
||||
budget = SliceBudget(WorkBudget(incrementalLimit));
|
||||
|
||||
js::gc::State initialState = incrementalState;
|
||||
if (!isIncrementalGCInProgress())
|
||||
invocationKind = GC_SHRINK;
|
||||
collect(false, budget, JS::gcreason::DEBUG_GC);
|
||||
|
||||
/*
|
||||
* For multi-slice zeal, reset the slice size when we get to the sweep
|
||||
* or compact phases.
|
||||
*/
|
||||
if (hasZealMode(ZealMode::IncrementalMultipleSlices)) {
|
||||
if ((initialState == State::Mark && incrementalState == State::Sweep) ||
|
||||
(initialState == State::Sweep && incrementalState == State::Compact))
|
||||
{
|
||||
incrementalLimit = zealFrequency / 2;
|
||||
}
|
||||
/* Reset the slice size when we get to the sweep or compact phases. */
|
||||
if ((initialState == State::Mark && incrementalState == State::Sweep) ||
|
||||
(initialState == State::Sweep && incrementalState == State::Compact))
|
||||
{
|
||||
incrementalLimit = zealFrequency / 2;
|
||||
}
|
||||
} else if (hasIncrementalTwoSliceZealMode()) {
|
||||
// These modes trigger incremental GC that happens in two slices and the
|
||||
// supplied budget is ignored by incrementalCollectSlice.
|
||||
budget = SliceBudget(WorkBudget(1));
|
||||
|
||||
if (!isIncrementalGCInProgress())
|
||||
invocationKind = GC_NORMAL;
|
||||
collect(false, budget, JS::gcreason::DEBUG_GC);
|
||||
} else if (hasZealMode(ZealMode::Compact)) {
|
||||
gc(GC_SHRINK, JS::gcreason::DEBUG_GC);
|
||||
} else {
|
||||
|
|
|
@ -62,8 +62,8 @@ enum class AbortReason {
|
|||
D(Alloc, 2) \
|
||||
D(VerifierPre, 4) \
|
||||
D(GenerationalGC, 7) \
|
||||
D(IncrementalRootsThenFinish, 8) \
|
||||
D(IncrementalMarkAllThenFinish, 9) \
|
||||
D(YieldBeforeMarking, 8) \
|
||||
D(YieldBeforeSweeping, 9) \
|
||||
D(IncrementalMultipleSlices, 10) \
|
||||
D(IncrementalMarkingValidator, 11) \
|
||||
D(ElementsBarrier, 12) \
|
||||
|
@ -71,7 +71,7 @@ enum class AbortReason {
|
|||
D(Compact, 14) \
|
||||
D(CheckHeapAfterGC, 15) \
|
||||
D(CheckNursery, 16) \
|
||||
D(IncrementalSweepThenFinish, 17) \
|
||||
D(YieldBeforeSweepingAtoms, 17) \
|
||||
D(CheckGrayMarking, 18)
|
||||
|
||||
enum class ZealMode {
|
||||
|
|
|
@ -230,6 +230,7 @@ class GCRuntime
|
|||
inline void clearZealMode(ZealMode mode);
|
||||
inline bool upcomingZealousGC();
|
||||
inline bool needZealousGC();
|
||||
inline bool hasIncrementalTwoSliceZealMode();
|
||||
|
||||
MOZ_MUST_USE bool addRoot(Value* vp, const char* name);
|
||||
void removeRoot(Value* vp);
|
||||
|
@ -1026,11 +1027,11 @@ GCRuntime::needZealousGC() {
|
|||
if (nextScheduled > 0 && --nextScheduled == 0) {
|
||||
if (hasZealMode(ZealMode::Alloc) ||
|
||||
hasZealMode(ZealMode::GenerationalGC) ||
|
||||
hasZealMode(ZealMode::IncrementalRootsThenFinish) ||
|
||||
hasZealMode(ZealMode::IncrementalMarkAllThenFinish) ||
|
||||
hasZealMode(ZealMode::YieldBeforeMarking) ||
|
||||
hasZealMode(ZealMode::YieldBeforeSweeping) ||
|
||||
hasZealMode(ZealMode::IncrementalMultipleSlices) ||
|
||||
hasZealMode(ZealMode::Compact) ||
|
||||
hasZealMode(ZealMode::IncrementalSweepThenFinish))
|
||||
hasZealMode(ZealMode::YieldBeforeSweepingAtoms))
|
||||
{
|
||||
nextScheduled = zealFrequency;
|
||||
}
|
||||
|
@ -1038,11 +1039,20 @@ GCRuntime::needZealousGC() {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
GCRuntime::hasIncrementalTwoSliceZealMode() {
|
||||
return hasZealMode(ZealMode::YieldBeforeMarking) ||
|
||||
hasZealMode(ZealMode::YieldBeforeSweeping) ||
|
||||
hasZealMode(ZealMode::YieldBeforeSweepingAtoms);
|
||||
}
|
||||
|
||||
#else
|
||||
inline bool GCRuntime::hasZealMode(ZealMode mode) { return false; }
|
||||
inline void GCRuntime::clearZealMode(ZealMode mode) { }
|
||||
inline bool GCRuntime::upcomingZealousGC() { return false; }
|
||||
inline bool GCRuntime::needZealousGC() { return false; }
|
||||
inline bool GCRuntime::hasIncrementalTwoSliceZealMode() { return false; }
|
||||
#endif
|
||||
|
||||
} /* namespace gc */
|
||||
|
|
Загрузка…
Ссылка в новой задаче