Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign the exposed cache api. #198

Merged
merged 15 commits into from
Feb 22, 2019
Merged
7 changes: 7 additions & 0 deletions Cargo.lock

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

8 changes: 0 additions & 8 deletions lib/clif-backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,16 @@ libc = "0.2.48"
# Dependencies for caching.
[dependencies.serde]
version = "1.0"
optional = true
[dependencies.serde_derive]
version = "1.0"
optional = true
[dependencies.serde_bytes]
version = "0.10"
optional = true
# [dependencies.bincode]
# version = "1.0.1"
# optional = true
[dependencies.serde-bench]
version = "0.0.7"
optional = true

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.0.1" }

[features]
cache = ["serde", "serde_derive", "serde_bytes", "serde-bench", "wasmer-runtime-core/cache"]
debug = ["wasmer-runtime-core/debug"]
52 changes: 43 additions & 9 deletions lib/clif-backend/src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,50 @@
use crate::relocation::{ExternalRelocation, TrapSink};

use hashbrown::HashMap;
use std::sync::Arc;
use wasmer_runtime_core::{
backend::sys::Memory,
cache::{Cache, Error},
module::ModuleInfo,
backend::{sys::Memory, CacheGen},
cache::{Error, SerializedCache},
module::{ModuleInfo, ModuleInner},
structures::Map,
types::{LocalFuncIndex, SigIndex},
};

use serde_bench::{deserialize, serialize};

pub struct CacheGenerator {
backend_cache: BackendCache,
memory: Arc<Memory>,
}

impl CacheGenerator {
pub fn new(backend_cache: BackendCache, memory: Arc<Memory>) -> Self {
Self {
backend_cache,
memory,
}
}
}

impl CacheGen for CacheGenerator {
fn generate_cache(
&self,
module: &ModuleInner,
) -> Result<(Box<ModuleInfo>, Box<[u8]>, Memory), Error> {
let info = Box::new(module.info.clone());

// Clone the memory to a new location. This could take a long time,
// depending on the throughput of your memcpy implementation.
let compiled_code = (*self.memory).clone();

Ok((
info,
self.backend_cache.into_backend_data()?.into_boxed_slice(),
compiled_code,
))
}
}

#[derive(Serialize, Deserialize)]
pub struct TrampolineCache {
#[serde(with = "serde_bytes")]
Expand All @@ -22,24 +56,24 @@ pub struct TrampolineCache {
pub struct BackendCache {
pub external_relocs: Map<LocalFuncIndex, Box<[ExternalRelocation]>>,
pub offsets: Map<LocalFuncIndex, usize>,
pub trap_sink: TrapSink,
pub trap_sink: Arc<TrapSink>,
pub trampolines: TrampolineCache,
}

impl BackendCache {
pub fn from_cache(cache: Cache) -> Result<(ModuleInfo, Memory, Self), Error> {
pub fn from_cache(cache: SerializedCache) -> Result<(ModuleInfo, Memory, Self), Error> {
let (info, backend_data, compiled_code) = cache.consume();

let backend_cache = deserialize(backend_data.as_slice())
.map_err(|e| Error::DeserializeError(e.to_string()))?;
let backend_cache =
deserialize(&backend_data).map_err(|e| Error::DeserializeError(e.to_string()))?;

Ok((info, compiled_code, backend_cache))
}

pub fn into_backend_data(self) -> Result<Vec<u8>, Error> {
pub fn into_backend_data(&self) -> Result<Vec<u8>, Error> {
let mut buffer = Vec::new();

serialize(&mut buffer, &self).map_err(|e| Error::SerializeError(e.to_string()))?;
serialize(&mut buffer, self).map_err(|e| Error::SerializeError(e.to_string()))?;

Ok(buffer)
}
Expand Down
134 changes: 69 additions & 65 deletions lib/clif-backend/src/func_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
let ptr_type = self.pointer_type();

let local_global_addr = match global_index.local_or_import(self.env.module) {
let local_global_addr = match global_index.local_or_import(&self.env.module.info) {
LocalOrImport::Local(local_global_index) => {
let globals_base_addr = func.create_global_value(ir::GlobalValueData::Load {
base: vmctx,
Expand Down Expand Up @@ -145,48 +145,49 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
let ptr_type = self.pointer_type();

let (local_memory_ptr_ptr, description) = match mem_index.local_or_import(self.env.module) {
LocalOrImport::Local(local_mem_index) => {
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
base: vmctx,
offset: (vm::Ctx::offset_memories() as i32).into(),
global_type: ptr_type,
readonly: true,
});

let local_memory_ptr_offset =
local_mem_index.index() * mem::size_of::<*mut vm::LocalMemory>();
let (local_memory_ptr_ptr, description) =
match mem_index.local_or_import(&self.env.module.info) {
LocalOrImport::Local(local_mem_index) => {
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
base: vmctx,
offset: (vm::Ctx::offset_memories() as i32).into(),
global_type: ptr_type,
readonly: true,
});

(
func.create_global_value(ir::GlobalValueData::IAddImm {
base: memories_base_addr,
offset: (local_memory_ptr_offset as i64).into(),
let local_memory_ptr_offset =
local_mem_index.index() * mem::size_of::<*mut vm::LocalMemory>();

(
func.create_global_value(ir::GlobalValueData::IAddImm {
base: memories_base_addr,
offset: (local_memory_ptr_offset as i64).into(),
global_type: ptr_type,
}),
self.env.module.info.memories[local_mem_index],
)
}
LocalOrImport::Import(import_mem_index) => {
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
base: vmctx,
offset: (vm::Ctx::offset_imported_memories() as i32).into(),
global_type: ptr_type,
}),
self.env.module.info.memories[local_mem_index],
)
}
LocalOrImport::Import(import_mem_index) => {
let memories_base_addr = func.create_global_value(ir::GlobalValueData::Load {
base: vmctx,
offset: (vm::Ctx::offset_imported_memories() as i32).into(),
global_type: ptr_type,
readonly: true,
});
readonly: true,
});

let local_memory_ptr_offset =
import_mem_index.index() * mem::size_of::<*mut vm::LocalMemory>();
let local_memory_ptr_offset =
import_mem_index.index() * mem::size_of::<*mut vm::LocalMemory>();

(
func.create_global_value(ir::GlobalValueData::IAddImm {
base: memories_base_addr,
offset: (local_memory_ptr_offset as i64).into(),
global_type: ptr_type,
}),
self.env.module.info.imported_memories[import_mem_index].1,
)
}
};
(
func.create_global_value(ir::GlobalValueData::IAddImm {
base: memories_base_addr,
offset: (local_memory_ptr_offset as i64).into(),
global_type: ptr_type,
}),
self.env.module.info.imported_memories[import_mem_index].1,
)
}
};

let (local_memory_ptr, local_memory_base) = {
let local_memory_ptr = func.create_global_value(ir::GlobalValueData::Load {
Expand Down Expand Up @@ -253,7 +254,8 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
let ptr_type = self.pointer_type();

let (table_struct_ptr_ptr, description) = match table_index.local_or_import(self.env.module)
let (table_struct_ptr_ptr, description) = match table_index
.local_or_import(&self.env.module.info)
{
LocalOrImport::Local(local_table_index) => {
let tables_base = func.create_global_value(ir::GlobalValueData::Load {
Expand Down Expand Up @@ -476,7 +478,7 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {
) -> cranelift_wasm::WasmResult<ir::Inst> {
let callee_index: FuncIndex = Converter(clif_callee_index).into();

match callee_index.local_or_import(self.env.module) {
match callee_index.local_or_import(&self.env.module.info) {
LocalOrImport::Local(_) => {
// this is an internal function
let vmctx = pos
Expand Down Expand Up @@ -568,18 +570,19 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {

let mem_index: MemoryIndex = Converter(clif_mem_index).into();

let (namespace, mem_index, description) = match mem_index.local_or_import(self.env.module) {
LocalOrImport::Local(local_mem_index) => (
call_names::LOCAL_NAMESPACE,
local_mem_index.index(),
self.env.module.info.memories[local_mem_index],
),
LocalOrImport::Import(import_mem_index) => (
call_names::IMPORT_NAMESPACE,
import_mem_index.index(),
self.env.module.info.imported_memories[import_mem_index].1,
),
};
let (namespace, mem_index, description) =
match mem_index.local_or_import(&self.env.module.info) {
LocalOrImport::Local(local_mem_index) => (
call_names::LOCAL_NAMESPACE,
local_mem_index.index(),
self.env.module.info.memories[local_mem_index],
),
LocalOrImport::Import(import_mem_index) => (
call_names::IMPORT_NAMESPACE,
import_mem_index.index(),
self.env.module.info.imported_memories[import_mem_index].1,
),
};

let name_index = match description.memory_type() {
MemoryType::Dynamic => call_names::DYNAMIC_MEM_GROW,
Expand Down Expand Up @@ -631,18 +634,19 @@ impl<'env, 'module, 'isa> FuncEnvironment for FuncEnv<'env, 'module, 'isa> {

let mem_index: MemoryIndex = Converter(clif_mem_index).into();

let (namespace, mem_index, description) = match mem_index.local_or_import(self.env.module) {
LocalOrImport::Local(local_mem_index) => (
call_names::LOCAL_NAMESPACE,
local_mem_index.index(),
self.env.module.info.memories[local_mem_index],
),
LocalOrImport::Import(import_mem_index) => (
call_names::IMPORT_NAMESPACE,
import_mem_index.index(),
self.env.module.info.imported_memories[import_mem_index].1,
),
};
let (namespace, mem_index, description) =
match mem_index.local_or_import(&self.env.module.info) {
LocalOrImport::Local(local_mem_index) => (
call_names::LOCAL_NAMESPACE,
local_mem_index.index(),
self.env.module.info.memories[local_mem_index],
),
LocalOrImport::Import(import_mem_index) => (
call_names::IMPORT_NAMESPACE,
import_mem_index.index(),
self.env.module.info.imported_memories[import_mem_index].1,
),
};

let name_index = match description.memory_type() {
MemoryType::Dynamic => call_names::DYNAMIC_MEM_SIZE,
Expand Down
Loading