Making caching support optional in Wasmtime (#2119)

This commit moves all of the caching support that currently lives in
`wasmtime-environ` into a `wasmtime-cache` crate and makes it optional. The
goal here is to slim down the `wasmtime-environ` crate and clearly separate
boundaries where caching is a standalone and optional feature, not intertwined
with other crates.
This commit is contained in:
Alex Crichton
2020-08-07 15:42:40 -05:00
committed by GitHub
parent a796d65467
commit 08f9eb1725
21 changed files with 104 additions and 54 deletions

40
Cargo.lock generated
View File

@@ -2373,6 +2373,7 @@ dependencies = [
"target-lexicon", "target-lexicon",
"tempfile", "tempfile",
"wasmparser 0.59.0", "wasmparser 0.59.0",
"wasmtime-cache",
"wasmtime-environ", "wasmtime-environ",
"wasmtime-jit", "wasmtime-jit",
"wasmtime-profiling", "wasmtime-profiling",
@@ -2404,6 +2405,30 @@ dependencies = [
"quote", "quote",
] ]
[[package]]
name = "wasmtime-cache"
version = "0.19.0"
dependencies = [
"anyhow",
"base64 0.12.3",
"bincode",
"directories",
"errno",
"file-per-thread-logger",
"filetime",
"lazy_static",
"libc",
"log",
"more-asserts",
"pretty_env_logger",
"serde",
"sha2",
"tempfile",
"toml",
"winapi",
"zstd",
]
[[package]] [[package]]
name = "wasmtime-cli" name = "wasmtime-cli"
version = "0.19.0" version = "0.19.0"
@@ -2425,6 +2450,7 @@ dependencies = [
"test-programs", "test-programs",
"wasi-common", "wasi-common",
"wasmtime", "wasmtime",
"wasmtime-cache",
"wasmtime-debug", "wasmtime-debug",
"wasmtime-environ", "wasmtime-environ",
"wasmtime-fuzzing", "wasmtime-fuzzing",
@@ -2455,33 +2481,19 @@ name = "wasmtime-environ"
version = "0.19.0" version = "0.19.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"base64 0.12.3",
"bincode",
"cfg-if", "cfg-if",
"cranelift-codegen", "cranelift-codegen",
"cranelift-entity", "cranelift-entity",
"cranelift-frontend", "cranelift-frontend",
"cranelift-wasm", "cranelift-wasm",
"directories",
"errno",
"file-per-thread-logger",
"filetime",
"gimli 0.21.0", "gimli 0.21.0",
"indexmap", "indexmap",
"lazy_static",
"libc",
"lightbeam", "lightbeam",
"log", "log",
"more-asserts", "more-asserts",
"pretty_env_logger",
"serde", "serde",
"sha2",
"tempfile",
"thiserror", "thiserror",
"toml",
"wasmparser 0.59.0", "wasmparser 0.59.0",
"winapi",
"zstd",
] ]
[[package]] [[package]]

View File

@@ -22,7 +22,8 @@ doc = false
[dependencies] [dependencies]
# Enable all supported architectures by default. # Enable all supported architectures by default.
wasmtime = { path = "crates/wasmtime", version = "0.19.0", default-features = false } wasmtime = { path = "crates/wasmtime", version = "0.19.0", default-features = false, features = ['cache'] }
wasmtime-cache = { path = "crates/cache", version = "0.19.0" }
wasmtime-debug = { path = "crates/debug", version = "0.19.0" } wasmtime-debug = { path = "crates/debug", version = "0.19.0" }
wasmtime-environ = { path = "crates/environ", version = "0.19.0" } wasmtime-environ = { path = "crates/environ", version = "0.19.0" }
wasmtime-jit = { path = "crates/jit", version = "0.19.0" } wasmtime-jit = { path = "crates/jit", version = "0.19.0" }

View File

@@ -31,7 +31,8 @@ wasi-common = { path = "../wasi-common", optional = true }
wasmtime-wasi = { path = "../wasi", optional = true } wasmtime-wasi = { path = "../wasi", optional = true }
[features] [features]
default = ['jitdump', 'wat', 'wasi'] default = ['jitdump', 'wat', 'wasi', 'cache']
lightbeam = ["wasmtime/lightbeam"] lightbeam = ["wasmtime/lightbeam"]
jitdump = ["wasmtime/jitdump"] jitdump = ["wasmtime/jitdump"]
cache = ["wasmtime/cache"]
wasi = ['wasi-common', 'wasmtime-wasi'] wasi = ['wasi-common', 'wasmtime-wasi']

View File

@@ -1,3 +1,7 @@
// Don't worry about unused imports if we're frobbing features, only worry about
// them with the default set of features enabled.
#![cfg_attr(not(feature = "cache"), allow(unused_imports))]
use crate::{handle_result, wasmtime_error_t}; use crate::{handle_result, wasmtime_error_t};
use std::ffi::CStr; use std::ffi::CStr;
use std::os::raw::c_char; use std::os::raw::c_char;
@@ -130,6 +134,7 @@ pub extern "C" fn wasmtime_config_profiler_set(
} }
#[no_mangle] #[no_mangle]
#[cfg(feature = "cache")]
pub unsafe extern "C" fn wasmtime_config_cache_config_load( pub unsafe extern "C" fn wasmtime_config_cache_config_load(
c: &mut wasm_config_t, c: &mut wasm_config_t,
filename: *const c_char, filename: *const c_char,

35
crates/cache/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,35 @@
[package]
name = "wasmtime-cache"
version = "0.19.0"
authors = ["The Wasmtime Project Developers"]
description = "Support for automatic module caching with Wasmtime"
license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/wasmtime"
documentation = "https://docs.rs/wasmtime-cache/"
edition = "2018"
[dependencies]
anyhow = "1.0"
base64 = "0.12.0"
bincode = "1.1.4"
directories = "2.0.1"
file-per-thread-logger = "0.1.1"
log = { version = "0.4.8", default-features = false }
serde = { version = "1.0.94", features = ["derive"] }
sha2 = "0.8.0"
toml = "0.5.5"
zstd = "0.5"
[target.'cfg(target_os = "windows")'.dependencies]
winapi = "0.3.7"
[target.'cfg(not(target_os = "windows"))'.dependencies]
errno = "0.2.4"
libc = "0.2.60"
[dev-dependencies]
filetime = "0.2.7"
lazy_static = "1.3.0"
more-asserts = "0.2.1"
pretty_env_logger = "0.4.0"
tempfile = "3"

View File

@@ -1,5 +1,5 @@
use super::*; use super::*;
use crate::cache::config::tests::test_prolog; use crate::config::tests::test_prolog;
use more_asserts::{assert_ge, assert_gt, assert_lt}; use more_asserts::{assert_ge, assert_gt, assert_lt};
use std::iter::repeat; use std::iter::repeat;
use std::process; use std::process;

View File

@@ -1,12 +1,11 @@
use tempfile; use wasmtime_cache::create_new_config;
use wasmtime_environ::cache_create_new_config;
#[test] #[test]
fn test_cache_write_default_config() { fn test_cache_write_default_config() {
let dir = tempfile::tempdir().expect("Can't create temporary directory"); let dir = tempfile::tempdir().expect("Can't create temporary directory");
let config_path = dir.path().join("cache-config.toml"); let config_path = dir.path().join("cache-config.toml");
let result = cache_create_new_config(Some(&config_path)); let result = create_new_config(Some(&config_path));
assert!(result.is_ok()); assert!(result.is_ok());
assert!(config_path.exists()); assert!(config_path.exists());
assert_eq!(config_path, result.unwrap()); assert_eq!(config_path, result.unwrap());

View File

@@ -21,31 +21,11 @@ wasmparser = "0.59.0"
lightbeam = { path = "../lightbeam", optional = true, version = "0.19.0" } lightbeam = { path = "../lightbeam", optional = true, version = "0.19.0" }
indexmap = { version = "1.0.2", features = ["serde-1"] } indexmap = { version = "1.0.2", features = ["serde-1"] }
thiserror = "1.0.4" thiserror = "1.0.4"
directories = "2.0.1"
sha2 = "0.8.0"
base64 = "0.12.0"
serde = { version = "1.0.94", features = ["derive"] } serde = { version = "1.0.94", features = ["derive"] }
bincode = "1.1.4"
log = { version = "0.4.8", default-features = false } log = { version = "0.4.8", default-features = false }
zstd = "0.5"
toml = "0.5.5"
file-per-thread-logger = "0.1.1"
more-asserts = "0.2.1" more-asserts = "0.2.1"
cfg-if = "0.1.9" cfg-if = "0.1.9"
gimli = "0.21" gimli = "0.21"
[target.'cfg(target_os = "windows")'.dependencies]
winapi = "0.3.7"
[target.'cfg(not(target_os = "windows"))'.dependencies]
libc = "0.2.60"
errno = "0.2.4"
[dev-dependencies]
tempfile = "3"
pretty_env_logger = "0.4.0"
filetime = "0.2.7"
lazy_static = "1.3.0"
[badges] [badges]
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }

View File

@@ -33,15 +33,11 @@ mod module_environ;
mod tunables; mod tunables;
mod vmoffsets; mod vmoffsets;
mod cache;
pub mod cranelift; pub mod cranelift;
#[cfg(feature = "lightbeam")] #[cfg(feature = "lightbeam")]
pub mod lightbeam; pub mod lightbeam;
pub use crate::address_map::*; pub use crate::address_map::*;
pub use crate::cache::create_new_config as cache_create_new_config;
pub use crate::cache::{CacheConfig, ModuleCacheEntry};
pub use crate::compilation::*; pub use crate::compilation::*;
pub use crate::cranelift::Cranelift; pub use crate::cranelift::Cranelift;
pub use crate::data_structures::*; pub use crate::data_structures::*;

View File

@@ -13,6 +13,7 @@ edition = "2018"
wasmtime-runtime = { path = "../runtime", version = "0.19.0" } wasmtime-runtime = { path = "../runtime", version = "0.19.0" }
wasmtime-environ = { path = "../environ", version = "0.19.0" } wasmtime-environ = { path = "../environ", version = "0.19.0" }
wasmtime-jit = { path = "../jit", version = "0.19.0" } wasmtime-jit = { path = "../jit", version = "0.19.0" }
wasmtime-cache = { path = "../cache", version = "0.19.0", optional = true }
wasmtime-profiling = { path = "../profiling", version = "0.19.0" } wasmtime-profiling = { path = "../profiling", version = "0.19.0" }
wasmparser = "0.59.0" wasmparser = "0.59.0"
target-lexicon = { version = "0.10.0", default-features = false } target-lexicon = { version = "0.10.0", default-features = false }
@@ -40,7 +41,7 @@ wasmtime-wasi = { path = "../wasi" }
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }
[features] [features]
default = ['wat', 'jitdump', 'parallel-compilation'] default = ['cache', 'wat', 'jitdump', 'parallel-compilation']
# Enables experimental support for the lightbeam codegen backend, an alternative # Enables experimental support for the lightbeam codegen backend, an alternative
# to cranelift. Requires Nightly Rust currently, and this is not enabled by # to cranelift. Requires Nightly Rust currently, and this is not enabled by
@@ -55,3 +56,6 @@ vtune = ["wasmtime-jit/vtune"]
# Enables parallel compilation of WebAssembly code # Enables parallel compilation of WebAssembly code
parallel-compilation = ["wasmtime-jit/parallel-compilation"] parallel-compilation = ["wasmtime-jit/parallel-compilation"]
# Enables support for automatic cache configuration to be enabled in `Config`.
cache = ["wasmtime-cache"]

View File

@@ -4,7 +4,8 @@ use crate::types::{EntityType, ExportType, ExternType, ImportType};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use std::path::Path; use std::path::Path;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use wasmtime_environ::ModuleCacheEntry; #[cfg(feature = "cache")]
use wasmtime_cache::ModuleCacheEntry;
use wasmtime_jit::{CompilationArtifacts, CompiledModule}; use wasmtime_jit::{CompilationArtifacts, CompiledModule};
/// A compiled WebAssembly module, ready to be instantiated. /// A compiled WebAssembly module, ready to be instantiated.
@@ -301,11 +302,13 @@ impl Module {
} }
unsafe fn compile(engine: &Engine, binary: &[u8]) -> Result<Self> { unsafe fn compile(engine: &Engine, binary: &[u8]) -> Result<Self> {
let cache_entry = ModuleCacheEntry::new("wasmtime", engine.cache_config()); #[cfg(feature = "cache")]
let artifacts = cache_entry let artifacts = ModuleCacheEntry::new("wasmtime", engine.cache_config())
.get_data((engine.compiler(), binary), |(compiler, binary)| { .get_data((engine.compiler(), binary), |(compiler, binary)| {
CompilationArtifacts::build(compiler, binary) CompilationArtifacts::build(compiler, binary)
})?; })?;
#[cfg(not(feature = "cache"))]
let artifacts = CompilationArtifacts::build(engine.compiler(), binary)?;
let compiled = CompiledModule::from_artifacts( let compiled = CompiledModule::from_artifacts(
artifacts, artifacts,

View File

@@ -7,13 +7,16 @@ use std::cmp;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
#[cfg(feature = "cache")]
use std::path::Path; use std::path::Path;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::sync::Arc; use std::sync::Arc;
use target_lexicon::Triple; use target_lexicon::Triple;
use wasmparser::Validator; use wasmparser::Validator;
#[cfg(feature = "cache")]
use wasmtime_cache::CacheConfig;
use wasmtime_environ::settings::{self, Configurable, SetError}; use wasmtime_environ::settings::{self, Configurable, SetError};
use wasmtime_environ::{ir, isa, isa::TargetIsa, wasm, CacheConfig, Tunables}; use wasmtime_environ::{ir, isa, isa::TargetIsa, wasm, Tunables};
use wasmtime_jit::{native, CompilationStrategy, Compiler}; use wasmtime_jit::{native, CompilationStrategy, Compiler};
use wasmtime_profiling::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent}; use wasmtime_profiling::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
use wasmtime_runtime::{ use wasmtime_runtime::{
@@ -37,6 +40,7 @@ pub struct Config {
pub(crate) isa_flags: isa::Builder, pub(crate) isa_flags: isa::Builder,
pub(crate) tunables: Tunables, pub(crate) tunables: Tunables,
pub(crate) strategy: CompilationStrategy, pub(crate) strategy: CompilationStrategy,
#[cfg(feature = "cache")]
pub(crate) cache_config: CacheConfig, pub(crate) cache_config: CacheConfig,
pub(crate) profiler: Arc<dyn ProfilingAgent>, pub(crate) profiler: Arc<dyn ProfilingAgent>,
pub(crate) memory_creator: Option<MemoryCreatorProxy>, pub(crate) memory_creator: Option<MemoryCreatorProxy>,
@@ -89,6 +93,7 @@ impl Config {
flags, flags,
isa_flags: native::builder(), isa_flags: native::builder(),
strategy: CompilationStrategy::Auto, strategy: CompilationStrategy::Auto,
#[cfg(feature = "cache")]
cache_config: CacheConfig::new_cache_disabled(), cache_config: CacheConfig::new_cache_disabled(),
profiler: Arc::new(NullProfilerAgent), profiler: Arc::new(NullProfilerAgent),
memory_creator: None, memory_creator: None,
@@ -395,14 +400,18 @@ impl Config {
/// ///
/// By default cache configuration is not enabled or loaded. /// By default cache configuration is not enabled or loaded.
/// ///
/// This method is only available when the `cache` feature of this crate is
/// enabled.
///
/// # Errors /// # Errors
/// ///
/// This method can fail due to any error that happens when loading the file /// This method can fail due to any error that happens when loading the file
/// pointed to by `path` and attempting to load the cache configuration. /// pointed to by `path` and attempting to load the cache configuration.
/// ///
/// [docs]: https://bytecodealliance.github.io/wasmtime/cli-cache.html /// [docs]: https://bytecodealliance.github.io/wasmtime/cli-cache.html
#[cfg(feature = "cache")]
pub fn cache_config_load(&mut self, path: impl AsRef<Path>) -> Result<&mut Self> { pub fn cache_config_load(&mut self, path: impl AsRef<Path>) -> Result<&mut Self> {
self.cache_config = wasmtime_environ::CacheConfig::from_file(Some(path.as_ref()))?; self.cache_config = CacheConfig::from_file(Some(path.as_ref()))?;
Ok(self) Ok(self)
} }
@@ -416,6 +425,9 @@ impl Config {
/// ///
/// By default cache configuration is not enabled or loaded. /// By default cache configuration is not enabled or loaded.
/// ///
/// This method is only available when the `cache` feature of this crate is
/// enabled.
///
/// # Errors /// # Errors
/// ///
/// This method can fail due to any error that happens when loading the /// This method can fail due to any error that happens when loading the
@@ -424,8 +436,9 @@ impl Config {
/// for an enabled cache are applied. /// for an enabled cache are applied.
/// ///
/// [docs]: https://bytecodealliance.github.io/wasmtime/cli-cache.html /// [docs]: https://bytecodealliance.github.io/wasmtime/cli-cache.html
#[cfg(feature = "cache")]
pub fn cache_config_load_default(&mut self) -> Result<&mut Self> { pub fn cache_config_load_default(&mut self) -> Result<&mut Self> {
self.cache_config = wasmtime_environ::CacheConfig::from_file(None)?; self.cache_config = CacheConfig::from_file(None)?;
Ok(self) Ok(self)
} }
@@ -793,6 +806,7 @@ impl Engine {
&self.inner.compiler &self.inner.compiler
} }
#[cfg(feature = "cache")]
pub(crate) fn cache_config(&self) -> &CacheConfig { pub(crate) fn cache_config(&self) -> &CacheConfig {
&self.config().cache_config &self.config().cache_config
} }

View File

@@ -58,6 +58,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[
"wasmtime-profiling", "wasmtime-profiling",
"wasmtime-obj", "wasmtime-obj",
"wasmtime-jit", "wasmtime-jit",
"wasmtime-cache",
"wasmtime", "wasmtime",
"wasmtime-wiggle", "wasmtime-wiggle",
"wasmtime-wasi", "wasmtime-wasi",

View File

@@ -1,8 +1,7 @@
//! The module that implements the `wasmtime config` command. //! The module that implements the `wasmtime config` command.
use anyhow::{anyhow, Result}; use anyhow::Result;
use structopt::StructOpt; use structopt::StructOpt;
use wasmtime_environ::cache_create_new_config;
const CONFIG_NEW_AFTER_HELP: &str = const CONFIG_NEW_AFTER_HELP: &str =
"If no file path is specified, the system configuration file path will be used."; "If no file path is specified, the system configuration file path will be used.";
@@ -37,7 +36,7 @@ pub struct ConfigNewCommand {
impl ConfigNewCommand { impl ConfigNewCommand {
/// Executes the command. /// Executes the command.
pub fn execute(&self) -> Result<()> { pub fn execute(&self) -> Result<()> {
let path = cache_create_new_config(self.path.as_ref()).map_err(|e| anyhow!(e))?; let path = wasmtime_cache::create_new_config(self.path.as_ref())?;
println!( println!(
"Successfully created a new configuation file at '{}'.", "Successfully created a new configuation file at '{}'.",