wasmtime
wasmtime copied to clipboard
Remove lazy `funcref` table init checking from codegen for `[return_]call_indirect`
Right now, whenever we do an indirect call, we have an extra branch in the codegen to check whether the table has been initialized or not yet.
We have these checks because, among other reasons, we can't create CoW images for funcref
tables since the funcref
elements are closures over the vmctx, and therefore are different for every instance.
However, we could
- create a CoW table image
- and remove the is-it-initialized check
- while still supporting lazy
funcref
tables
by initializing tables to contain generic trampolines that do the lazy initialization when invoked:
- define trampoline(s) to initialize a vmctx's
i
thfuncref
table- where
i
is static and we only havei=0
for the common case, other tables do what we do today - and then this trampoline is either handwritten asm that works for all wasm signatures, or
- we have one of these per wasm signature in the module
- the trampolines use the caller vmctx to find the table being accessed and initialize it when they are invoked, and then they tail call to the actual initialized
funcref
element
- where
- create
VMFuncRef
s of these trampolines where the vmctx is null- the trampolines don't use their callee_vmctx
- and this, crucially, means that they can be shared across all instances of the module
- the CoW init image for a lazy
funcref
table is then an array of these trampolines - and since lazy
funcref
tables are always filled with callableVMFuncRef
s now, we don't need to branch on whether the table is initialized or not in an indirect call
I think we would still need checks for general table access like table.{get,set,fill,copy}
.
(Also note that this doesn't require actual CoW and virtual memory, we could do all this with memcpy depending on configuration and perf trade offs)