104 lines
3.6 KiB
Diff
104 lines
3.6 KiB
Diff
From bb3a58359a268e13758b5b1e4ba2b27990debb16 Mon Sep 17 00:00:00 2001
|
|
From: Jon Coppeard <jcoppeard@mozilla.com>
|
|
Date: Wed, 10 Jul 2024 15:01:49 +0800
|
|
Subject: [PATCH] Don't sweep realms that were allocated during incremental GC r=jandem
|
|
|
|
---
|
|
js/public/HeapAPI.h | 4 +++-
|
|
js/src/gc/GC.cpp | 4 ++++
|
|
js/src/vm/Realm-inl.h | 12 +++++++++---
|
|
js/src/vm/Realm.cpp | 2 ++
|
|
js/src/vm/Realm.h | 3 ++-
|
|
5 files changed, 20 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h
|
|
index 593396288d..9c0192488d 100644
|
|
--- a/js/public/HeapAPI.h
|
|
+++ b/js/public/HeapAPI.h
|
|
@@ -237,7 +237,9 @@ struct Zone {
|
|
bool isGCSweepingOrCompacting() const {
|
|
return gcState_ == Sweep || gcState_ == Compact;
|
|
}
|
|
-
|
|
+ bool isGCMarkingOrSweeping() const {
|
|
+ return gcState() >= MarkBlackOnly && gcState() <= Sweep;
|
|
+ }
|
|
static MOZ_ALWAYS_INLINE JS::shadow::Zone* from(JS::Zone* zone) {
|
|
return reinterpret_cast<JS::shadow::Zone*>(zone);
|
|
}
|
|
diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp
|
|
index 59b56f297a..a30e9fdbdc 100644
|
|
--- a/js/src/gc/GC.cpp
|
|
+++ b/js/src/gc/GC.cpp
|
|
@@ -6365,6 +6365,10 @@ void GCRuntime::finishCollection() {
|
|
zone->notifyObservingDebuggers();
|
|
zone->updateGCStartThresholds(*this, invocationKind, lock);
|
|
zone->arenas.checkGCStateNotInUse();
|
|
+ for (RealmsInZoneIter realm(zone); !realm.done(); realm.next()) {
|
|
+ realm->clearAllocatedDuringGC();
|
|
+ }
|
|
+
|
|
}
|
|
}
|
|
|
|
diff --git a/js/src/vm/Realm-inl.h b/js/src/vm/Realm-inl.h
|
|
index 4672d976ad..4f7a000f5a 100644
|
|
--- a/js/src/vm/Realm-inl.h
|
|
+++ b/js/src/vm/Realm-inl.h
|
|
@@ -46,9 +46,15 @@ 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 29a9f14d8d..64d727f191 100644
|
|
--- a/js/src/vm/Realm.cpp
|
|
+++ b/js/src/vm/Realm.cpp
|
|
@@ -59,6 +59,8 @@ Realm::Realm(Compartment* comp, const JS::RealmOptions& options)
|
|
varNames_(zone_),
|
|
randomKeyGenerator_(runtime_->forkRandomKeyGenerator()),
|
|
debuggers_(zone_),
|
|
+ allocatedDuringIncrementalGC_(zone_->isGCMarkingOrSweeping() ||
|
|
+ zone_->isGCFinished()),
|
|
wasm(runtime_) {
|
|
MOZ_ASSERT_IF(creationOptions_.mergeable(),
|
|
creationOptions_.invisibleToDebugger());
|
|
diff --git a/js/src/vm/Realm.h b/js/src/vm/Realm.h
|
|
index 591ac3feab..de7b8204b2 100644
|
|
--- a/js/src/vm/Realm.h
|
|
+++ b/js/src/vm/Realm.h
|
|
@@ -427,7 +427,7 @@ class JS::Realm : public JS::shadow::Realm {
|
|
|
|
bool isSelfHostingRealm_ = false;
|
|
bool isSystem_ = false;
|
|
-
|
|
+ bool allocatedDuringIncrementalGC_;
|
|
js::UniquePtr<js::coverage::LCovRealm> lcovRealm_ = nullptr;
|
|
|
|
public:
|
|
@@ -656,6 +656,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
|
|
--
|
|
2.27.0
|
|
|