Add wasm_memory_discard compatibility flag - #6999
Merged
Merged
Conversation
Contributor
|
APIError: Invalid Anthropic API Key |
2 similar comments
Contributor
|
APIError: Invalid Anthropic API Key |
Contributor
|
APIError: Invalid Anthropic API Key |
Contributor
|
@guybedford Bonk workflow failed. Check the logs for details. View workflow run · To retry, trigger Bonk again. |
Merging this PR will not alter performance
Comparing Footnotes
|
guybedford
force-pushed
the
gbedford/wasm-memory-discard
branch
2 times, most recently
from
August 15, 2026 04:11
526325e to
205518d
Compare
jasnell
approved these changes
Aug 17, 2026
Gates the experimental WebAssembly memory.discard proposal, exposing WebAssembly.Memory.prototype.discard(byteOffset, byteLength) and the memory.discard opcode on a per-worker basis. The feature is wired through V8's per-context conditional-feature mechanism: a per-isolate enabled callback (SetWasmMemoryDiscardEnabledCallback) reports the flag state, which V8 consults both when installing the JS API (InstallConditionalFeatures) and when compiling wasm modules that use the memory.discard opcode. Lock::installWasmMemoryDiscard() enables the feature once per context, based on the flag, via NewContextOptions. Floats the memory.discard V8 patch (0039) into workerd's V8 patch set so the feature is present in workerd's own V8 build. The patch routes the JS API, the jitted memory.discard wrapper and the interpreter through BackingStore::DiscardWasmMemory rather than discarding raw addresses, so page release happens at a single point, and that point discards through the page allocator the reservation actually came from. Under V8_ENABLE_SANDBOX wasm memory is reserved from the isolate group's backing-store allocator, not the platform allocator, so reaching for GetPlatformPageAllocator() decommitted through an allocator that does not own the region -- benign on Linux, where DiscardSystemPages is madvise(MADV_DONTNEED) keyed on address, but wrong on the DecommitPages/SetPermissions path used elsewhere. Also removes the obsolete jspiEnabledCallback declaration left behind when JSPI was stabilized.
guybedford
force-pushed
the
gbedford/wasm-memory-discard
branch
from
August 17, 2026 18:30
3d2b6fb to
54f23ed
Compare
guybedford
enabled auto-merge (squash)
August 17, 2026 18:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
wasm_memory_discardcompatibility flag gating the experimental WebAssembly memory.discard sub-proposal, exposingWebAssembly.Memory.prototype.discard(byteOffset, byteLength)and thememory.discardopcode per-worker.Wired through V8's per-context conditional-feature mechanism: a per-isolate enabled callback (
SetWasmMemoryDiscardEnabledCallback) reports the flag state, consulted both when installing the JS API (InstallConditionalFeatures) and when compiling wasm modules using the opcode. The flag stays set for the isolate lifetime since V8 re-queries it at compile time.Floats the V8 prototype as patch
0039, a port of CL 4300676 updated to the memory.discard semantics prototyped in SpiderMonkey, behind--experimental-wasm-memory-discard.Includes a wd-test covering the API and opcode, and as a drive-by removes the now-obsolete
jspiEnabledCallbackdeclaration.Page release goes through one funnel, and the right allocator
memory.discardreturns physical pages to the OS, so where it releases them from matters. The patch routes all three entry points — the JS API, the jittedmemory_discard_wrapper, and the interpreter — throughBackingStore::DiscardWasmMemoryrather than discarding raw addresses:trusted_data->memory_object(mem_index)->backing_store()->DiscardWasmMemory(dst, size);That single point then resolves the allocator the reservation actually came from, mirroring what the free path already does:
Under
V8_ENABLE_SANDBOX, wasm memory is reserved from the isolate group's backing-store allocator inTryAllocateAndPartiallyCommitMemory, not the platform allocator. Reaching forGetPlatformPageAllocator()therefore decommitted through an allocator that does not own the region. That is benign on Linux —DiscardSystemPagesismadvise(MADV_DONTNEED), keyed on address — but wrong on theDecommitPages+SetPermissionspath used elsewhere, which mutates allocator bookkeeping.Verification
Measured against a patched d8 with the sandbox enabled: a 64 MB discard releases exactly
67108864bytes of RSS, and the region reads back as zeroes and stays writable. Release is precise at page granularity — discarding a single 64 KB wasm page frees exactly 64 KB, re-discarding it frees nothing, and a subsequent overlapping 32 MB discard frees exactly 32 MB − 64 KB.One note for anyone testing this at the V8 level: d8 enables the wasm trap handler by default, which requires an 8 GB
kFullGuardSize32reservation per memory and so cannot allocate any wasm memory inside a smaller sandbox.--no-wasm-trap-handleris needed to match an embedder that does not install the handler