Partial hashing of module for faster caching (#221)
* Simple module compilation cache * Fix base64 encoding bug * Use warn! everywhere in cache system * Remove unused import * Temporary workaround for long path on Windows * Remove unused import for non-windows builds * Add command line argument to enable cache system + apply minor review feedback * Initial implementation of partial module hashing * Proper module hashing for the cache * Use newer version of cranelift
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
//! Data structures for representing decoded wasm modules.
|
||||
|
||||
use crate::module_environ::FunctionBodyData;
|
||||
use crate::tunables::Tunables;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use cranelift_codegen::ir;
|
||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
use cranelift_wasm::{
|
||||
@@ -13,7 +15,7 @@ use std::string::String;
|
||||
use std::vec::Vec;
|
||||
|
||||
/// A WebAssembly table initializer.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Hash)]
|
||||
pub struct TableElements {
|
||||
/// The index of a table to initialize.
|
||||
pub table_index: TableIndex,
|
||||
@@ -26,7 +28,7 @@ pub struct TableElements {
|
||||
}
|
||||
|
||||
/// An entity to export.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum Export {
|
||||
/// Function export.
|
||||
Function(FuncIndex),
|
||||
@@ -39,7 +41,7 @@ pub enum Export {
|
||||
}
|
||||
|
||||
/// Implemenation styles for WebAssembly linear memory.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub enum MemoryStyle {
|
||||
/// The actual memory can be resized and moved.
|
||||
Dynamic,
|
||||
@@ -77,7 +79,7 @@ impl MemoryStyle {
|
||||
|
||||
/// A WebAssembly linear memory description along with our chosen style for
|
||||
/// implementing it.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub struct MemoryPlan {
|
||||
/// The WebAssembly linear memory description.
|
||||
pub memory: Memory,
|
||||
@@ -100,7 +102,7 @@ impl MemoryPlan {
|
||||
}
|
||||
|
||||
/// Implemenation styles for WebAssembly tables.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub enum TableStyle {
|
||||
/// Signatures are stored in the table and checked in the caller.
|
||||
CallerChecksSignature,
|
||||
@@ -115,7 +117,7 @@ impl TableStyle {
|
||||
|
||||
/// A WebAssembly table description along with our chosen style for
|
||||
/// implementing it.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
pub struct TablePlan {
|
||||
/// The WebAssembly table description.
|
||||
pub table: cranelift_wasm::Table,
|
||||
@@ -133,6 +135,7 @@ impl TablePlan {
|
||||
|
||||
/// A translated WebAssembly module, excluding the function bodies and
|
||||
/// memory initializers.
|
||||
// WARNING: when modifying, make sure that `hash_for_cache` is still valid!
|
||||
#[derive(Debug)]
|
||||
pub struct Module {
|
||||
/// Unprocessed signatures exactly as provided by `declare_signature()`.
|
||||
@@ -170,10 +173,6 @@ pub struct Module {
|
||||
|
||||
/// WebAssembly table initializers.
|
||||
pub table_elements: Vec<TableElements>,
|
||||
|
||||
/// Hash of the source wasm code if this module is not synthesized.
|
||||
/// TODO: this is temporary workaround. Will be replaced with derive macro.
|
||||
pub hash: Option<[u8; 32]>,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
@@ -192,7 +191,6 @@ impl Module {
|
||||
exports: IndexMap::new(),
|
||||
start_func: None,
|
||||
table_elements: Vec::new(),
|
||||
hash: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,4 +281,29 @@ impl Module {
|
||||
pub fn is_imported_global(&self, index: GlobalIndex) -> bool {
|
||||
index.index() < self.imported_globals.len()
|
||||
}
|
||||
|
||||
/// Computes hash of the module for the purpose of caching.
|
||||
pub fn hash_for_cache<'data, H>(
|
||||
&self,
|
||||
function_body_inputs: &PrimaryMap<DefinedFuncIndex, FunctionBodyData<'data>>,
|
||||
state: &mut H,
|
||||
) where
|
||||
H: Hasher,
|
||||
{
|
||||
// There's no need to cache names (strings), start function
|
||||
// and data initializers (for both memory and tables)
|
||||
self.signatures.hash(state);
|
||||
self.functions.hash(state);
|
||||
self.table_plans.hash(state);
|
||||
self.memory_plans.hash(state);
|
||||
self.globals.hash(state);
|
||||
// IndexMap (self.export) iterates over values in order of item inserts
|
||||
// Let's actually sort the values.
|
||||
let mut exports = self.exports.values().collect::<Vec<_>>();
|
||||
exports.sort();
|
||||
for val in exports {
|
||||
val.hash(state);
|
||||
}
|
||||
function_body_inputs.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user