mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-26 15:11:37 +00:00
Add hidden flag --cache-key
to use prehashed modules for speed
This commit is contained in:
@ -5,8 +5,10 @@ All PRs to the Wasmer repository must add to this file.
|
||||
Blocks of changes will separated by version increments.
|
||||
|
||||
## **[Unreleased]**
|
||||
## 0.5.4
|
||||
- [#537](https://github.com/wasmerio/wasmer/pull/537) Add hidden flag (`--cache-key`) to use prehashed key into the compiled wasm cache
|
||||
- [#536](https://github.com/wasmerio/wasmer/pull/536) Update cache to use compiler backend name in cache key
|
||||
|
||||
## 0.5.4
|
||||
- [#529](https://github.com/wasmerio/wasmer/pull/529) Updates the Wasm Interface library, which is used by wapm, with bug fixes and error message improvements
|
||||
|
||||
## 0.5.3
|
||||
|
@ -77,6 +77,30 @@ impl WasmHash {
|
||||
hex::encode(&self.into_array() as &[u8])
|
||||
}
|
||||
|
||||
/// Create hash from hexadecimal representation
|
||||
pub fn decode(hex_str: &str) -> Result<Self, Error> {
|
||||
let bytes = hex::decode(hex_str).map_err(|e| {
|
||||
Error::DeserializeError(format!(
|
||||
"Could not decode prehashed key as hexadecimal: {}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
if bytes.len() != 64 {
|
||||
return Err(Error::DeserializeError(
|
||||
"Prehashed keys must deserialze into exactly 64 bytes".to_string(),
|
||||
));
|
||||
}
|
||||
use std::convert::TryInto;
|
||||
Ok(WasmHash(
|
||||
bytes[0..32].try_into().map_err(|e| {
|
||||
Error::DeserializeError(format!("Could not get first 32 bytes: {}", e))
|
||||
})?,
|
||||
bytes[32..64].try_into().map_err(|e| {
|
||||
Error::DeserializeError(format!("Could not get last 32 bytes: {}", e))
|
||||
})?,
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn into_array(self) -> [u8; 64] {
|
||||
let mut total = [0u8; 64];
|
||||
total[0..32].copy_from_slice(&self.0);
|
||||
|
@ -24,6 +24,7 @@ use wasmer_runtime::{
|
||||
use wasmer_runtime_core::{
|
||||
self,
|
||||
backend::{Backend, Compiler, CompilerConfig, MemoryBoundCheckMode},
|
||||
debug,
|
||||
loader::{Instance as LoadedInstance, LocalLoader},
|
||||
};
|
||||
#[cfg(feature = "backend:singlepass")]
|
||||
@ -115,9 +116,18 @@ struct Run {
|
||||
#[structopt(long = "resume")]
|
||||
resume: Option<String>,
|
||||
|
||||
/// The command name is a string that will override the first argument passed
|
||||
/// to the wasm program. This is used in wapm to provide nicer output in
|
||||
/// help commands and error messages of the running wasm program
|
||||
#[structopt(long = "command-name", hidden = true)]
|
||||
command_name: Option<String>,
|
||||
|
||||
/// A prehashed string, used to speed up start times by avoiding hashing the
|
||||
/// wasm module. If the specified hash is not found, Wasmer will hash the module
|
||||
/// as if no `cache-key` argument was passed.
|
||||
#[structopt(long = "cache-key", hidden = true)]
|
||||
cache_key: Option<String>,
|
||||
|
||||
/// Application arguments
|
||||
#[structopt(name = "--", raw(multiple = "true"))]
|
||||
args: Vec<String>,
|
||||
@ -350,10 +360,6 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
} else {
|
||||
// If we have cache enabled
|
||||
|
||||
// We generate a hash for the given binary, so we can use it as key
|
||||
// for the Filesystem cache
|
||||
let hash = WasmHash::generate_for_backend(&wasm_binary, options.backend);
|
||||
|
||||
let wasmer_cache_dir = get_cache_dir();
|
||||
|
||||
// We create a new cache instance.
|
||||
@ -362,6 +368,19 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
let mut cache = unsafe {
|
||||
FileSystemCache::new(wasmer_cache_dir).map_err(|e| format!("Cache error: {:?}", e))?
|
||||
};
|
||||
let load_cache_key = || -> Result<_, String> {
|
||||
if let Some(ref prehashed_cache_key) = options.cache_key {
|
||||
if let Ok(module) = WasmHash::decode(prehashed_cache_key)
|
||||
.and_then(|prehashed_key| cache.load(prehashed_key))
|
||||
{
|
||||
debug!("using prehashed key: {}", prehashed_cache_key);
|
||||
return Ok(module);
|
||||
}
|
||||
}
|
||||
|
||||
// We generate a hash for the given binary, so we can use it as key
|
||||
// for the Filesystem cache
|
||||
let hash = WasmHash::generate_for_backend(&wasm_binary, options.backend);
|
||||
|
||||
// cache.load will return the Module if it's able to deserialize it properly, and an error if:
|
||||
// * The file is not found
|
||||
@ -369,7 +388,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
match cache.load(hash) {
|
||||
Ok(module) => {
|
||||
// We are able to load the module from cache
|
||||
module
|
||||
Ok(module)
|
||||
}
|
||||
Err(_) => {
|
||||
let module = webassembly::compile_with_config_with(
|
||||
@ -384,11 +403,14 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
||||
// We try to save the module into a cache file
|
||||
cache.store(hash, module.clone()).unwrap_or_default();
|
||||
|
||||
module
|
||||
Ok(module)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
load_cache_key()?
|
||||
};
|
||||
|
||||
if let Some(loader) = options.loader {
|
||||
let mut import_object = wasmer_runtime_core::import::ImportObject::new();
|
||||
import_object.allow_missing_functions = true; // Import initialization might be left to the loader.
|
||||
|
Reference in New Issue
Block a user