Merge pull request #3245 from peterhuene/add-paged-init-setting
Add `paged_memory_initialization` to Config.
This commit is contained in:
@@ -352,6 +352,7 @@ pub struct Config {
|
|||||||
pub(crate) async_support: bool,
|
pub(crate) async_support: bool,
|
||||||
pub(crate) deserialize_check_wasmtime_version: bool,
|
pub(crate) deserialize_check_wasmtime_version: bool,
|
||||||
pub(crate) parallel_compilation: bool,
|
pub(crate) parallel_compilation: bool,
|
||||||
|
pub(crate) paged_memory_initialization: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@@ -375,6 +376,8 @@ impl Config {
|
|||||||
async_support: false,
|
async_support: false,
|
||||||
deserialize_check_wasmtime_version: true,
|
deserialize_check_wasmtime_version: true,
|
||||||
parallel_compilation: 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)]
|
#[cfg(compiler)]
|
||||||
{
|
{
|
||||||
@@ -984,6 +987,27 @@ impl Config {
|
|||||||
self
|
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
|
/// Configures the maximum size, in bytes, where a linear memory is
|
||||||
/// considered static, above which it'll be considered dynamic.
|
/// considered static, above which it'll be considered dynamic.
|
||||||
///
|
///
|
||||||
@@ -1329,6 +1353,7 @@ impl Clone for Config {
|
|||||||
async_stack_size: self.async_stack_size,
|
async_stack_size: self.async_stack_size,
|
||||||
deserialize_check_wasmtime_version: self.deserialize_check_wasmtime_version,
|
deserialize_check_wasmtime_version: self.deserialize_check_wasmtime_version,
|
||||||
parallel_compilation: self.parallel_compilation,
|
parallel_compilation: self.parallel_compilation,
|
||||||
|
paged_memory_initialization: self.paged_memory_initialization,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ impl Module {
|
|||||||
|
|
||||||
// If configured, attempt to use paged memory initialization
|
// If configured, attempt to use paged memory initialization
|
||||||
// instead of the default mode of 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();
|
translation.try_paged_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,29 @@ fn initializes_linear_memory() -> Result<()> {
|
|||||||
Ok(())
|
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]
|
#[test]
|
||||||
fn linear_memory_limits() -> Result<()> {
|
fn linear_memory_limits() -> Result<()> {
|
||||||
// this test will allocate 4GB of virtual memory space, and may not work in
|
// this test will allocate 4GB of virtual memory space, and may not work in
|
||||||
|
|||||||
Reference in New Issue
Block a user