node
node copied to clipboard
WASM cache: POC
This is a POC for compiled WebAssembly module cache proposal (#36671).
Checklist
- [ ]
make -j4 test
(UNIX), orvcbuild test
(Windows) passes - [ ] tests and/or benchmarks are included
- [ ] documentation is changed or added
- [ ] commit message follows commit guidelines
@devsnek
I think this seems better suited to userland.
There are some technical difficulties. Please check the overview below. Personally, I don't see how this could be made into a standalone package (I guess this is what you are suggesting), could you please elaborate?
Short version
-
The only way to deserialise a WASM module in public V8 API is to use the infrastructure supporting
.compileStreaming
. @addaleax -
WebAssembly.compileStreaming
is not available, unlessWasmStreamingCallback
was registered with V8 prior to startup. Makes it challenging to implement the feature as a standalone module.
Compiled WASM module cache is paramount for a good WASM experience, I wonder why you are convinced this should be standalone. It's hard to claim that WASM is out of scope for Node.js, since WASI is already in core.
WebAssembly.compileStreaming
workflow
- Embeder registers a WASM streaming callback. This has to be done prior to V8 startup, otherwise
compileStreaming
won't be available. -
compileStreaming(input)
will pass theinput
(resolving thePromise
if necessary) to the registered callback, along withWasmStreaming
object. - The callback should verify that
input
is something it could stream from, V8 itself doesn't check theinput
. - The callback uses
WasmStreaming
object to feed the module in:-
.SetClient(client)
— request a notification once the Module is compiled and optimised -
.SetUrl(url)
-
.SetCompiledModuleBytes(bytes)
— pass the previously compiled and optimised module -
.OnBytesReceived(bytes)
— transfer a chunk -
.Finish()
- or
.Abort()
-
- Once
.Finish()
was called, V8 starts Tier 1 compiler. - When Tier 1 completes, the Promise returned from
.compileStreaming
resolves, and the Module becomes available. It's not optimised yet. - Tier 2 continues in the background.
- Tier 2 completes, V8 transparently replaces the Module code with the optimised version.
- A client, if registered with
WasmStreaming.SetClient
, is notified. It could extract the optimised compiled module bytes and save it to cache. Only optimised version is cacheable.
Concerning WebAssembly.compileStreaming (sidenote)
Node.js doesn't expose .compileStreaming
at the moment. As a side effect of the proposed changes, it gets exposed. This is probably wrong. According to the spec, is is taking a Request
object. There's no such thing in Node.js.
I would imagine V8 could be modified to support caching in WebAssembly.compile. In that case, the callback wouldn't need to be registered before the context is created, and you could do it from userland.
See https://github.com/nodejs/node/issues/36671#issuecomment-768257129.