diff --git a/crates/wasmtime/src/compiler.rs b/crates/wasmtime/src/compiler.rs index 33856f4b2198..5022ef9dac0c 100644 --- a/crates/wasmtime/src/compiler.rs +++ b/crates/wasmtime/src/compiler.rs @@ -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}; @@ -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)>, translations: PrimaryMap>, ) -> Result<(wasmtime_jit::ObjectBuilder<'a>, Artifacts)> { @@ -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, @@ -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 = wasm_functions_for_module(&mut wasm_functions, module) .map(|(key, wasm_func_index)| { diff --git a/crates/wasmtime/src/component/component.rs b/crates/wasmtime/src/component/component.rs index 013f93bd79e0..a57165ed441d 100644 --- a/crates/wasmtime/src/component/component.rs +++ b/crates/wasmtime/src/component/component.rs @@ -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, )?; @@ -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 { .. })); + } + } +} diff --git a/crates/wasmtime/src/module.rs b/crates/wasmtime/src/module.rs index 38a51fcd7ea0..a5553ff94f9c 100644 --- a/crates/wasmtime/src/module.rs +++ b/crates/wasmtime/src/module.rs @@ -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 @@ -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(), )?; @@ -1361,3 +1344,27 @@ fn memory_images(engine: &Engine, module: &CompiledModule) -> Result