Merge branch 'master' into blake3

This commit is contained in:
Syrus Akbary
2020-01-13 13:26:31 +01:00
committed by GitHub
22 changed files with 242 additions and 218 deletions

View File

@ -52,9 +52,5 @@ cc = "1.0"
[features]
debug = []
trace = ["debug"]
# backend flags used in conditional compilation of Backend::variants
"backend-cranelift" = []
"backend-singlepass" = []
"backend-llvm" = []
managed = []
deterministic-execution = ["wasmparser/deterministic"]

View File

@ -22,60 +22,6 @@ pub mod sys {
}
pub use crate::sig_registry::SigRegistry;
/// Enum used to select which compiler should be used to generate code.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
pub enum Backend {
Cranelift,
Singlepass,
LLVM,
Auto,
}
impl Backend {
/// Get a list of the currently enabled (via feature flag) backends.
pub fn variants() -> &'static [&'static str] {
&[
#[cfg(feature = "backend-cranelift")]
"cranelift",
#[cfg(feature = "backend-singlepass")]
"singlepass",
#[cfg(feature = "backend-llvm")]
"llvm",
"auto",
]
}
/// Stable string representation of the backend.
/// It can be used as part of a cache key, for example.
pub fn to_string(&self) -> &'static str {
match self {
Backend::Cranelift => "cranelift",
Backend::Singlepass => "singlepass",
Backend::LLVM => "llvm",
Backend::Auto => "auto",
}
}
}
impl Default for Backend {
fn default() -> Self {
Backend::Cranelift
}
}
impl std::str::FromStr for Backend {
type Err = String;
fn from_str(s: &str) -> Result<Backend, String> {
match s.to_lowercase().as_str() {
"singlepass" => Ok(Backend::Singlepass),
"cranelift" => Ok(Backend::Cranelift),
"llvm" => Ok(Backend::LLVM),
"auto" => Ok(Backend::Auto),
_ => Err(format!("The backend {} doesn't exist", s)),
}
}
}
/// The target architecture for code generation.
#[derive(Copy, Clone, Debug)]
pub enum Architecture {
@ -104,22 +50,6 @@ pub struct InlineBreakpoint {
pub ty: InlineBreakpointType,
}
#[cfg(test)]
mod backend_test {
use super::*;
use std::str::FromStr;
#[test]
fn str_repr_matches() {
// if this test breaks, think hard about why it's breaking
// can we avoid having these be different?
for &backend in &[Backend::Cranelift, Backend::LLVM, Backend::Singlepass] {
assert_eq!(backend, Backend::from_str(backend.to_string()).unwrap());
}
}
}
/// This type cannot be constructed from
/// outside the runtime crate.
pub struct Token {

View File

@ -2,13 +2,9 @@
//! serializing compiled wasm code to a binary format. The binary format can be persisted,
//! and loaded to allow skipping compilation and fast startup.
use crate::{
backend::Backend,
module::{Module, ModuleInfo},
sys::Memory,
};
use crate::{module::ModuleInfo, sys::Memory};
use blake3;
use std::{fmt, io, mem, slice};
use std::{io, mem, slice};
/// Indicates the invalid type of invalid cache file
#[derive(Debug)]
@ -35,7 +31,7 @@ pub enum Error {
/// The cached binary has been invalidated.
InvalidatedCache,
/// The current backend does not support caching.
UnsupportedBackend(Backend),
UnsupportedBackend(String),
}
impl From<io::Error> for Error {
@ -246,24 +242,6 @@ impl Artifact {
}
}
/// A generic cache for storing and loading compiled wasm modules.
///
/// The `wasmer-runtime` supplies a naive `FileSystemCache` api.
pub trait Cache {
/// Error type to return when load error occurs
type LoadError: fmt::Debug;
/// Error type to return when store error occurs
type StoreError: fmt::Debug;
/// loads a module using the default `Backend`
fn load(&self, key: WasmHash) -> Result<Module, Self::LoadError>;
/// loads a cached module using a specific `Backend`
fn load_with_backend(&self, key: WasmHash, backend: Backend)
-> Result<Module, Self::LoadError>;
/// Store a module into the cache with the given key
fn store(&mut self, key: WasmHash, module: Module) -> Result<(), Self::StoreError>;
}
/// A unique ID generated from the version of Wasmer for use with cache versioning
pub const WASMER_VERSION_HASH: &'static str =
include_str!(concat!(env!("OUT_DIR"), "/wasmer_version_hash.txt"));

View File

@ -4,7 +4,7 @@
use crate::fault::FaultInfo;
use crate::{
backend::RunnableModule,
backend::{Backend, CacheGen, Compiler, CompilerConfig, Features, Token},
backend::{CacheGen, Compiler, CompilerConfig, Features, Token},
cache::{Artifact, Error as CacheError},
error::{CompileError, CompileResult},
module::{ModuleInfo, ModuleInner},
@ -92,7 +92,12 @@ pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule,
) -> Self;
/// Returns the backend id associated with this MCG.
fn backend_id() -> Backend;
fn backend_id() -> String;
/// It sets if the current compiler requires validation before compilation
fn requires_pre_validation() -> bool {
true
}
/// Feeds the compiler config.
fn feed_compiler_config(&mut self, _config: &CompilerConfig) -> Result<(), E> {
@ -222,12 +227,12 @@ impl<
compiler_config: CompilerConfig,
_: Token,
) -> CompileResult<ModuleInner> {
if requires_pre_validation(MCG::backend_id()) {
if MCG::requires_pre_validation() {
validate_with_features(wasm, &compiler_config.features)?;
}
let mut mcg = match MCG::backend_id() {
Backend::LLVM => MCG::new_with_target(
let mut mcg = match MCG::backend_id().as_ref() {
"llvm" => MCG::new_with_target(
compiler_config.triple.clone(),
compiler_config.cpu_name.clone(),
compiler_config.cpu_features.clone(),
@ -235,13 +240,7 @@ impl<
_ => MCG::new(),
};
let mut chain = (self.middleware_chain_generator)();
let info = crate::parse::read_module(
wasm,
MCG::backend_id(),
&mut mcg,
&mut chain,
&compiler_config,
)?;
let info = crate::parse::read_module(wasm, &mut mcg, &mut chain, &compiler_config)?;
let (exec_context, cache_gen) =
mcg.finalize(&info.read().unwrap())
.map_err(|x| CompileError::InternalError {
@ -263,15 +262,6 @@ impl<
}
}
fn requires_pre_validation(backend: Backend) -> bool {
match backend {
Backend::Cranelift => true,
Backend::LLVM => true,
Backend::Singlepass => false,
Backend::Auto => false,
}
}
/// A sink for parse events.
pub struct EventSink<'a, 'b> {
buffer: SmallVec<[Event<'a, 'b>; 2]>,

View File

@ -1,7 +1,7 @@
//! The module module contains the implementation data structures and helper functions used to
//! manipulate and access wasm modules.
use crate::{
backend::{Backend, RunnableModule},
backend::RunnableModule,
cache::{Artifact, Error as CacheError},
error,
import::ImportObject,
@ -65,7 +65,7 @@ pub struct ModuleInfo {
/// Map signature index to function signature.
pub signatures: Map<SigIndex, FuncSig>,
/// Backend.
pub backend: Backend,
pub backend: String,
/// Table of namespace indexes.
pub namespace_table: StringTable<NamespaceIndex>,

View File

@ -3,7 +3,7 @@
use crate::codegen::*;
use crate::{
backend::{Backend, CompilerConfig, RunnableModule},
backend::{CompilerConfig, RunnableModule},
error::CompileError,
module::{
DataInitializer, ExportIndex, ImportName, ModuleInfo, StringTable, StringTableBuilder,
@ -57,7 +57,6 @@ pub fn read_module<
E: Debug,
>(
wasm: &[u8],
backend: Backend,
mcg: &mut MCG,
middlewares: &mut MiddlewareChain,
compiler_config: &CompilerConfig,
@ -83,7 +82,7 @@ pub fn read_module<
func_assoc: Map::new(),
signatures: Map::new(),
backend: backend,
backend: MCG::backend_id(),
namespace_table: StringTable::new(),
name_table: StringTable::new(),

View File

@ -2,7 +2,7 @@
//! state could read or updated at runtime. Use cases include generating stack traces, switching
//! generated code from one tier to another, or serializing state of a running instace.
use crate::backend::{Backend, RunnableModule};
use crate::backend::RunnableModule;
use std::collections::BTreeMap;
use std::ops::Bound::{Included, Unbounded};
use std::sync::Arc;
@ -186,7 +186,7 @@ pub struct CodeVersion {
pub base: usize,
/// The backend used to compile this module.
pub backend: Backend,
pub backend: String,
/// `RunnableModule` for this code version.
pub runnable_module: Arc<Box<dyn RunnableModule>>,

View File

@ -1,6 +1,6 @@
//! The tiering module supports switching between code compiled with different optimization levels
//! as runtime.
use crate::backend::{Backend, Compiler, CompilerConfig};
use crate::backend::{Compiler, CompilerConfig};
use crate::compile_with_config;
use crate::fault::{
catch_unsafe_unwind, ensure_sighandler, pop_code_version, push_code_version, with_ctx,
@ -43,7 +43,7 @@ struct OptimizationState {
}
struct OptimizationOutcome {
backend_id: Backend,
backend_id: String,
module: Module,
}
@ -54,7 +54,7 @@ unsafe impl Sync for CtxWrapper {}
unsafe fn do_optimize(
binary: &[u8],
backend_id: Backend,
backend_id: String,
compiler: Box<dyn Compiler>,
ctx: &Mutex<CtxWrapper>,
state: &OptimizationState,
@ -87,8 +87,8 @@ pub unsafe fn run_tiering<F: Fn(InteractiveShellContext) -> ShellExitOperation>(
import_object: &ImportObject,
start_raw: extern "C" fn(&mut Ctx),
baseline: &mut Instance,
baseline_backend: Backend,
optimized_backends: Vec<(Backend, Box<dyn Fn() -> Box<dyn Compiler> + Send>)>,
baseline_backend: String,
optimized_backends: Vec<(String, Box<dyn Fn() -> Box<dyn Compiler> + Send>)>,
interactive_shell: F,
) -> Result<(), String> {
ensure_sighandler();
@ -140,7 +140,7 @@ pub unsafe fn run_tiering<F: Fn(InteractiveShellContext) -> ShellExitOperation>(
}));
loop {
let new_optimized: Option<(Backend, &mut Instance)> = {
let new_optimized: Option<(String, &mut Instance)> = {
let mut outcome = opt_state.outcome.lock().unwrap();
if let Some(x) = outcome.take() {
let instance = x

View File

@ -1064,7 +1064,7 @@ mod vm_ctx_tests {
fn generate_module() -> ModuleInner {
use super::Func;
use crate::backend::{sys::Memory, Backend, CacheGen, RunnableModule};
use crate::backend::{sys::Memory, CacheGen, RunnableModule};
use crate::cache::Error as CacheError;
use crate::typed_func::Wasm;
use crate::types::{LocalFuncIndex, SigIndex};
@ -1118,7 +1118,7 @@ mod vm_ctx_tests {
func_assoc: Map::new(),
signatures: Map::new(),
backend: Backend::Cranelift,
backend: Default::default(),
namespace_table: StringTable::new(),
name_table: StringTable::new(),