← All reports

IsoSubspaces share a single default aligned-memory allocator

Component: JavaScriptCore Heap | fe81aba

JSC's GC heap is partitioned into Subspaces, each holding same-sized cells for a specific object kind — JSFinalObject variants, butterflies, JSString. Each subspace manages BlockDirectorys of 16KB MarkedBlocks that are allocated, swept, and freed independently.

This commit removes a per-subspace default: IsoSubspaces that do not supply their own AlignedMemoryAllocator no longer create a private FastMallocAlignedMemoryAllocator and instead fall back to a single allocator owned by Heap (heap.fastMallocAllocator). Subspaces that pass in a custom allocator are unaffected. Because subspaces sharing that default now draw from the same underlying block pool, BlockDirectory::findEmptyBlockToSteal() can pull empty MarkedBlocks from other subspaces sharing that allocator rather than requesting fresh memory — except for blocks marked in the existing destructibleBits() bitvector, which are skipped because reclaiming a destructible block requires an inline destructor sweep first.

Empty heap blocks can now migrate between different JS object type pools, which reduces per-subspace memory waste and changes heap layout and reuse behavior. For anyone reasoning about JSC memory grooming, that is the consequential part: a block that held one cell type can now be handed to a directory serving a different one, so assumptions about which subspace a given address range has ever belonged to no longer hold across a GC cycle.