Implement lowered-then-lifted functions (#4327)

* Implement lowered-then-lifted functions

This commit is a few features bundled into one, culminating in the
implementation of lowered-then-lifted functions for the component model.
It's probably not going to be used all that often but this is possible
within a valid component so Wasmtime needs to do something relatively
reasonable. The main things implemented in this commit are:

* Component instances are now assigned a `RuntimeComponentInstanceIndex`
  to differentiate each one. This will be used in the future to detect
  fusion (one instance lowering a function from another instance). For
  now it's used to allocate separate `VMComponentFlags` for each
  internal component instance.

* The `CoreExport<FuncIndex>` of lowered functions was changed to a
  `CoreDef` since technically a lowered function can use another lowered
  function as the callee. This ended up being not too difficult to plumb
  through as everything else was already in place.

* A need arose to compile host-to-wasm trampolines which weren't already
  present. Currently wasm in a component is always entered through a
  host-to-wasm trampoline but core wasm modules are the source of all
  the trampolines. In the case of a lowered-then-lifted function there
  may not actually be any core wasm modules, so component objects now
  contain necessary trampolines not otherwise provided by the core wasm
  objects. This feature required splitting a new function into the
  `Compiler` trait for creating a host-to-wasm trampoline. After doing
  this core wasm compilation was also updated to leverage this which
  further enabled compiling trampolines in parallel as opposed to the
  previous synchronous compilation.

* Review comments
This commit is contained in:
Alex Crichton
2022-06-28 13:50:08 -05:00
committed by GitHub
parent df1502531d
commit c1b3962f7b
17 changed files with 400 additions and 107 deletions

View File

@@ -288,11 +288,19 @@ impl wasmtime_environ::Compiler for Compiler {
}))
}
fn compile_host_to_wasm_trampoline(
&self,
ty: &WasmFuncType,
) -> Result<Box<dyn Any + Send>, CompileError> {
self.host_to_wasm_trampoline(ty)
.map(|x| Box::new(x) as Box<_>)
}
fn emit_obj(
&self,
translation: &ModuleTranslation,
types: &ModuleTypes,
funcs: PrimaryMap<DefinedFuncIndex, Box<dyn Any + Send>>,
compiled_trampolines: Vec<Box<dyn Any + Send>>,
tunables: &Tunables,
obj: &mut Object<'static>,
) -> Result<(PrimaryMap<DefinedFuncIndex, FunctionInfo>, Vec<Trampoline>)> {
@@ -300,6 +308,10 @@ impl wasmtime_environ::Compiler for Compiler {
.into_iter()
.map(|(_i, f)| *f.downcast().unwrap())
.collect();
let compiled_trampolines: Vec<CompiledFunction> = compiled_trampolines
.into_iter()
.map(|f| *f.downcast().unwrap())
.collect();
let mut builder = ModuleTextBuilder::new(obj, &translation.module, &*self.isa);
if self.linkopts.force_jump_veneers {
@@ -307,11 +319,6 @@ impl wasmtime_environ::Compiler for Compiler {
}
let mut addrs = AddressMapSection::default();
let mut traps = TrapEncodingBuilder::default();
let compiled_trampolines = translation
.exported_signatures
.iter()
.map(|i| self.host_to_wasm_trampoline(&types[*i]))
.collect::<Result<Vec<_>, _>>()?;
let mut func_starts = Vec::with_capacity(funcs.len());
for (i, func) in funcs.iter() {
@@ -325,6 +332,10 @@ impl wasmtime_environ::Compiler for Compiler {
}
// Build trampolines for every signature that can be used by this module.
assert_eq!(
translation.exported_signatures.len(),
compiled_trampolines.len()
);
let mut trampolines = Vec::with_capacity(translation.exported_signatures.len());
for (i, func) in translation
.exported_signatures