Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 { .. }));
}
}