Sub-allocate numeric component storage into a WebAssembly.Memory, so the
same bytes are visible to a wasm module (physics, codecs, …) without copying.
memory.grow swaps in a new backing buffer, so every live view is refreshed
via needsRefresh when the arena has to grow.
The arena owns [byteOffset, end) of the memory; pass byteOffset when the
same Memory also backs a module whose own state lives in the low addresses.
Shared memory = wasm-accessible AND cross-worker shareable. Construct the
memory with { shared: true } (which requires maximum) and memory.buffer
is a growable SharedArrayBuffer. This allocator then gives you the union of
both off-the-shelf arenas in one — numeric components that a wasm module can
read/write in place and that can be posted to a worker without copying:
Unlike non-shared memory (whose old buffer is DETACHED on grow), a shared
memory's prior buffer stays valid and aliases the same pages; V8 still returns
a fresh SharedArrayBuffer object from memory.buffer after a grow, so views
are refreshed onto it and every column stays on one shared buffer. In a
browser, SharedArrayBuffer requires cross-origin isolation (COOP/COEP).
⚠️ Arena columns are freed when discarded (e.g. a store.fromData that
replaces them). Do NOT retain a live-reference snapshot (db.toData({ copy: false })) across a subsequent fromData under an arena allocator — the
snapshot's column buffers may have been freed and reused (use-after-free).
Serialize/persist such a snapshot synchronously, or take it with copy: true.
Sub-allocate numeric component storage into a
WebAssembly.Memory, so the same bytes are visible to a wasm module (physics, codecs, …) without copying.memory.growswaps in a new backing buffer, so every live view is refreshed vianeedsRefreshwhen the arena has to grow.The arena owns
[byteOffset, end)of the memory; passbyteOffsetwhen the sameMemoryalso backs a module whose own state lives in the low addresses.Shared memory = wasm-accessible AND cross-worker shareable. Construct the memory with
{ shared: true }(which requiresmaximum) andmemory.bufferis a growableSharedArrayBuffer. This allocator then gives you the union of both off-the-shelf arenas in one — numeric components that a wasm module can read/write in place and that can be posted to a worker without copying:Unlike non-shared memory (whose old buffer is DETACHED on grow), a shared memory's prior buffer stays valid and aliases the same pages; V8 still returns a fresh
SharedArrayBufferobject frommemory.bufferafter a grow, so views are refreshed onto it and every column stays on one shared buffer. In a browser,SharedArrayBufferrequires cross-origin isolation (COOP/COEP).⚠️ Arena columns are freed when discarded (e.g. a
store.fromDatathat replaces them). Do NOT retain a live-reference snapshot (db.toData({ copy: false })) across a subsequentfromDataunder an arena allocator — the snapshot's column buffers may have been freed and reused (use-after-free). Serialize/persist such a snapshot synchronously, or take it withcopy: true.