diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index 3ef53358bc10..578872cd1955 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -2851,6 +2851,9 @@ void GCRuntime::finishCollection() { for (GCZonesIter zone(this); !zone.done(); zone.next()) { zone->changeGCState(Zone::Finished, Zone::NoGC); zone->notifyObservingDebuggers(); + for (RealmsInZoneIter realm(zone); !realm.done(); realm.next()) { + realm->clearAllocatedDuringGC(); + } } #ifdef JS_GC_ZEAL diff --git a/js/src/vm/Realm-inl.h b/js/src/vm/Realm-inl.h index 39b384be7178..90331aad1921 100644 --- a/js/src/vm/Realm-inl.h +++ b/js/src/vm/Realm-inl.h @@ -35,9 +35,14 @@ inline bool JS::Realm::hasLiveGlobal() const { } inline bool JS::Realm::marked() const { - // Preserve this Realm if it has a live global or if it has been entered (to - // ensure we don't destroy the Realm while we're allocating its global). - return hasLiveGlobal() || hasBeenEnteredIgnoringJit(); + // The Realm survives in the following cases: + // - its global is live + // - it has been entered (to ensure we don't destroy the Realm while we're + // allocating its global) + // - it was allocated after the start of an incremental GC (as there may be + // pointers to it from other GC things) + return hasLiveGlobal() || hasBeenEnteredIgnoringJit() || + allocatedDuringIncrementalGC_; } /* static */ inline js::ObjectRealm& js::ObjectRealm::get(const JSObject* obj) { diff --git a/js/src/vm/Realm.cpp b/js/src/vm/Realm.cpp index 489219be7100..50253f512fad 100644 --- a/js/src/vm/Realm.cpp +++ b/js/src/vm/Realm.cpp @@ -55,6 +55,8 @@ Realm::Realm(Compartment* comp, const JS::RealmOptions& options) objects_(zone_), randomKeyGenerator_(runtime_->forkRandomKeyGenerator()), debuggers_(zone_), + allocatedDuringIncrementalGC_(zone_->isGCMarkingOrSweeping() || + zone_->isGCFinished()), wasm(runtime_) { runtime_->numRealms++; } diff --git a/js/src/vm/Realm.h b/js/src/vm/Realm.h index 385a0a9471ab..da041a76e6f1 100644 --- a/js/src/vm/Realm.h +++ b/js/src/vm/Realm.h @@ -406,6 +406,7 @@ class JS::Realm : public JS::shadow::Realm { friend class js::AutoRestoreRealmDebugMode; bool isSystem_ = false; + bool allocatedDuringIncrementalGC_; js::UniquePtr lcovRealm_ = nullptr; @@ -615,6 +616,7 @@ class JS::Realm : public JS::shadow::Realm { } inline bool marked() const; + void clearAllocatedDuringGC() { allocatedDuringIncrementalGC_ = false; } /* * The principals associated with this realm. Note that the same several