Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 5e4ff7aa732e8f62d5536aa65527564b7b70cc63
https://github.com/WebKit/WebKit/commit/5e4ff7aa732e8f62d5536aa65527564b7b70cc63
Author: Dan Hecht <[email protected]>
Date: 2026-10-12 (Mon, 12 Oct 2026)
Changed paths:
M Source/JavaScriptCore/API/tests/testapi.cpp
M Source/JavaScriptCore/heap/Collector.cpp
M Source/JavaScriptCore/heap/Collector.h
M Source/JavaScriptCore/heap/Heap.cpp
M Source/JavaScriptCore/heap/Heap.h
M Source/JavaScriptCore/heap/MarkingConstraint.h
M Source/JavaScriptCore/heap/MarkingConstraintSet.cpp
M Source/JavaScriptCore/heap/MarkingConstraintSet.h
M Source/JavaScriptCore/runtime/PinballCompletion.cpp
M Tools/Scripts/run-javascriptcore-tests
Log Message:
-----------
[JSC] Support heaps joining and leaving a Collector, for global collections
https://bugs.webkit.org/show_bug.cgi?id=327055
rdar://189661773
Reviewed by Yusuke Suzuki.
By default, each Heap owns its own Collector, which collects only that heap.
That Collector now lives in m_localCollector. With useGlobalGC enabled, all
heaps are instead collected by one shared Collector, which is created once
and never destroyed. m_collector points to whichever Collector the heap uses.
Local and global Collectors may eventually coexist, but while global
collection is being developed, the flag picks one for the whole process.
A heap joins its Collector in notifyIsSafeToCollect and leaves it in
shutDown. Adding a marking constraint goes through the same mechanism.
With a shared Collector, any other heap can start a collection at any time,
so membership changes have to happen between collections. If the Collector
is idle, the requesting thread applies the change itself while holding the
thread lock, which keeps a collection from starting. Otherwise the change is
queued, and whichever thread conducts next applies it before it begins a
collection. Joining doesn't wait for the change to be applied, but leaving
and adding a constraint do, the same way a mutator waits for a collection.
A local Collector is always idle when its heap joins, so joining never starts
its thread.
Each MarkingConstraint now records the heap that added it, so a leaving
heap's constraints can be removed from the MarkingConstraintSet.
Other changes:
- Only a heap that has joined can take the conn, and the conn asserts check
that only the conducting heap's mutator holds it.
- A mutator doesn't begin a collection if its own heap has just left.
- If the last heap leaves while GC requests are still queued, those requests
are marked as served, since there's nothing left to collect. A heap leaving
its local Collector still waits for a collection that's already running,
but no longer for queued ones.
- Heap::createCoreConstraints() returns the core constraints instead of
adding them, and the Collector adds them when it applies the join.
- The global Collector's collect-continuously thread starts when the first
heap joins, and it queues nothing while there are no heaps. A local
Collector stops its collector and collect-continuously threads when it's
destroyed along with its heap.
Global collection isn't usable yet, even for heaps with no references to each
other: stopping the mutators of several heaps isn't implemented, so a
collection can still cover only one heap.
The new testapi test creates and destroys VMs on several threads, adding a
marking constraint to each one in between. run-javascriptcore-tests also runs
it with useGlobalGC enabled.
Test: Source/JavaScriptCore/API/tests/testapi.cpp
* Source/JavaScriptCore/API/tests/testapi.cpp:
(countMarkingConstraintRun):
(TestAPI::heapMembershipChanges):
(testCAPIViaCpp):
* Source/JavaScriptCore/heap/Collector.cpp:
(JSC::Collector::Collector):
(JSC::Collector::globalCollector):
(JSC::Collector::~Collector):
(JSC::Collector::stopThread):
(JSC::Collector::requestCollection):
(JSC::Collector::shouldCollectInCollectorThread):
(JSC::Collector::collectInMutatorThread):
(JSC::Collector::runCurrentPhase):
(JSC::Collector::runNotRunningPhase):
(JSC::Collector::runBeginPhase):
(JSC::Collector::runFixpointPhase):
(JSC::Collector::changePhase):
(JSC::Collector::finishChangingPhase):
(JSC::Collector::resumeCompilerThreads):
(JSC::Collector::requestMembershipChange):
(JSC::Collector::isIdleWithLock):
(JSC::Collector::applyAllMembershipChangesWithLock):
(JSC::Collector::applyMembershipChangeWithLock):
(JSC::Collector::assertConn):
(JSC::Collector::anyMutatorHasConnWithLock):
(JSC::Collector::dump const):
(JSC::Collector::startCollectingContinuously):
(JSC::m_threadCondition): Deleted.
(JSC::Collector::addMarkingConstraint): Deleted.
* Source/JavaScriptCore/heap/Collector.h:
(JSC::Collector::hasPendingGCRequest):
(JSC::Collector::WTF_REQUIRES_LOCK):
(JSC::Collector::hasOutstandingRequest): Deleted.
(JSC::Collector::WTF_GUARDED_BY_LOCK):
* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::Heap):
(JSC::Heap::shutDown):
(JSC::Heap::lastChanceToFinalize):
(JSC::Heap::releaseDelayedReleasedObjects):
(JSC::Heap::beginMarking):
(JSC::Heap::clearConcurrentRetainedDataIfPossible):
(JSC::Heap::gatherStackRoots):
* Source/JavaScriptCore/heap/Heap.h:
(JSC::Heap::isSafeToCollect const): Deleted.
* Source/JavaScriptCore/heap/MarkingConstraint.h:
* Source/JavaScriptCore/heap/MarkingConstraintSet.cpp:
(JSC::MarkingConstraintSet::add):
(JSC::MarkingConstraintSet::remove):
(JSC::MarkingConstraintSet::executeConvergence):
* Source/JavaScriptCore/heap/MarkingConstraintSet.h:
(JSC::MarkingConstraintSet::isWavefrontRetreating):
* Source/JavaScriptCore/runtime/PinballCompletion.cpp:
(JSC::PinballCompletion::visitChildrenImpl):
* Source/JavaScriptCore/API/tests/testapi.cpp:
(countMarkingConstraintRun):
(TestAPI::heapMembershipChanges):
(testCAPIViaCpp):
* Tools/Scripts/run-javascriptcore-tests:
(runTest):
Canonical link: https://commits.webkit.org/323479@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications