Browse Source

Add `paged_memory_initialization` to Config.

This commit adds a `paged_memory_initialization` setting to `Config`.

The setting controls whether or not an attempt is made to organize data
segments into Wasm pages during compilation.

When used in conjunction with the `uffd` feature on Linux, Wasmtime can
completely skip initializing linear memories and instead initialize any pages
that are accessed for the first time during Wasm execution.
pull/3245/head
Peter Huene 3 years ago
parent
commit
e2b9b54301
No known key found for this signature in database GPG Key ID: 1DD33E128C1F90D2
  1. 25
      crates/wasmtime/src/config.rs
  2. 2
      crates/wasmtime/src/module.rs
  3. 23
      tests/all/instance.rs

25
crates/wasmtime/src/config.rs

@ -352,6 +352,7 @@ pub struct Config {
pub(crate) async_support: bool,
pub(crate) deserialize_check_wasmtime_version: bool,
pub(crate) parallel_compilation: bool,
pub(crate) paged_memory_initialization: bool,
}
impl Config {
@ -375,6 +376,8 @@ impl Config {
async_support: false,
deserialize_check_wasmtime_version: true,
parallel_compilation: true,
// Default to paged memory initialization when using uffd on linux
paged_memory_initialization: cfg!(all(target_os = "linux", feature = "uffd")),
};
#[cfg(compiler)]
{
@ -984,6 +987,27 @@ impl Config {
self
}
/// Sets whether or not an attempt is made to initialize linear memories by page.
///
/// This setting is `false` by default and Wasmtime initializes linear memories
/// by copying individual data segments from the compiled module.
///
/// Setting this to `true` will cause compilation to attempt to organize the
/// data segments into WebAssembly pages and linear memories are initialized by
/// copying each page rather than individual data segments.
///
/// Modules that import a memory or have data segments that use a global base
/// will continue to be initialized by copying each data segment individually.
///
/// When combined with the `uffd` feature on Linux, this will allow Wasmtime
/// to delay initialization of a linear memory page until it is accessed
/// for the first time during WebAssembly execution; this may improve
/// instantiation performance as a result.
pub fn paged_memory_initialization(&mut self, value: bool) -> &mut Self {
self.paged_memory_initialization = value;
self
}
/// Configures the maximum size, in bytes, where a linear memory is
/// considered static, above which it'll be considered dynamic.
///
@ -1329,6 +1353,7 @@ impl Clone for Config {
async_stack_size: self.async_stack_size,
deserialize_check_wasmtime_version: self.deserialize_check_wasmtime_version,
parallel_compilation: self.parallel_compilation,
paged_memory_initialization: self.paged_memory_initialization,
}
}
}

2
crates/wasmtime/src/module.rs

@ -380,7 +380,7 @@ impl Module {
// If configured, attempt to use paged memory initialization
// instead of the default mode of memory initialization
if cfg!(all(feature = "uffd", target_os = "linux")) {
if engine.config().paged_memory_initialization {
translation.try_paged_init();
}

23
tests/all/instance.rs

@ -32,6 +32,29 @@ fn initializes_linear_memory() -> Result<()> {
Ok(())
}
#[test]
fn initializes_linear_memory_paged() -> Result<()> {
let wat = r#"
(module
(memory (export "memory") 2)
(data (i32.const 0) "Hello World!")
)"#;
let mut config = Config::new();
config.paged_memory_initialization(true);
let module = Module::new(&Engine::new(&config)?, wat)?;
let mut store = Store::new(module.engine(), ());
let instance = Instance::new(&mut store, &module, &[])?;
let memory = instance.get_memory(&mut store, "memory").unwrap();
let mut bytes = [0; 12];
memory.read(&store, 0, &mut bytes)?;
assert_eq!(bytes, "Hello World!".as_bytes());
Ok(())
}
#[test]
fn linear_memory_limits() -> Result<()> {
// this test will allocate 4GB of virtual memory space, and may not work in

Loading…
Cancel
Save