forked from bytecodealliance/wasmtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds a new API to the `wasmtime::Func` type for wrapping a C-ABI function with a well-defined signature derived from a wasm type signature. The purpose of this API is to add the-most-optimized-we-can path for using the C API and having wasm call host functions. Previously when wasm called a host function it would perform these steps: 1. Using a trampoline, place all arguments into a `u128*` array on the stack. 2. Call `Func::invoke` which uses the type of the function (dynamically) to read values from this `u128*`. 3. Values are placed within a `Vec<Val>` after being read. 4. The C API receives `&[Val]` and translates this to `&[wasmtime_val_t]`, iterating over each value and copying its contents into a new vector. 5. Then the host function is actually called. 6. The above argument-shuffling steps are all performed in reverse for the results, shipping everything through `wasmtime_val_t` and `Val`. PRs such as bytecodealliance#3319 and related attempts have made this sequence faster, but the numbers on bytecodealliance#3319 show that even after we get all the allocation and such bits out of the way we're still spending quite a lot of time shuffling arguments back-and-forth relative to the `Func::wrap` API that Rust can use. This commit fixes the issue by eliminating all steps except 1/5 above. Although we still place all arguments on the stack and read them out again to call the C-defined function with it's much faster than pushing this all through the `Val` and `wasmtime_val_t` machinery. This overall gets the cost of a wasm->host call basically on-par with `Func::wrap`, although it's still not as optimized. Benchmarking the overhead of wasm->host calls, where `i64` returns one i64 value and `many` takes 5 `i32` parameters and returns one `i64` value, the numbers I get are: | Import | Rust | C before | C after | |--------|------|----------|---------| | `i64` | 1ns | 40ns | 7ns | | `many` | 1ns | 91ns | 10ns | This commit is a clear win over the previous implementation, but it's even still somewhat far away from Rust. That being said I think I'm out of ideas of how to make this better. Without open-coding much larger portions of `wasmtime` I'm not sure how much better we can get here. The time in C after this commit is almost entirely spent in trampolines storing the arguments to the stack and loading them later, and at this point I'm not sure how much more optimized we can get than that since Rust needs to enter the picture here somehow to handle the Wasmtime fiddly-bits of calling back into C. I'm hopeful, though, that this is such a large improvement from before that the question of optimizing this further in C is best left for another day. The new `Func::wrap_cabi` method is unlikely to ever get used from Rust, but a `wasmtime_func_wrap` API was added to the C API to mirror `Func::wrap` where if the host function pointer has a specific ABI this function can be called instead of `wasmtime_func_new`.
- Loading branch information
1 parent
1925865
commit 9c19f96
Showing
12 changed files
with
775 additions
and
28 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.