Allow incremental GC when keepAtoms is set

This is a port of BZ 1213977 that should improve performance when parsing
large web-sites by reducing the amount of non-incremental (large) GCing.
This commit is contained in:
Amelia Hart 2026-07-27 18:03:24 +02:00 committed by wuggy
commit 37f37bd489
2 changed files with 20 additions and 8 deletions

View file

@ -3642,14 +3642,22 @@ GCRuntime::beginMarkPhase(JS::gcreason::Reason reason, AutoLockForExclusiveAcces
}
/*
* Atoms are not in the cross-compartment map. So if there are any
* zones that are not being collected, we are not allowed to collect
* atoms. Otherwise, the non-collected zones could contain pointers
* to atoms that we would miss.
* Atoms are not in the cross-compartment map. If there are any zones that
* are not being collected then we cannot collect the atoms zone, otherwise
* the non-collected zones could contain pointers to atoms that we would
* miss.
*
* keepAtoms() will only change on the main thread, which we are currently
* on. If the value of keepAtoms() changes between GC slices, then we'll
* cancel the incremental GC. See IsIncrementalGCSafe.
* If keepAtoms() is true then either an instance of AutoKeepAtoms is
* currently on the stack or parsing is currently happening on another
* thread. In either case we don't have information about which atoms are
* roots, so we must skip collecting atoms.
*
* Note that only affects the first slice of an incremental GC since root
* marking is completed before we return to the mutator.
*
* Off-main-thread parsing is inhibited after the start of GC which prevents
* races between creating atoms during parsing and sweeping atoms on the
* main thread.
*/
if (isFull && !rt->keepAtoms()) {
@ -5732,6 +5740,10 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
State prevState = incrementalState;
// We don't allow off-main-thread parsing to start while we're doing an
// incremental GC.
MOZ_ASSERT_IF(rt->activeGCInAtomsZone(), !rt->exclusiveThreadsPresent());
if (nonincrementalByAPI) {
// Reset any in progress incremental GC if this was triggered via the
// API. This isn't required for correctness, but sometimes during tests

View file

@ -56,7 +56,7 @@ enum class State {
D(None) \
D(NonIncrementalRequested) \
D(AbortRequested) \
D(KeepAtomsSet) \
D(Unused1) \
D(IncrementalDisabled) \
D(ModeChange) \
D(MallocBytesTrigger) \