* Change wasm-to-host trampolines to take the values_vec size
This commit changes the ABI of wasm-to-host trampolines, which are
only used right now for functions created with `Func::new`, to pass
along the size of the `values_vec` argument. Previously the trampoline
simply received `*mut ValRaw` and assumed that it was the appropriate
size. By receiving a size as well we can thread through `&mut [ValRaw]`
internally instead of `*mut ValRaw`.
The original motivation for this is that I'm planning to leverage these
trampolines for the component model for host-defined functions. Out of
an abundance of caution of making sure that everything lines up I wanted
to be able to write down asserts about the size received at runtime
compared to the size expected. This overall led me to the desire to
thread this size parameter through on the assumption that it would not
impact performance all that much.
I ran two benchmarks locally from the `call.rs` benchmark and got:
* `sync/no-hook/wasm-to-host - nop - unchecked` - no change
* `sync/no-hook/wasm-to-host - nop-params-and-results - unchecked` - 5%
slower
This is what I roughly expected in that if nothing actually reads the
new parameter (e.g. no arguments) then threading through the parameter
is effectively otherwise free. Otherwise though accesses to the `ValRaw`
storage is now bounds-checked internally in Wasmtime instead of assuming
it's valid, leading to the 5% slowdown (~9.6ns to ~10.3ns). If this
becomes a peformance bottleneck for a particular use case then we should
be fine to remove the bounds checking here or otherwise only bounds
check in debug mode, otherwise I plan on leaving this as-is.
Of particular note this also changes the C API for `*_unchecked`
functions where the C callback now receives the size of the array as
well.
* Add docs
* Make `ValRaw` fields private
Force accessing to go through constructors and accessors to localize the
knowledge about little-endian-ness. This is spawned since I made a
mistake in #4039 about endianness.
* Fix some tests
* Component model changes
The goal of this new benchmark, `call`, is to help us measure the
overhead of both calling into WebAssembly from the host as well as
calling the host from WebAssembly. There's lots of various ways to
measure this so this benchmark is a bit large but should hopefully be
pretty thorough. It's expected that this benchmark will rarely be run in
its entirety but rather only a subset of the benchmarks will be run at
any one given time.
Some metrics measured here are:
* Typed vs Untyped vs Unchecked - testing the cost of both calling wasm
with these various methods as well as having wasm call the host where
the host function is defined with these various methods.
* With and without `call_hook` - helps to measure the overhead of the
`Store::call_hook` API.
* Synchronous and Asynchronous - measures the overhead of calling into
WebAssembly asynchronously (with and without the pooling allocator) in
addition to defining host APIs in various methods when wasm is called
asynchronously.
Currently all the numbers are as expected, notably:
* Host calling WebAssembly is ~25ns of overhead
* WebAssembly calling the host is ~3ns of overhead
* "Unchecked" is a bit slower than "typed", and "Untyped" is slower than
unchecked.
* Asynchronous wasm calling a synchronous host function has ~3ns of
overhead (nothing more than usual).
* Asynchronous calls are much slower, on the order of 2-3us due to
`madvise`.
Lots of other fiddly bits that can be measured here, but this will
hopefully help establish a benchmark through which we can measure in the
future in addition to measuring changes such as #3876