Bug 1669669 - Don't mark or sweep permanent atoms r=sfink

Differential Revision: https://phabricator.services.mozilla.com/D121392
This commit is contained in:
Jon Coppeard 2021-08-02 08:58:00 +00:00
Родитель ab4d1a3f8c
Коммит 37016a9847
5 изменённых файлов: 61 добавлений и 12 удалений

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

@ -1646,6 +1646,49 @@ void GCRuntime::finish() {
stats().printTotalProfileTimes();
}
void GCRuntime::freezePermanentAtoms() {
// This is called just after the permanent atoms have been created. At this
// point all existing atoms are permanent. Move the arenas containing atoms
// out of atoms zone arena lists until shutdown. Since we won't sweep them, we
// don't need to mark them at the start of every GC.
MOZ_ASSERT(atomsZone);
MOZ_ASSERT(zones().empty());
atomsZone->arenas.clearFreeLists();
freezePermanentAtomsOfKind(AllocKind::ATOM, permanentAtoms.ref());
freezePermanentAtomsOfKind(AllocKind::FAT_INLINE_ATOM,
permanentFatInlineAtoms.ref());
}
void GCRuntime::freezePermanentAtomsOfKind(AllocKind kind,
ArenaList& arenaList) {
for (auto atom = atomsZone->cellIterUnsafe<JSAtom>(kind); !atom.done();
atom.next()) {
MOZ_ASSERT(atom->isPermanentAtom());
atom->asTenured().markBlack();
}
arenaList = std::move(atomsZone->arenas.arenaList(kind));
}
void GCRuntime::restorePermanentAtoms() {
// Move the arenas containing permanent atoms that were removed by
// freezePermanentAtoms() back to the atoms zone arena lists so we can collect
// them.
MOZ_ASSERT(heapState() == JS::HeapState::MajorCollecting);
restorePermanentAtomsOfKind(AllocKind::ATOM, permanentAtoms.ref());
restorePermanentAtomsOfKind(AllocKind::FAT_INLINE_ATOM,
permanentFatInlineAtoms.ref());
}
void GCRuntime::restorePermanentAtomsOfKind(AllocKind kind,
ArenaList& arenaList) {
atomsZone->arenas.arenaList(kind).insertListWithCursorAtEnd(arenaList);
}
bool GCRuntime::setParameter(JSGCParamKey key, uint32_t value) {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
waitBackgroundSweepEnd();
@ -4414,6 +4457,10 @@ bool GCRuntime::beginPreparePhase(JS::GCReason reason, AutoGCSession& session) {
session.maybeCheckAtomsAccess.emplace(rt);
}
if (reason == JS::GCReason::DESTROY_RUNTIME) {
restorePermanentAtoms();
}
/*
* Start a parallel task to clear all mark state for the zones we are
* collecting. This is linear in the size of the heap we are collecting and so

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

@ -288,6 +288,11 @@ class GCRuntime {
void finishRoots();
void finish();
void freezePermanentAtoms();
void freezePermanentAtomsOfKind(AllocKind kind, ArenaList& arenaList);
void restorePermanentAtoms();
void restorePermanentAtomsOfKind(AllocKind kind, ArenaList& arenaList);
JS::HeapState heapState() const { return heapState_; }
inline bool hasZealMode(ZealMode mode);
@ -934,6 +939,10 @@ class GCRuntime {
AtomMarkingRuntime atomMarking;
private:
// Arenas used for permanent atoms and static strings created at startup.
MainThreadData<ArenaList> permanentAtoms;
MainThreadData<ArenaList> permanentFatInlineAtoms;
// When chunks are empty, they reside in the emptyChunks pool and are
// re-used as needed or eventually expired if not re-used. The emptyChunks
// pool gets refilled from the background allocation task heuristically so

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

@ -311,7 +311,7 @@ void js::gc::GCRuntime::traceRuntime(JSTracer* trc, AutoTraceSession& session) {
void js::gc::GCRuntime::traceRuntimeAtoms(JSTracer* trc,
const AutoAccessAtomsZone& access) {
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::MARK_RUNTIME_DATA);
rt->tracePermanentAtoms(trc);
rt->tracePermanentAtomsDuringInit(trc);
TraceAtoms(trc, access);
TraceWellKnownSymbols(trc);
jit::JitRuntime::TraceAtomZoneRoots(trc, access);

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

@ -446,24 +446,15 @@ static void TracePermanentAtoms(JSTracer* trc, AtomSet::Range atoms) {
}
}
void JSRuntime::tracePermanentAtoms(JSTracer* trc) {
void JSRuntime::tracePermanentAtomsDuringInit(JSTracer* trc) {
// Permanent atoms only need to be traced in the runtime which owns them.
if (parentRuntime) {
return;
}
// Static strings are not included in the permanent atoms table.
if (staticStrings) {
staticStrings->trace(trc);
}
if (permanentAtomsDuringInit_) {
TracePermanentAtoms(trc, permanentAtomsDuringInit_->all());
}
if (permanentAtoms_) {
TracePermanentAtoms(trc, permanentAtoms_->all());
}
}
void js::TraceWellKnownSymbols(JSTracer* trc) {
@ -636,6 +627,8 @@ bool JSRuntime::initMainAtomsTables(JSContext* cx) {
MOZ_ASSERT(!parentRuntime);
MOZ_ASSERT(!permanentAtomsPopulated());
gc.freezePermanentAtoms();
// The permanent atoms table has now been populated.
permanentAtoms_ =
js_new<FrozenAtomSet>(permanentAtomsDuringInit_); // Takes ownership.

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

@ -860,7 +860,7 @@ struct JSRuntime {
}
bool initMainAtomsTables(JSContext* cx);
void tracePermanentAtoms(JSTracer* trc);
void tracePermanentAtomsDuringInit(JSTracer* trc);
// Cached well-known symbols (ES6 rev 24 6.1.5.1). Like permanent atoms,
// these are shared with the parentRuntime, if any.