Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: aa19dc61a03ee7712c6e3e11ec7c8d9410dbd70a
https://github.com/WebKit/WebKit/commit/aa19dc61a03ee7712c6e3e11ec7c8d9410dbd70a
Author: Yusuke Suzuki <[email protected]>
Date: 2026-09-13 (Sun, 13 Sep 2026)
Changed paths:
A JSTests/stress/steal-empty-blocks-across-subspaces.js
M Source/JavaScriptCore/heap/AlignedMemoryAllocator.cpp
M Source/JavaScriptCore/heap/AlignedMemoryAllocator.h
M Source/JavaScriptCore/heap/BlockDirectory.cpp
M Source/JavaScriptCore/heap/BlockDirectory.h
M Source/JavaScriptCore/heap/CompleteSubspace.cpp
M Source/JavaScriptCore/heap/Heap.cpp
M Source/JavaScriptCore/heap/Heap.h
M Source/JavaScriptCore/heap/IsoSubspace.cpp
M Source/JavaScriptCore/heap/IsoSubspace.h
M Source/JavaScriptCore/heap/LocalAllocator.cpp
M Source/JavaScriptCore/heap/MarkedBlock.cpp
M Source/JavaScriptCore/heap/Subspace.cpp
M Source/JavaScriptCore/heap/Subspace.h
Log Message:
-----------
[JSC] Unify JS Allocators
https://bugs.webkit.org/show_bug.cgi?id=324020
rdar://187253898
Reviewed by Dan Hecht.
This patch unifies JS allocators. Previously each IsoSubspace had its
own allocator. But we no longer want to do it and we would like to unify
them into one. This unlocks making MarkedBlock stealing. However just
using it causes severe performance regressions due to several reasons.
1. We are stealing MarkedBlock with destructors. And we invoke sweep.
This may slip the different type of cells' destructors into different
type of cells' allocation. This is problematic: we are fine to pay
JSString destruction cost when allocating a new JSString. But we are
not fine to pay this cost when allocating JSArray. We intentionally
skips MarkedBlock which requires destructor calls for stealing target.
Keep them in the BlockDirectory and same type of cell will pay this
cost when reusing this MarkedBlock.
2. We are skipping MarkedBlock w/ WeakSet as a stealing target right now.
This sounds strange since WeakSet should be completely empty since
MarkedBlock is empty. When WeakBlock is still including WeakImpl with
dead values, then it should be chained to Heap as logically-empty.
The problem is that we are pooling completely empty WeakBlocks to
accelerate the further WeakBlock allocations for this MarkedBlock
again, and WeakSet::sweep will iterate them, and as a piggy-backed work,
we also do logically-empty WeakBlock sweeping! This is similar
problem to (1): we accidentally pay completely unrelated JSCell's
cost at different JSCell type's allocation path. For now, we
intentionally skip MarkedBlock with WeakSet as a stealing target.
3. Previously m_emptyCursor and front BlockDirectory are monotonically
forwarding. But this is very wrong: IncrementalSweeper will make some
MarkedBlock empty even after m_emptyCursor skipped this block because
at that time it was not empty. This patch fixes them by recording
usable BlockDirectory in the allocator, and also resetting
m_emptyCursor whenever lower-index MarkedBlock becomes empty.
* JSTests/stress/steal-empty-blocks-across-subspaces.js: Added.
(makeObjects):
(makeClosures):
(makeArrays):
(makeDestructibleCells):
* Source/JavaScriptCore/heap/AlignedMemoryAllocator.cpp:
(JSC::AlignedMemoryAllocator::addDirectoryWithEmptyBlocks):
(JSC::AlignedMemoryAllocator::takeDirectoryWithEmptyBlocks):
(JSC::AlignedMemoryAllocator::findEmptyBlockToSteal):
(JSC::AlignedMemoryAllocator::registerDirectory): Deleted.
(JSC::AlignedMemoryAllocator::registerSubspace): Deleted.
* Source/JavaScriptCore/heap/AlignedMemoryAllocator.h:
(JSC::AlignedMemoryAllocator::WTF_GUARDED_BY_LOCK):
(): Deleted.
* Source/JavaScriptCore/heap/BlockDirectory.cpp:
(JSC::BlockDirectory::noteBlockMayBeStealable):
(JSC::BlockDirectory::findEmptyBlockToSteal):
(JSC::BlockDirectory::prepareForAllocation):
(JSC::BlockDirectory::sweep):
(JSC::BlockDirectory::shrink):
(JSC::BlockDirectory::didFinishUsingBlock):
* Source/JavaScriptCore/heap/BlockDirectory.h:
(JSC::BlockDirectory::WTF_REQUIRES_SHARED_LOCK):
(JSC::BlockDirectory::nextDirectoryInAlignedMemoryAllocator const): Deleted.
(JSC::BlockDirectory::setNextDirectoryInAlignedMemoryAllocator): Deleted.
* Source/JavaScriptCore/heap/CompleteSubspace.cpp:
(JSC::CompleteSubspace::allocatorForSlow):
* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::Heap):
* Source/JavaScriptCore/heap/Heap.h:
* Source/JavaScriptCore/heap/IsoSubspace.cpp:
(JSC::IsoSubspace::IsoSubspace):
* Source/JavaScriptCore/heap/IsoSubspace.h:
* Source/JavaScriptCore/heap/LocalAllocator.cpp:
(JSC::LocalAllocator::tryAllocateWithoutCollecting):
* Source/JavaScriptCore/heap/MarkedBlock.cpp:
(JSC::MarkedBlock::Handle::sweep):
* Source/JavaScriptCore/heap/Subspace.cpp:
(JSC::Subspace::initialize):
(JSC::Subspace::prepareForAllocation):
(JSC::Subspace::findEmptyBlockToSteal): Deleted.
* Source/JavaScriptCore/heap/Subspace.h:
(JSC::Subspace::didCreateFirstDirectory): Deleted.
(JSC::Subspace::nextSubspaceInAlignedMemoryAllocator const): Deleted.
(JSC::Subspace::setNextSubspaceInAlignedMemoryAllocator): Deleted.
Canonical link: https://commits.webkit.org/321016@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications