Skip to content

Commit

Permalink
Use Transient HashMaps to cache wasmi modules for execution.
Browse files Browse the repository at this point in the history
  • Loading branch information
gnunicorn committed Jul 2, 2018
1 parent d55c998 commit 8ae8e11
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 2 deletions.
10 changes: 9 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions substrate/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ substrate-runtime-io = { path = "../runtime-io" }
substrate-primitives = { path = "../primitives" }
substrate-serializer = { path = "../serializer" }
substrate-state-machine = { path = "../state-machine" }
lazy_static = "1.0"
transient-hashmap = "0.4.1"
ed25519 = { path = "../ed25519" }
serde = "1.0"
serde_derive = "1.0"
Expand Down
4 changes: 4 additions & 0 deletions substrate/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ extern crate wasmi;
extern crate byteorder;
extern crate rustc_hex;
extern crate triehash;
extern crate transient_hashmap;
#[macro_use] extern crate log;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate error_chain;

Expand Down
19 changes: 18 additions & 1 deletion substrate/executor/src/wasm_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
//! Rust implementation of Substrate contracts.

use std::cmp::Ordering;
use std::sync::Mutex;
use std::collections::HashMap;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
use transient_hashmap::TransientHashMap;
use wasmi::{
Module, ModuleInstance, MemoryInstance, MemoryRef, TableRef, ImportsBuilder,
};
Expand Down Expand Up @@ -463,6 +467,11 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
#[derive(Debug, Default, Clone)]
pub struct WasmExecutor;

lazy_static! {
static ref MODULE_CACHE: Mutex<TransientHashMap<u64, Module>> = Mutex::new({ TransientHashMap::new(60) });
}


impl CodeExecutor for WasmExecutor {
type Error = Error;

Expand All @@ -473,7 +482,15 @@ impl CodeExecutor for WasmExecutor {
method: &str,
data: &[u8],
) -> Result<Vec<u8>> {
let module = Module::from_buffer(code).expect("all modules compiled with rustc are valid wasm code; qed");

let mut cache = MODULE_CACHE.lock().unwrap();
let module = cache.entry({
let mut h = DefaultHasher::new();
h.write(code);
h.finish()
}).or_insert_with(|| Module::from_buffer(code)
.expect("all modules compiled with rustc are valid wasm code; qed")
);

// start module instantiation. Don't run 'start' function yet.
let intermediate_instance = ModuleInstance::new(
Expand Down

0 comments on commit 8ae8e11

Please sign in to comment.