Implement caching for parser refactor

This commit is contained in:
Brandon Fish
2019-05-05 20:11:47 -05:00
parent 4770277b15
commit 0926a5020e
3 changed files with 73 additions and 39 deletions

View File

@ -10,10 +10,11 @@ use inkwell::{
use smallvec::SmallVec; use smallvec::SmallVec;
use std::sync::Arc; use std::sync::Arc;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::Backend, backend::{Backend, CacheGen, Token},
cache::{Artifact, Error as CacheError},
codegen::*, codegen::*,
memory::MemoryType, memory::MemoryType,
module::ModuleInfo, module::{ModuleInfo, ModuleInner},
structures::{Map, SliceMap, TypedIndex}, structures::{Map, SliceMap, TypedIndex},
types::{ types::{
FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex, FuncIndex, FuncSig, GlobalIndex, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex,
@ -25,7 +26,7 @@ use wasmparser::{
Type as WpType, Type as WpType,
}; };
use crate::backend::LLVMBackend; use crate::backend::{LLVMBackend, LLVMCache};
use crate::intrinsics::{CtxType, GlobalCache, Intrinsics, MemoryCache}; use crate::intrinsics::{CtxType, GlobalCache, Intrinsics, MemoryCache};
use crate::read_info::type_to_type; use crate::read_info::type_to_type;
use crate::state::{ControlFrame, IfElseState, State}; use crate::state::{ControlFrame, IfElseState, State};
@ -4640,7 +4641,10 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
Ok(self.functions.last_mut().unwrap()) Ok(self.functions.last_mut().unwrap())
} }
fn finalize(self, module_info: &ModuleInfo) -> Result<LLVMBackend, CodegenError> { fn finalize(
self,
module_info: &ModuleInfo,
) -> Result<(LLVMBackend, Box<dyn CacheGen>), CodegenError> {
// self.module.print_to_stderr(); // self.module.print_to_stderr();
generate_trampolines( generate_trampolines(
@ -4668,8 +4672,8 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
// self.module.print_to_stderr(); // self.module.print_to_stderr();
let (backend, _cache_gen) = LLVMBackend::new(self.module, self.intrinsics); let (backend, cache_gen) = LLVMBackend::new(self.module, self.intrinsics);
Ok(backend) Ok((backend, Box::new(cache_gen)))
} }
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> { fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
@ -4693,4 +4697,17 @@ impl ModuleCodeGenerator<LLVMFunctionCodeGenerator, LLVMBackend, CodegenError>
self.func_import_count += 1; self.func_import_count += 1;
Ok(()) Ok(())
} }
unsafe fn from_cache(artifact: Artifact, _: Token) -> Result<ModuleInner, CacheError> {
let (info, _, memory) = artifact.consume();
let (backend, cache_gen) =
LLVMBackend::from_buffer(memory).map_err(CacheError::DeserializeError)?;
Ok(ModuleInner {
runnable_module: Box::new(backend),
cache_gen: Box::new(cache_gen),
info,
})
}
} }

View File

@ -50,7 +50,7 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
/// Creates a new function and returns the function-scope code generator for it. /// Creates a new function and returns the function-scope code generator for it.
fn next_function(&mut self) -> Result<&mut FCG, E>; fn next_function(&mut self) -> Result<&mut FCG, E>;
fn finalize(self, module_info: &ModuleInfo) -> Result<RM, E>; fn finalize(self, module_info: &ModuleInfo) -> Result<(RM, Box<dyn CacheGen>), E>;
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), E>; fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), E>;
/// Sets function signatures. /// Sets function signatures.
@ -58,6 +58,8 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
/// Adds an import function. /// Adds an import function.
fn feed_import_function(&mut self) -> Result<(), E>; fn feed_import_function(&mut self) -> Result<(), E>;
unsafe fn from_cache(cache: Artifact, _: Token) -> Result<ModuleInner, CacheError>;
} }
pub struct StreamingCompiler< pub struct StreamingCompiler<
@ -131,15 +133,6 @@ impl<
compiler_config: CompilerConfig, compiler_config: CompilerConfig,
_: Token, _: Token,
) -> CompileResult<ModuleInner> { ) -> CompileResult<ModuleInner> {
struct Placeholder;
impl CacheGen for Placeholder {
fn generate_cache(&self) -> Result<(Box<[u8]>, Memory), CacheError> {
Err(CacheError::Unknown(
"the streaming compiler API doesn't support caching yet".to_string(),
))
}
}
let mut mcg = MCG::new(); let mut mcg = MCG::new();
let mut chain = (self.middleware_chain_generator)(); let mut chain = (self.middleware_chain_generator)();
let info = crate::parse::read_module( let info = crate::parse::read_module(
@ -149,22 +142,24 @@ impl<
&mut chain, &mut chain,
&compiler_config, &compiler_config,
)?; )?;
let exec_context = mcg let (exec_context, cache_gen) =
.finalize(&info) mcg.finalize(&info)
.map_err(|x| CompileError::InternalError { .map_err(|x| CompileError::InternalError {
msg: format!("{:?}", x), msg: format!("{:?}", x),
})?; })?;
Ok(ModuleInner { Ok(ModuleInner {
cache_gen: Box::new(Placeholder), cache_gen,
runnable_module: Box::new(exec_context), runnable_module: Box::new(exec_context),
info: info, info,
}) })
} }
unsafe fn from_cache(&self, _artifact: Artifact, _: Token) -> Result<ModuleInner, CacheError> { unsafe fn from_cache(
Err(CacheError::Unknown( &self,
"the streaming compiler API doesn't support caching yet".to_string(), artifact: Artifact,
)) token: Token,
) -> Result<ModuleInner, CacheError> {
MCG::from_cache(artifact, token)
} }
} }

View File

@ -10,10 +10,11 @@ use smallvec::SmallVec;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::{any::Any, collections::HashMap, sync::Arc}; use std::{any::Any, collections::HashMap, sync::Arc};
use wasmer_runtime_core::{ use wasmer_runtime_core::{
backend::{Backend, RunnableModule}, backend::{sys::Memory, Backend, CacheGen, RunnableModule, Token},
cache::{Artifact, Error as CacheError},
codegen::*, codegen::*,
memory::MemoryType, memory::MemoryType,
module::ModuleInfo, module::{ModuleInfo, ModuleInner},
structures::{Map, TypedIndex}, structures::{Map, TypedIndex},
typed_func::Wasm, typed_func::Wasm,
types::{ types::{
@ -349,7 +350,10 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
Ok(self.functions.last_mut().unwrap()) Ok(self.functions.last_mut().unwrap())
} }
fn finalize(mut self, _: &ModuleInfo) -> Result<X64ExecutionContext, CodegenError> { fn finalize(
mut self,
_: &ModuleInfo,
) -> Result<(X64ExecutionContext, Box<dyn CacheGen>), CodegenError> {
let (assembler, mut br_table_data, breakpoints) = match self.functions.last_mut() { let (assembler, mut br_table_data, breakpoints) = match self.functions.last_mut() {
Some(x) => ( Some(x) => (
x.assembler.take().unwrap(), x.assembler.take().unwrap(),
@ -404,7 +408,17 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
.collect(), .collect(),
); );
Ok(X64ExecutionContext { struct Placeholder;
impl CacheGen for Placeholder {
fn generate_cache(&self) -> Result<(Box<[u8]>, Memory), CacheError> {
Err(CacheError::Unknown(
"the singlepass backend doesn't support caching yet".to_string(),
))
}
}
Ok((
X64ExecutionContext {
code: output, code: output,
functions: self.functions, functions: self.functions,
signatures: self.signatures.as_ref().unwrap().clone(), signatures: self.signatures.as_ref().unwrap().clone(),
@ -412,7 +426,9 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
breakpoints: breakpoints, breakpoints: breakpoints,
func_import_count: self.func_import_count, func_import_count: self.func_import_count,
function_pointers: out_labels, function_pointers: out_labels,
}) },
Box::new(Placeholder),
))
} }
fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> { fn feed_signatures(&mut self, signatures: Map<SigIndex, FuncSig>) -> Result<(), CodegenError> {
@ -461,6 +477,12 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
Ok(()) Ok(())
} }
unsafe fn from_cache(artifact: Artifact, _: Token) -> Result<ModuleInner, CacheError> {
Err(CacheError::Unknown(
"the singlepass compiler API doesn't support caching yet".to_string(),
))
}
} }
impl X64FunctionCode { impl X64FunctionCode {