Avoid serializing/reparsing modules during gc

Currently the `wasm-gc-api` crate doesn't expose `parity_wasm::Module` as a
public dependency which means that whenever we want to run a GC (which is twice
per `wasm-bindgen` invocation) we have to serialize and reparse the module a
lot! The `wasm-bindgen` has to serialize, `wasm-gc` then parses, `wasm-gc` then
serializes, and `wasm-bindgen` then parses.

This commit sidesteps all of these operations by ensuring that we always use the
same `parity_wasm::Module` instance, even when multiple versions of the
`parity_wasm` crate are in use. We'll get a speed boost when they happen to
align (which they always should for `wasm-bindgen`), but it'll work even if they
aren't aligned (by going through serialization).

Concretely on my machine this takes a `wasm-bindgen` invocation from 0.5s to
0.2s, a nice win!
This commit is contained in:
Alex Crichton 2018-07-25 15:39:17 -07:00
parent 19acb5bb72
commit 9b5d47f5e1
2 changed files with 7 additions and 5 deletions

View File

@ -19,5 +19,5 @@ serde_derive = "1.0"
serde_json = "1.0"
tempfile = "3.0"
wasm-bindgen-shared = { path = "../shared", version = '=0.2.14' }
wasm-gc-api = "0.1.8"
wasm-gc-api = "0.1.9"
wasmi = "0.3"

View File

@ -1580,12 +1580,14 @@ impl<'a> Context<'a> {
fn gc(&mut self) -> Result<(), Error> {
let module = mem::replace(self.module, Module::default());
let wasm_bytes = parity_wasm::serialize(module)?;
let bytes = wasm_gc::Config::new()
let result = wasm_gc::Config::new()
.demangle(self.config.demangle)
.keep_debug(self.config.keep_debug || self.config.debug)
.gc(&wasm_bytes)?;
*self.module = deserialize_buffer(&bytes)?;
.run(module, |m| parity_wasm::serialize(m).unwrap())?;
*self.module = match result.into_module() {
Ok(m) => m,
Err(result) => deserialize_buffer(&result.into_bytes()?)?,
};
Ok(())
}