Get caching working again

This commit is contained in:
Lachlan Sneff
2019-02-20 16:41:41 -08:00
parent 82eea00a02
commit 9f40eedba8
21 changed files with 244 additions and 246 deletions

View File

@ -2,7 +2,7 @@ use crate::{
backing::ImportBacking,
error::CompileResult,
error::RuntimeResult,
module::{ModuleInner},
module::ModuleInner,
types::{FuncIndex, LocalFuncIndex, Value},
vm,
};
@ -21,8 +21,7 @@ pub mod sys {
}
pub use crate::sig_registry::SigRegistry;
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
pub enum Backend {
Cranelift,
}
@ -45,7 +44,6 @@ pub trait Compiler {
/// be called from inside the runtime.
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner>;
unsafe fn from_cache(&self, cache: Cache, _: Token) -> Result<ModuleInner, CacheError>;
}
@ -95,7 +93,9 @@ pub trait FuncResolver: Send + Sync {
) -> Option<NonNull<vm::Func>>;
}
pub trait CacheGen: Send + Sync {
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Arc<Memory>), CacheError>;
}
fn generate_cache(
&self,
module: &ModuleInner,
) -> Result<(Box<ModuleInfo>, Box<[u8]>, Memory), CacheError>;
}

View File

@ -6,9 +6,9 @@ use std::{
fs::File,
io::{self, Seek, SeekFrom, Write},
mem,
sync::Arc,
path::Path,
slice,
sync::Arc,
};
#[derive(Debug)]
@ -69,7 +69,7 @@ struct CacheInner {
info: Box<ModuleInfo>,
#[serde(with = "serde_bytes")]
backend_metadata: Box<[u8]>,
compiled_code: Arc<Memory>,
compiled_code: Memory,
}
pub struct Cache {
@ -80,7 +80,7 @@ impl Cache {
pub(crate) fn from_parts(
info: Box<ModuleInfo>,
backend_metadata: Box<[u8]>,
compiled_code: Arc<Memory>,
compiled_code: Memory,
) -> Self {
Self {
inner: CacheInner {
@ -104,9 +104,7 @@ impl Cache {
let inner =
deserialize(body_slice).map_err(|e| Error::DeserializeError(format!("{:#?}", e)))?;
Ok(Cache {
inner,
})
Ok(Cache { inner })
}
pub fn info(&self) -> &ModuleInfo {
@ -114,7 +112,7 @@ impl Cache {
}
#[doc(hidden)]
pub fn consume(self) -> (ModuleInfo, Box<[u8]>, Arc<Memory>) {
pub fn consume(self) -> (ModuleInfo, Box<[u8]>, Memory) {
(
*self.inner.info,
self.inner.backend_metadata,

View File

@ -2,7 +2,6 @@
#[macro_use]
extern crate field_offset;
#[macro_use]
extern crate serde_derive;
@ -44,7 +43,6 @@ pub use self::module::Module;
pub use self::typed_func::Func;
use std::sync::Arc;
use self::cache::{Cache, Error as CacheError};
pub mod prelude {
@ -90,7 +88,7 @@ pub fn validate(wasm: &[u8]) -> bool {
}
}
//
//
// pub fn compile_to_cache_with(
// wasm: &[u8],
// compiler: &dyn backend::Compiler,
@ -102,7 +100,6 @@ pub fn validate(wasm: &[u8]) -> bool {
// Ok(Cache::new(wasm, info, backend_metadata, compiled_code))
// }
pub unsafe fn load_cache_with(
cache: Cache,
compiler: &dyn backend::Compiler,

View File

@ -1,5 +1,6 @@
use crate::{
backend::{Backend, FuncResolver, ProtectedCaller},
cache::{Cache, Error as CacheError},
error,
import::ImportObject,
structures::{Map, TypedIndex},
@ -10,7 +11,6 @@ use crate::{
LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryDescriptor, MemoryIndex,
SigIndex, TableDescriptor, TableIndex,
},
cache::{Cache, Error as CacheError},
Instance,
};
@ -25,14 +25,12 @@ pub struct ModuleInner {
pub func_resolver: Box<dyn FuncResolver>,
pub protected_caller: Box<dyn ProtectedCaller>,
pub cache_gen: Box<dyn CacheGen>,
pub info: ModuleInfo,
}
#[derive(Clone)]
#[derive(Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize)]
pub struct ModuleInfo {
// This are strictly local and the typsystem ensures that.
pub memories: Map<LocalMemoryIndex, MemoryDescriptor>,
@ -62,12 +60,9 @@ pub struct ModuleInfo {
pub wasm_hash: WasmHash,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct WasmHash([u8; 32]);
impl WasmHash {
pub fn generate(wasm: &[u8]) -> Self {
WasmHash(crate::cache::hash_data(wasm))
@ -125,23 +120,25 @@ impl Module {
}
pub fn cache(&self) -> Result<Cache, CacheError> {
let (info, backend_cache, code) = self.inner.cache_gen.generate_cache(&self.inner)?;
let (info, backend_metadata, code) = self.inner.cache_gen.generate_cache(&self.inner)?;
Ok(Cache::from_parts(info, backend_metadata, code))
}
pub fn info(&self) -> &ModuleInfo {
&self.inner.info
}
}
impl ModuleInner {}
#[doc(hidden)]
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ImportName {
pub namespace_index: NamespaceIndex,
pub name_index: NameIndex,
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExportIndex {
Func(FuncIndex),
Memory(MemoryIndex),
@ -150,8 +147,7 @@ pub enum ExportIndex {
}
/// A data initializer for linear memory.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DataInitializer {
/// The index of the memory to initialize.
pub memory_index: MemoryIndex,
@ -163,8 +159,7 @@ pub struct DataInitializer {
}
/// A WebAssembly table initializer.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct TableInitializer {
/// The index of a table to initialize.
pub table_index: TableIndex,
@ -225,8 +220,7 @@ impl<K: TypedIndex> StringTableBuilder<K> {
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct StringTable<K: TypedIndex> {
table: Map<K, (u32, u32)>,
buffer: String,
@ -249,8 +243,7 @@ impl<K: TypedIndex> StringTable<K> {
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct NamespaceIndex(u32);
impl TypedIndex for NamespaceIndex {
@ -265,8 +258,7 @@ impl TypedIndex for NamespaceIndex {
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct NameIndex(u32);
impl TypedIndex for NameIndex {

View File

@ -8,8 +8,7 @@ use std::{
};
/// Dense item map
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Map<K, V>
where
K: TypedIndex,

View File

@ -10,7 +10,6 @@ pub use self::unix::*;
#[cfg(windows)]
pub use self::windows::*;
use serde::{
de::{self, SeqAccess, Visitor},
ser::SerializeStruct,
@ -21,7 +20,6 @@ use serde_bytes::Bytes;
use std::fmt;
impl Serialize for Memory {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@ -36,7 +34,6 @@ impl Serialize for Memory {
}
}
impl<'de> Deserialize<'de> for Memory {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where

View File

@ -207,16 +207,26 @@ impl Drop for Memory {
impl Clone for Memory {
fn clone(&self) -> Self {
let mut new = Memory::with_size_protect(self.size, self.protection).unwrap();
let temp_protection = if self.protection.is_writable() {
self.protection
} else {
Protect::ReadWrite
};
let mut new = Memory::with_size_protect(self.size, temp_protection).unwrap();
unsafe {
new.as_slice_mut().copy_from_slice(self.as_slice());
if temp_protection != self.protection {
new.protect(.., self.protection).unwrap();
}
}
new
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Protect {
None,

View File

@ -158,16 +158,26 @@ impl Drop for Memory {
impl Clone for Memory {
fn clone(&self) -> Self {
let mut new = Memory::with_size_protect(self.size, self.protection).unwrap();
let temp_protection = if self.protection.is_writable() {
self.protection
} else {
Protect::ReadWrite
};
let mut new = Memory::with_size_protect(self.size, temp_protection).unwrap();
unsafe {
new.as_slice_mut().copy_from_slice(self.as_slice());
if temp_protection != self.protection {
new.protect(.., self.protection).unwrap();
}
}
new
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Protect {
None,

View File

@ -2,8 +2,7 @@ use crate::{memory::MemoryType, module::ModuleInfo, structures::TypedIndex, unit
use std::{borrow::Cow, mem};
/// Represents a WebAssembly type.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Type {
/// The `i32` type.
I32,
@ -25,8 +24,7 @@ impl std::fmt::Display for Type {
///
/// As the number of types in WebAssembly expand,
/// this structure will expand as well.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum Value {
/// The `i32` type.
I32(i32),
@ -171,15 +169,13 @@ impl ValueType for f64 {
}
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ElementType {
/// Any wasm function.
Anyfunc,
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, Copy)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct TableDescriptor {
/// Type of data stored in this table.
pub element: ElementType,
@ -203,8 +199,7 @@ impl TableDescriptor {
/// A const value initializer.
/// Over time, this will be able to represent more and more
/// complex expressions.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum Initializer {
/// Corresponds to a `const.*` instruction.
Const(Value),
@ -212,24 +207,21 @@ pub enum Initializer {
GetGlobal(ImportedGlobalIndex),
}
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct GlobalDescriptor {
pub mutable: bool,
pub ty: Type,
}
/// A wasm global.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GlobalInit {
pub desc: GlobalDescriptor,
pub init: Initializer,
}
/// A wasm memory.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MemoryDescriptor {
/// The minimum number of allowed pages.
pub minimum: Pages,
@ -261,8 +253,7 @@ impl MemoryDescriptor {
/// The signature of a function that is either implemented
/// in a wasm module or exposed to wasm by the host.
#[derive(Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
pub struct FuncSig {
params: Cow<'static, [Type]>,
returns: Cow<'static, [Type]>,
@ -400,8 +391,7 @@ define_local_or_import![
(GlobalIndex | (LocalGlobalIndex, ImportedGlobalIndex): imported_globals),
];
#[derive(Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SigIndex(u32);
impl TypedIndex for SigIndex {
#[doc(hidden)]

View File

@ -7,8 +7,7 @@ const WASM_PAGE_SIZE: usize = 65_536;
const WASM_MAX_PAGES: usize = 65_536;
/// Units of WebAssembly pages (as specified to be 65,536 bytes).
#[derive(Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Pages(pub u32);
impl Pages {
@ -33,8 +32,7 @@ impl fmt::Debug for Pages {
}
/// Units of WebAssembly memory in terms of 8-bit bytes.
#[derive(Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Bytes(pub usize);
impl fmt::Debug for Bytes {

View File

@ -494,11 +494,13 @@ mod vm_ctx_tests {
fn generate_module() -> ModuleInner {
use super::Func;
use crate::backend::{Backend, FuncResolver, ProtectedCaller, Token, UserTrapper, CacheGen, sys::Memory};
use crate::backend::{
sys::Memory, Backend, CacheGen, FuncResolver, ProtectedCaller, Token, UserTrapper,
};
use crate::cache::Error as CacheError;
use crate::error::RuntimeResult;
use crate::types::{FuncIndex, LocalFuncIndex, Value};
use crate::module::WasmHash;
use crate::types::{FuncIndex, LocalFuncIndex, Value};
use hashbrown::HashMap;
use std::ptr::NonNull;
struct Placeholder;
@ -528,11 +530,13 @@ mod vm_ctx_tests {
}
}
impl CacheGen for Placeholder {
fn generate_cache(&self, module: &ModuleInner) -> Result<(Box<ModuleInfo>, Box<[u8]>, Memory), CacheError> {
fn generate_cache(
&self,
module: &ModuleInner,
) -> Result<(Box<ModuleInfo>, Box<[u8]>, Memory), CacheError> {
unimplemented!()
}
}
ModuleInner {
func_resolver: Box::new(Placeholder),