Skip to content

fix: balance linear-memory limiter reservations - #61

Open
matthargett wants to merge 1 commit into
explodingcamera:nextfrom
rebeckerspecialties:fix/linear-memory-limiter-lifecycle
Open

matthargett wants to merge 1 commit into
explodingcamera:nextfrom
rebeckerspecialties:fix/linear-memory-limiter-lifecycle

Conversation

@matthargett

Copy link
Copy Markdown
Contributor

A host with a main WASM guest and a potentially short-lived WASM-backed AudioWorklet processors needs one quota across worker restarts to gracefully handle abuse (perhaps unintentional) cases. The W3C Web Audio model puts processors on a rendering thread; using WASM there is my embedding choice for my little game runtime. Limiter approval currently precedes fallible allocation, with no refund or teardown signal, which is a problem when running a WebAudio graph that's a little too big to run on Apple Watch.

This PR adds default no-op failure/release callbacks, keeps charges with the backing memory through shared-handle lifetime, and stages module memories before publishing them so that partial allocation failures refund earlier reservations. The limiter handle uses atomic reference counting so shared memory can outlive its creating store. Host-created shared memory starts uncharged; its first limiter-approved guest growth binds the accounting owner. I measured branch prediction and L1 cache misses in the opcode dispatch path on iPhone XS/11/12 to see if there's a ripple effect that affects performance, and its unchanged.

Tests cover allocation failure, multi-memory partial failure, imported memory, custom pages, concurrent stores, stale shared growth, and last-handle release. I had to fortify this when I experimented with wasmtime, WasmEdge, and WAMR as well, but lmk if there's other fortifications you want to see :D

Refund approved growth when backing allocation fails or a shared-memory proposal goes stale. Retain memory charges until the backing allocation is freed, including across shared handles and worker-store teardown. Stage module memories before publishing them so partial allocation failure does not strand an unreachable charge.
@explodingcamera

Copy link
Copy Markdown
Owner

Thanks for the PR! I'm a little unsure about this, so I might have to take some time to think about it.

I've been waiting for the Custom Allocator API to be stabilized in Rust (which it finally will be in the next version 🎊), and that might be a better fit for this use case, with a per-store configurable allocator for Wasm guest data.

I think ResourceLimiter should probably stay closer to policy ("is this resource allowed to grow?"), while the allocator handles actual memory accounting.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants