Remove global state for trap registration (#909)

* Remove global state for trap registration

There's a number of changes brought about in this commit, motivated by a
few things. One motivation was to remove an instance of using
`lazy_static!` in an effort to remove global state and encapsulate it
wherever possible. A second motivation came when investigating a
slowly-compiling wasm module (a bit too slowly) where a good chunk of
time was spent in managing trap registrations.

The specific change made here is that `TrapRegistry` is now stored
inside of a `Compiler` instead of inside a global. Additionally traps
are "bulk registered" for a module rather than one-by-one. This form of
bulk-registration allows optimizing the locks used here, where a lock is
only held for a module at-a-time instead of once-per-function.

With these changes the "unregister" logic has also been tweaked a bit
here and there to continue to work. As a nice side effect the `Compiler`
type now has one fewer field that requires actual mutability and has
been updated for multi-threaded compilation, nudging us closer to a
world where we can support multi-threaded compilation. Yay!

In terms of performance improvements, a local wasm test file that
previously took 3 seconds to compile is now 10% faster to compile,
taking ~2.7 seconds now.

* Perform trap resolution after unwinding

This avoids taking locks in signal handlers which feels a bit iffy...

* Remove `TrapRegistration::dummy()`

Avoid an case where you're trying to lookup trap information from a
dummy module for something that happened in a different module.

* Tweak some comments
This commit is contained in:
Alex Crichton
2020-02-06 12:40:50 -06:00
committed by GitHub
parent 9dffaf9d57
commit 348c597a8e
14 changed files with 233 additions and 131 deletions

View File

@@ -12,7 +12,7 @@ use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody};
pub(crate) fn create_handle(
module: Module,
store: Option<&Store>,
store: &Store,
finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody>,
state: Box<dyn Any>,
) -> Result<InstanceHandle> {
@@ -26,19 +26,16 @@ pub(crate) fn create_handle(
let data_initializers = Vec::new();
// Compute indices into the shared signature table.
let signatures = store
.map(|store| {
module
.signatures
.values()
.map(|sig| store.compiler().signatures().register(sig))
.collect::<PrimaryMap<_, _>>()
})
.unwrap_or_else(PrimaryMap::new);
let signatures = module
.signatures
.values()
.map(|sig| store.compiler().signatures().register(sig))
.collect::<PrimaryMap<_, _>>();
unsafe {
Ok(InstanceHandle::new(
Arc::new(module),
store.compiler().trap_registry().register_traps(Vec::new()),
finished_functions.into_boxed_slice(),
imports,
&data_initializers,