Skip to content

Commit

Permalink
Enable copy-on-write memories for components (#7459)
Browse files Browse the repository at this point in the history
* Enable copy-on-write memories for components

This commit fixes a mistake in component compilation where copy-on-write
and lazy initialization of function tables was accidentally not
performed. I believe this is an accidental regression from a previous
refactor, and this commit now ensures that the shared infrastructure
between components and core modules accounts for copy-on-write and lazy
table initialization.

* Add some tests
  • Loading branch information
alexcrichton authored Nov 3, 2023
1 parent 97f6a8b commit 40adf87
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 24 deletions.
24 changes: 20 additions & 4 deletions crates/wasmtime/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use std::collections::{btree_map, BTreeMap, BTreeSet};
use std::{any::Any, collections::HashMap};
use wasmtime_environ::{
Compiler, DefinedFuncIndex, FuncIndex, FunctionBodyData, ModuleTranslation, ModuleType,
ModuleTypes, PrimaryMap, SignatureIndex, StaticModuleIndex, Tunables, WasmFunctionInfo,
ModuleTypes, PrimaryMap, SignatureIndex, StaticModuleIndex, WasmFunctionInfo,
};
use wasmtime_jit::{CompiledFunctionInfo, CompiledModuleInfo};

Expand Down Expand Up @@ -447,8 +447,7 @@ impl FunctionIndices {
pub fn link_and_append_code<'a>(
mut self,
mut obj: object::write::Object<'static>,
tunables: &'a Tunables,
compiler: &dyn Compiler,
engine: &'a Engine,
compiled_funcs: Vec<(String, Box<dyn Any + Send>)>,
translations: PrimaryMap<StaticModuleIndex, ModuleTranslation<'_>>,
) -> Result<(wasmtime_jit::ObjectBuilder<'a>, Artifacts)> {
Expand All @@ -457,6 +456,8 @@ impl FunctionIndices {
// The result is a vector parallel to `compiled_funcs` where
// `symbol_ids_and_locs[i]` is the symbol ID and function location of
// `compiled_funcs[i]`.
let compiler = engine.compiler();
let tunables = &engine.config().tunables;
let symbol_ids_and_locs = compiler.append_code(
&mut obj,
&compiled_funcs,
Expand Down Expand Up @@ -559,7 +560,22 @@ impl FunctionIndices {

artifacts.modules = translations
.into_iter()
.map(|(module, translation)| {
.map(|(module, mut translation)| {
// If configured attempt to use static memory initialization which
// can either at runtime be implemented as a single memcpy to
// initialize memory or otherwise enabling virtual-memory-tricks
// such as mmap'ing from a file to get copy-on-write.
if engine.config().memory_init_cow {
let align = compiler.page_size_align();
let max_always_allowed = engine.config().memory_guaranteed_dense_image_size;
translation.try_static_init(align, max_always_allowed);
}

// Attempt to convert table initializer segments to
// FuncTable representation where possible, to enable
// table lazy init.
translation.try_func_table_init();

let funcs: PrimaryMap<DefinedFuncIndex, CompiledFunctionInfo> =
wasm_functions_for_module(&mut wasm_functions, module)
.map(|(key, wasm_func_index)| {
Expand Down
34 changes: 32 additions & 2 deletions crates/wasmtime/src/component/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ impl Component {

let (mut object, compilation_artifacts) = function_indices.link_and_append_code(
object,
&engine.config().tunables,
compiler,
engine,
compiled_funcs,
module_translations,
)?;
Expand Down Expand Up @@ -473,3 +472,34 @@ impl ComponentRuntimeInfo for ComponentInner {
}
}
}

#[cfg(test)]
mod tests {
use crate::component::Component;
use crate::{Config, Engine};
use wasmtime_environ::MemoryInitialization;

#[test]
fn cow_on_by_default() {
let mut config = Config::new();
config.wasm_component_model(true);
let engine = Engine::new(&config).unwrap();
let component = Component::new(
&engine,
r#"
(component
(core module
(memory 1)
(data (i32.const 100) "abcd")
)
)
"#,
)
.unwrap();

for (_, module) in component.inner.static_modules.iter() {
let init = &module.env_module().memory_initialization;
assert!(matches!(init, MemoryInitialization::Static { .. }));
}
}
}
43 changes: 25 additions & 18 deletions crates/wasmtime/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,6 @@ impl Module {
use crate::compiler::CompileInputs;

let tunables = &engine.config().tunables;
let compiler = engine.compiler();

// First a `ModuleEnvironment` is created which records type information
// about the wasm module. This is where the WebAssembly is parsed and
Expand Down Expand Up @@ -437,25 +436,9 @@ impl Module {
engine.append_compiler_info(&mut object);
engine.append_bti(&mut object);

// If configured attempt to use static memory initialization which
// can either at runtime be implemented as a single memcpy to
// initialize memory or otherwise enabling virtual-memory-tricks
// such as mmap'ing from a file to get copy-on-write.
if engine.config().memory_init_cow {
let align = engine.compiler().page_size_align();
let max_always_allowed = engine.config().memory_guaranteed_dense_image_size;
translation.try_static_init(align, max_always_allowed);
}

// Attempt to convert table initializer segments to
// FuncTable representation where possible, to enable
// table lazy init.
translation.try_func_table_init();

let (mut object, compilation_artifacts) = function_indices.link_and_append_code(
object,
tunables,
compiler,
engine,
compiled_funcs,
std::iter::once(translation).collect(),
)?;
Expand Down Expand Up @@ -1361,3 +1344,27 @@ fn memory_images(engine: &Engine, module: &CompiledModule) -> Result<Option<Modu
};
ModuleMemoryImages::new(module.module(), module.code_memory().wasm_data(), mmap)
}

#[cfg(test)]
mod tests {
use crate::{Engine, Module};
use wasmtime_environ::MemoryInitialization;

#[test]
fn cow_on_by_default() {
let engine = Engine::default();
let module = Module::new(
&engine,
r#"
(module
(memory 1)
(data (i32.const 100) "abcd")
)
"#,
)
.unwrap();

let init = &module.env_module().memory_initialization;
assert!(matches!(init, MemoryInitialization::Static { .. }));
}
}

0 comments on commit 40adf87

Please sign in to comment.