Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 847b1d1f5e7f89b6e750e1190bd3e4daa4027018
https://github.com/WebKit/WebKit/commit/847b1d1f5e7f89b6e750e1190bd3e4daa4027018
Author: Keith Miller <[email protected]>
Date: 2026-10-15 (Thu, 15 Oct 2026)
Changed paths:
M Source/JavaScriptCore/heap/BlockDirectory.cpp
M Source/JavaScriptCore/heap/BlockDirectory.h
M Source/JavaScriptCore/heap/BlockDirectoryBits.h
M Source/JavaScriptCore/heap/BlockDirectoryInlines.h
M Source/JavaScriptCore/heap/Heap.cpp
M Source/JavaScriptCore/heap/Heap.h
M Source/JavaScriptCore/heap/HeapCellInlines.h
M Source/JavaScriptCore/heap/IsoCellSet.cpp
M Source/JavaScriptCore/heap/IsoCellSet.h
M Source/JavaScriptCore/heap/LocalAllocator.cpp
M Source/JavaScriptCore/heap/MarkedBlock.cpp
M Source/JavaScriptCore/heap/MarkedBlock.h
M Source/JavaScriptCore/heap/MarkedBlockInlines.h
M Source/JavaScriptCore/heap/MarkedSpace.cpp
M Source/JavaScriptCore/heap/Subspace.cpp
M Source/WTF/WTF.xcodeproj/project.pbxproj
M Source/WTF/wtf/CMakeLists.txt
M Source/WTF/wtf/FastBitVector.h
A Source/WTF/wtf/VersionedField.h
M Tools/TestWebKitAPI/CMakeLists.txt
M Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
A Tools/TestWebKitAPI/Tests/WTF/VersionedField.cpp
Log Message:
-----------
[JSC] BlockDirectory's bits should be guarded by a mutate-grow lock
https://bugs.webkit.org/show_bug.cgi?id=325474
rdar://188567814
Reviewed by Yusuke Suzuki and Dan Hecht.
BlockDirectory's bits have relied on the mutator being the only thread that
allocates from or
sweeps a directory's blocks, so most mutator-side reads and writes went
unlocked and
m_bitvectorLock mainly guarded the few places where other threads touch the
bits. That
assumption stands in the way of sweeping concurrently with the mutator, and of
a global GC
with multiple mutators allocating from the same directory. This patch starts
making those
cases possible. m_bitvectorLock is now a MutateGrowLock, which is a thin
renaming of
WTF::ReadWriteLock. Per-block bit updates take the shared mutate() side, and
only operations
that resize or restructure the bit vectors (addBlock, removeBlock) take the
exclusive grow()
side. A block's inUse bit acts as a per-block lock, claimInUse() is the acquire
and
releaseInUse() release it. This could be error-prone so a Clang thread safety
analysis tracks
ownership of the claimed block through a new BlockOwnership capability. Right
now the
capability model only ASSERTs that some thread is holding the inUse bit but if
there bugs
in the future we can add proper thread id tracking.
Because shared holders can write different bits of the same word at the same
time, every
per-bit accessor is a relaxed atomic operation. This is generally safe because
of the inUse
ownership mechanism. Bulk vector rewrites stay plain and still require the
exclusive lock.
Additionally, many of the cursors need to be turned into a new VersionedField.
VersionedField
is largely ported from libpas with a more C++ style interface. It works by
attaching a version
number to the contents of the field. The field supports moving in either
direction, however,
it's only possible to move one way without failure.
IsoCellSet used to borrow the directory's lock to keep its per-block bits and
its
blocks-with-bits vector in sync. That no longer fits. addBlock and removeBlock
now call into
IsoCellSet while already holding grow(). IsoCellSet::add() runs on marker
threads and needs
mutual exclusion that the shared side doesn't provide. Taking grow() there
would stall
allocation and sweeping for a structure the directory doesn't own. IsoCellSet
now has its own
lock for installing, dropping and resizing those bits. To avoid deadlocking, a
thread can't
take the m_bitvectorLock after taking the IsoCellSet lock. In the future we may
end up
with a MutateGrowLock in IsoCellSets too.
BlockDirectory::sweep() is also renamed sweepAll() to distinguish it from
per-block sweeping,
as a drive by change.
Tests:
JSC Covered by existing tests. No behavior change.
Tools/TestWebKitAPI/Tests/WTF/VersionedField.cpp
Canonical link: https://commits.webkit.org/323819@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications