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

Reply via email to