Move wasm data sections out of wasmtime_environ::Module (#3231)

* Reduce indentation in `to_paged`

Use a few early-returns from `match` to avoid lots of extra indentation.

* Move wasm data sections out of `wasmtime_environ::Module`

This is the first step down the road of #3230. The long-term goal is
that `Module` is always `bincode`-decoded, but wasm data segments are a
possibly very-large portion of this residing in modules which we don't
want to shove through bincode. This refactors the internals of wasmtime
to be ok with this data living separately from the `Module` itself,
providing access at necessary locations.

Wasm data segments are now extracted from a wasm module and
concatenated directly. Data sections then describe ranges within this
concatenated list of data, and passive data works the same way. This
implementation does not lend itself to eventually optimizing the case
where passive data is dropped and no longer needed. That's left for a
future PR.
This commit is contained in:
Alex Crichton
2021-08-24 14:04:03 -05:00
committed by GitHub
parent b05cd2e023
commit a662f5361d
12 changed files with 274 additions and 208 deletions

View File

@@ -61,6 +61,16 @@ pub struct InstanceAllocationRequest<'a> {
/// We use a number of `PhantomPinned` declarations to indicate this to the
/// compiler. More info on this in `wasmtime/src/store.rs`
pub store: Option<*mut dyn Store>,
/// A list of all wasm data that can be referenced by the module that
/// will be allocated. The `Module` given here has active/passive data
/// segments that are specified as relative indices into this list of bytes.
///
/// Note that this is an unsafe pointer. The pointer is expected to live for
/// the entire duration of the instance at this time. It's the
/// responsibility of the callee when allocating to ensure that this data
/// outlives the instance.
pub wasm_data: *const [u8],
}
/// An link error while instantiating a module.
@@ -337,10 +347,10 @@ fn initialize_memories(
instance
.memory_init_segment(
init.memory_index,
&init.data,
init.data.clone(),
get_memory_init_start(init, instance)?,
0,
u32::try_from(init.data.len()).unwrap(),
init.data.end - init.data.start,
)
.map_err(InstantiationError::Trap)?;
}
@@ -391,13 +401,11 @@ fn initialize_instance(
let slice =
unsafe { slice::from_raw_parts_mut(memory.base, memory.current_length) };
for (page_index, page) in pages.iter().enumerate() {
if let Some(data) = page {
debug_assert_eq!(data.len(), WASM_PAGE_SIZE as usize);
let start = page_index * WASM_PAGE_SIZE as usize;
let end = start + WASM_PAGE_SIZE as usize;
slice[start..end].copy_from_slice(data);
}
for (page_index, page) in pages {
debug_assert_eq!(page.end - page.start, WASM_PAGE_SIZE);
let start = (*page_index * u64::from(WASM_PAGE_SIZE)) as usize;
let end = start + WASM_PAGE_SIZE as usize;
slice[start..end].copy_from_slice(instance.wasm_data(page.clone()));
}
}
@@ -652,8 +660,9 @@ unsafe impl InstanceAllocator for OnDemandInstanceAllocator {
memories,
tables,
dropped_elements: EntitySet::with_capacity(req.module.passive_elements.len()),
dropped_data: EntitySet::with_capacity(req.module.passive_data.len()),
dropped_data: EntitySet::with_capacity(req.module.passive_data_map.len()),
host_state,
wasm_data: &*req.wasm_data,
vmctx: VMContext {
_marker: marker::PhantomPinned,
},