-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Statically register host WASM functions #10394
Statically register host WASM functions #10394
Conversation
let mut base = Base::host_functions(); | ||
let overlay = Overlay::host_functions(); | ||
base.retain(|host_fn| { | ||
!overlay.iter().any(|ext_host_fn| host_fn.name() == ext_host_fn.name()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want to pull the overlay names into a set or do we think there will be very few of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's how it was originally, so it's probably not a big deal? Nevertheless there aren't that many of them, and I haven't seen this pop up in any of profiles.
I can rework this to use a HashSet
if you really want though.
primitives/wasm-interface/src/lib.rs
Outdated
type State; | ||
type Error; | ||
type FunctionContext: FunctionContext; | ||
fn with_function_context<R>(caller: wasmtime::Caller<Self::State>, callback: impl FnOnce(&mut dyn FunctionContext) -> R) -> R; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of curiosity, why dynamic object and not Self::FunctionContext
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making it Self::FunctionContext
significantly complicates the lifetimes everywhere, and from the top of my head I'm not even sure if it's actually possible to use a concrete type here without GATs (since Caller
actually takes a lifetime which has to be passed to the Self::FunctionContext
, it's just elided here). Also, rest of the traits (e.g. host::FromFFIValue
) and the dynamic dispatch machinery (Function::execute
) take it as &dyn FunctionContext
anyway.
If we really want a concrete type here I'd suggest that we should ignore it for now and just revisit this once GATs are stabilized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah, all is fine. Was just curious
primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
Outdated
Show resolved
Hide resolved
FWIW, this will require polkadot companion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good
Maybe this will appease cargo-unleash?
This reverts commit 0f7ccf8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just some nitpicks here and there.
Ty for the work!
primitives/wasm-interface/src/lib.rs
Outdated
fn_name: &str, | ||
func: impl wasmtime::IntoFunc<Self::State, Params, Results> + 'static, | ||
) -> core::result::Result<(), Self::Error> { | ||
if self.seen.contains(fn_name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is to prevent double registration?
Maybe some debug log would be nice that says that we filtered this one out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but only in a sense that since this is explicitly used to override the functions from the Base
with the functions from the Overlay
it is expected that there will be some duplicates.
Yeah I guess I can add a debug log here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I've also added a little bit more strict checking here to disambiguate between duplicates in Base
vs duplicates in Overlay
.
type FFIType = u8; | ||
type FFIType = u32; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to be sure. This was internally passed before as u32
anyway, because wasm types don't know u8
"natively"? So, we don't change it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. WASM FFI doesn't support 8-bit and 16-bit integers natively, so it was being converted into an u32
later anyway. So I've put the extra WasmTy
bound on the FFIType
so that it will be guaranteed that's actually FFI-compatible and moved the conversion into the native WASM FFI type earlier.
primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
Outdated
Show resolved
Hide resolved
primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
Outdated
Show resolved
Hide resolved
primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
Outdated
Show resolved
Hide resolved
&mut self, | ||
fn_name: &str, | ||
func: impl wasmtime::IntoFunc<Self::State, Params, Results>, | ||
) -> Result<(), Self::Error> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you return a result here? To be future proof?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... good question! (:
Currently it can indeed only return an Ok
; IIRC it's a vestigial remain from before one of the refactorings I did before I pushed this PR out where it could actually return an error.
primitives/runtime-interface/proc-macro/src/runtime_interface/host_function_interface.rs
Outdated
Show resolved
Hide resolved
bot merge |
Error: Github API says paritytech/polkadot#4471 is not mergeable |
bot merge |
* Statically register host WASM functions * Fix `substrate-test-client` compilation * Move `ExtendedHostFunctions` to `sp-wasm-interface` * Fix `sp-runtime-interface` tests' compilation * Fix `sc-executor-wasmtime` tests' compilation * Use `runtime_interface` macro in `test-runner` * Fix `sc-executor` tests' compilation * Reformatting/`rustfmt` * Add an extra comment regarding the `H` generic arg in `create_runtime` * Even more `rustfmt` * Depend on `wasmtime` without default features in `sp-wasm-interface` * Bump version of `sp-wasm-interface` to 4.0.1 * Bump `sp-wasm-interface` in `Cargo.lock` too * Bump all of the `sp-wasm-interface` requirements to 4.0.1 Maybe this will appease cargo-unleash? * Revert "Bump all of the `sp-wasm-interface` requirements to 4.0.1" This reverts commit 0f7ccf8. * Make `cargo-unleash` happy (maybe) * Use `cargo-unleash` to bump the crates' versions * Align to review comments
* Statically register host WASM functions * Fix `substrate-test-client` compilation * Move `ExtendedHostFunctions` to `sp-wasm-interface` * Fix `sp-runtime-interface` tests' compilation * Fix `sc-executor-wasmtime` tests' compilation * Use `runtime_interface` macro in `test-runner` * Fix `sc-executor` tests' compilation * Reformatting/`rustfmt` * Add an extra comment regarding the `H` generic arg in `create_runtime` * Even more `rustfmt` * Depend on `wasmtime` without default features in `sp-wasm-interface` * Bump version of `sp-wasm-interface` to 4.0.1 * Bump `sp-wasm-interface` in `Cargo.lock` too * Bump all of the `sp-wasm-interface` requirements to 4.0.1 Maybe this will appease cargo-unleash? * Revert "Bump all of the `sp-wasm-interface` requirements to 4.0.1" This reverts commit 0f7ccf8. * Make `cargo-unleash` happy (maybe) * Use `cargo-unleash` to bump the crates' versions * Align to review comments
* Statically register host WASM functions * Fix `substrate-test-client` compilation * Move `ExtendedHostFunctions` to `sp-wasm-interface` * Fix `sp-runtime-interface` tests' compilation * Fix `sc-executor-wasmtime` tests' compilation * Use `runtime_interface` macro in `test-runner` * Fix `sc-executor` tests' compilation * Reformatting/`rustfmt` * Add an extra comment regarding the `H` generic arg in `create_runtime` * Even more `rustfmt` * Depend on `wasmtime` without default features in `sp-wasm-interface` * Bump version of `sp-wasm-interface` to 4.0.1 * Bump `sp-wasm-interface` in `Cargo.lock` too * Bump all of the `sp-wasm-interface` requirements to 4.0.1 Maybe this will appease cargo-unleash? * Revert "Bump all of the `sp-wasm-interface` requirements to 4.0.1" This reverts commit 0f7ccf8. * Make `cargo-unleash` happy (maybe) * Use `cargo-unleash` to bump the crates' versions * Align to review comments
skip check-dependent-cumulus
polkadot companion: paritytech/polkadot#4471
This PR changes how we register the host WASM functions exposed to the runtime. Currently we register them dynamically with wasmtime::Func::new, while this PR makes it so that we statically register them with wasmtime::Func::wrap.
Why? Let me quote
wasmtime
docs:And indeed, using
Func::wrap
is significantly more efficient than usingFunc::new
. Granted, we probably don't make enough calls from the WASM runtime for this to make a significant difference when those functions are called, however where it makes a huge difference is when we're instantiating new WASM instances.When using
Func::new
every time a host function is registeredwasmtime
has to JIT a new trampoline for it, and this is extremely slow; when usingFunc::wrap
it doesn't, and from what I can see this cuts down the instantiation time by over 90%.Of course this also doesn't make a huge difference in practice right now since we're using our own instance reuse mechanism, however this is absolutely necessary if we'd ever want to switch to
wasmtime
's native instance pooling. (Without this PR even withwasmtime
s instance pooling enabled the cost of JITing those trampolines completely dominates the execution time.)EDIT(pep): Closes #8959