Bug 1764796 - Use the store buffer to trace preserved nursery wrappers in a minor GC r=mccr8

HeapObjectPostWriteBarrier adds or removes a store buffer entry for a change in
the GC graph entry based on the second and third arguments which are the target
of the edge before and after the change.

This patch also removes the store buffer entry in
nsWrapperCache::ReleaseWrapper which didn't happen before. This should help
keep less garbage alive unnecessarily.

Differential Revision: https://phabricator.services.mozilla.com/D143736
This commit is contained in:
Jon Coppeard 2022-04-19 08:48:33 +00:00
Родитель 5d9aa3dd08
Коммит cc1c9e02a4
3 изменённых файлов: 2 добавлений и 17 удалений

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

@ -29,7 +29,7 @@ void nsWrapperCache::HoldJSObjects(void* aScriptObjectHolder,
JS::Zone* aWrapperZone) { JS::Zone* aWrapperZone) {
cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer, aWrapperZone); cyclecollector::HoldJSObjectsImpl(aScriptObjectHolder, aTracer, aWrapperZone);
if (mWrapper && !JS::ObjectIsTenured(mWrapper)) { if (mWrapper && !JS::ObjectIsTenured(mWrapper)) {
CycleCollectedJSRuntime::Get()->NurseryWrapperPreserved(mWrapper); JS::HeapObjectPostWriteBarrier(&mWrapper, nullptr, mWrapper);
} }
} }
@ -48,6 +48,7 @@ void nsWrapperCache::ReleaseWrapper(void* aScriptObjectHolder) {
if (PreservingWrapper()) { if (PreservingWrapper()) {
SetPreservingWrapper(false); SetPreservingWrapper(false);
cyclecollector::DropJSObjectsImpl(aScriptObjectHolder); cyclecollector::DropJSObjectsImpl(aScriptObjectHolder);
JS::HeapObjectPostWriteBarrier(&mWrapper, mWrapper, nullptr);
} }
} }

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

@ -1602,14 +1602,7 @@ void CycleCollectedJSRuntime::JSObjectsTenured() {
} }
} }
#ifdef DEBUG
for (auto iter = mPreservedNurseryObjects.Iter(); !iter.Done(); iter.Next()) {
MOZ_ASSERT(JS::ObjectIsTenured(iter.Get().get()));
}
#endif
mNurseryObjects.Clear(); mNurseryObjects.Clear();
mPreservedNurseryObjects.Clear();
} }
void CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache) { void CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache) {
@ -1619,11 +1612,6 @@ void CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache) {
mNurseryObjects.InfallibleAppend(aCache); mNurseryObjects.InfallibleAppend(aCache);
} }
void CycleCollectedJSRuntime::NurseryWrapperPreserved(JSObject* aWrapper) {
mPreservedNurseryObjects.InfallibleAppend(
JS::PersistentRooted<JSObject*>(mJSRuntime, aWrapper));
}
void CycleCollectedJSRuntime::DeferredFinalize( void CycleCollectedJSRuntime::DeferredFinalize(
DeferredFinalizeAppendFunction aAppendFunc, DeferredFinalizeFunction aFunc, DeferredFinalizeAppendFunction aAppendFunc, DeferredFinalizeFunction aFunc,
void* aThing) { void* aThing) {

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

@ -401,7 +401,6 @@ class CycleCollectedJSRuntime {
// storage), because we do not want to keep it alive. nsWrapperCache handles // storage), because we do not want to keep it alive. nsWrapperCache handles
// this for us via its "object moved" handling. // this for us via its "object moved" handling.
void NurseryWrapperAdded(nsWrapperCache* aCache); void NurseryWrapperAdded(nsWrapperCache* aCache);
void NurseryWrapperPreserved(JSObject* aWrapper);
void JSObjectsTenured(); void JSObjectsTenured();
void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc, void DeferredFinalize(DeferredFinalizeAppendFunction aAppendFunc,
@ -465,9 +464,6 @@ class CycleCollectedJSRuntime {
static const size_t kSegmentSize = 512; static const size_t kSegmentSize = 512;
SegmentedVector<nsWrapperCache*, kSegmentSize, InfallibleAllocPolicy> SegmentedVector<nsWrapperCache*, kSegmentSize, InfallibleAllocPolicy>
mNurseryObjects; mNurseryObjects;
SegmentedVector<JS::PersistentRooted<JSObject*>, kSegmentSize,
InfallibleAllocPolicy>
mPreservedNurseryObjects;
nsTHashSet<JS::Zone*> mZonesWaitingForGC; nsTHashSet<JS::Zone*> mZonesWaitingForGC;