Merge pull request #3760 from cfallin/memfd-lazy-create

Make memfd image creation lazy (on first instantiation).
This commit is contained in:
Chris Fallin
2022-02-03 13:20:24 -08:00
committed by GitHub
4 changed files with 25 additions and 14 deletions

5
Cargo.lock generated
View File

@@ -1890,9 +1890,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.8.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]] [[package]]
name = "oorandom" name = "oorandom"
@@ -3377,6 +3377,7 @@ dependencies = [
"libc", "libc",
"log", "log",
"object", "object",
"once_cell",
"paste", "paste",
"psm", "psm",
"rayon", "rayon",

View File

@@ -37,6 +37,7 @@ lazy_static = "1.4"
rayon = { version = "1.0", optional = true } rayon = { version = "1.0", optional = true }
object = { version = "0.27", default-features = false, features = ['read_core', 'elf'] } object = { version = "0.27", default-features = false, features = ['read_core', 'elf'] }
async-trait = { version = "0.1.51", optional = true } async-trait = { version = "0.1.51", optional = true }
once_cell = "1.9"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
winapi = "0.3.7" winapi = "0.3.7"

View File

@@ -690,6 +690,9 @@ impl<'a> Instantiator<'a> {
// properly referenced while in use by the store. // properly referenced while in use by the store.
store.modules_mut().register(&self.cur.module); store.modules_mut().register(&self.cur.module);
// Initialize any memfd images now.
let memfds = self.cur.module.memfds()?;
unsafe { unsafe {
// The first thing we do is issue an instance allocation request // The first thing we do is issue an instance allocation request
// to the instance allocator. This, on success, will give us an // to the instance allocator. This, on success, will give us an
@@ -708,7 +711,7 @@ impl<'a> Instantiator<'a> {
.allocate(InstanceAllocationRequest { .allocate(InstanceAllocationRequest {
module: compiled_module.module(), module: compiled_module.module(),
unique_id: Some(compiled_module.unique_id()), unique_id: Some(compiled_module.unique_id()),
memfds: self.cur.module.memfds(), memfds,
image_base: compiled_module.code().as_ptr() as usize, image_base: compiled_module.code().as_ptr() as usize,
functions: compiled_module.functions(), functions: compiled_module.functions(),
imports: self.cur.build(), imports: self.cur.build(),

View File

@@ -4,6 +4,7 @@ use crate::{
}; };
use crate::{Engine, ModuleType}; use crate::{Engine, ModuleType};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use once_cell::sync::OnceCell;
use std::fs; use std::fs;
use std::mem; use std::mem;
use std::path::Path; use std::path::Path;
@@ -108,8 +109,11 @@ struct ModuleInner {
types: Arc<TypeTables>, types: Arc<TypeTables>,
/// Registered shared signature for the module. /// Registered shared signature for the module.
signatures: Arc<SignatureCollection>, signatures: Arc<SignatureCollection>,
/// a set of memfd images for memories, if any. /// A set of memfd images for memories, if any. Note that module
memfds: Option<Arc<ModuleMemFds>>, /// instantiation (hence the need for lazy init) may happen for the
/// same module concurrently in multiple Stores, so we use a
/// OnceCell.
memfds: OnceCell<Option<Arc<ModuleMemFds>>>,
} }
impl Module { impl Module {
@@ -531,8 +535,6 @@ impl Module {
}) })
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
let memfds = ModuleMemFds::new(module.module(), module.wasm_data())?;
return Ok(Self { return Ok(Self {
inner: Arc::new(ModuleInner { inner: Arc::new(ModuleInner {
engine: engine.clone(), engine: engine.clone(),
@@ -541,7 +543,7 @@ impl Module {
artifact_upvars: modules, artifact_upvars: modules,
module_upvars, module_upvars,
signatures, signatures,
memfds, memfds: OnceCell::new(),
}), }),
}); });
@@ -555,13 +557,12 @@ impl Module {
signatures: &Arc<SignatureCollection>, signatures: &Arc<SignatureCollection>,
) -> Result<Module> { ) -> Result<Module> {
let module = artifacts[module_index].clone(); let module = artifacts[module_index].clone();
let memfds = ModuleMemFds::new(module.module(), module.wasm_data())?;
Ok(Module { Ok(Module {
inner: Arc::new(ModuleInner { inner: Arc::new(ModuleInner {
engine: engine.clone(), engine: engine.clone(),
types: types.clone(), types: types.clone(),
module, module,
memfds, memfds: OnceCell::new(),
artifact_upvars: artifact_upvars artifact_upvars: artifact_upvars
.iter() .iter()
.map(|i| artifacts[*i].clone()) .map(|i| artifacts[*i].clone())
@@ -682,13 +683,12 @@ impl Module {
modules: &PrimaryMap<ModuleIndex, Module>, modules: &PrimaryMap<ModuleIndex, Module>,
) -> Result<Module> { ) -> Result<Module> {
let module = self.inner.artifact_upvars[artifact_index].clone(); let module = self.inner.artifact_upvars[artifact_index].clone();
let memfds = ModuleMemFds::new(module.module(), module.wasm_data())?;
Ok(Module { Ok(Module {
inner: Arc::new(ModuleInner { inner: Arc::new(ModuleInner {
types: self.inner.types.clone(), types: self.inner.types.clone(),
engine: self.inner.engine.clone(), engine: self.inner.engine.clone(),
module, module,
memfds, memfds: OnceCell::new(),
artifact_upvars: artifact_upvars artifact_upvars: artifact_upvars
.iter() .iter()
.map(|i| self.inner.artifact_upvars[*i].clone()) .map(|i| self.inner.artifact_upvars[*i].clone())
@@ -723,8 +723,14 @@ impl Module {
&self.inner.signatures &self.inner.signatures
} }
pub(crate) fn memfds(&self) -> Option<&Arc<ModuleMemFds>> { pub(crate) fn memfds(&self) -> Result<Option<&Arc<ModuleMemFds>>> {
self.inner.memfds.as_ref() Ok(self
.inner
.memfds
.get_or_try_init(|| {
ModuleMemFds::new(self.inner.module.module(), self.inner.module.wasm_data())
})?
.as_ref())
} }
/// Looks up the module upvar value at the `index` specified. /// Looks up the module upvar value at the `index` specified.