Avoid vector allocations in wasm->host calls (#3294)

This commit improves the runtime support for wasm-to-host invocations
for functions created with `Func::new` or `wasmtime_func_new` in the C
API. Previously a `Vec` (sometimes a `SmallVec`) would be dynamically
allocated on each host call to store the arguments that are coming from
wasm and going to the host. In the case of the `wasmtime` crate we need
to decode the `u128`-stored values, and in the case of the C API we need
to decode the `Val` into the C API's `wasmtime_val_t`.

The technique used in this commit is to store a singular `Vec<T>` inside
the "store", be it the literal `Store<T>` or within the `T` in the case
of the C API, which can be reused across wasm->host calls. This means
that we're unlikely to actually perform dynamic memory allocation and
instead we should hit a faster path where the `Vec` always has enough
capacity.

Note that this is just a mild improvement for `Func::new`-based
functions. It's still the case that `Func::wrap` is much faster, but
unfortunately the C API doesn't have access to `Func::wrap`, so the main
motivation here is accelerating the C API.
This commit is contained in:
Alex Crichton
2021-09-03 15:14:21 -05:00
committed by GitHub
parent 0473e1990a
commit c73673559b
7 changed files with 83 additions and 39 deletions

View File

@@ -1,4 +1,4 @@
use crate::{wasm_engine_t, wasmtime_error_t, ForeignData};
use crate::{wasm_engine_t, wasmtime_error_t, wasmtime_val_t, ForeignData};
use std::cell::UnsafeCell;
use std::ffi::c_void;
use std::sync::Arc;
@@ -67,6 +67,10 @@ pub struct StoreData {
foreign: crate::ForeignData,
#[cfg(feature = "wasi")]
pub(crate) wasi: Option<wasmtime_wasi::WasiCtx>,
/// Temporary storage for usage during a wasm->host call to store values
/// in a slice we pass to the C API.
pub hostcall_val_storage: Vec<wasmtime_val_t>,
}
#[no_mangle]
@@ -85,6 +89,7 @@ pub extern "C" fn wasmtime_store_new(
foreign: ForeignData { data, finalizer },
#[cfg(feature = "wasi")]
wasi: None,
hostcall_val_storage: Vec::new(),
},
),
})