Tidy up some internals of instance allocation (#5346)
* Simplify the `ModuleRuntimeInfo` trait slightly Fold two functions into one as they're only called from one location anyway. * Remove ModuleRuntimeInfo::signature This is redundant as the array mapping is already stored within the `VMContext` so that can be consulted rather than having a separate trait function for it. This required altering the `Global` creation slightly to work correctly in this situation. * Remove a now-dead constant * Shared `VMOffsets` across instances This commit removes the computation of `VMOffsets` to being per-module instead of per-instance. The `VMOffsets` structure is also quite large so this shaves off 112 bytes per instance which isn't a huge impact but should help lower the cost of instantiating small modules. * Remove `InstanceAllocator::adjust_tunables` This is no longer needed or necessary with the pooling allocator. * Fix compile warning * Fix a vtune warning * Fix pooling tests * Fix another test warning
This commit is contained in:
@@ -92,18 +92,11 @@ impl StorePtr {
|
||||
/// This trait is unsafe as it requires knowledge of Wasmtime's runtime internals to implement correctly.
|
||||
pub unsafe trait InstanceAllocator: Send + Sync {
|
||||
/// Validates that a module is supported by the allocator.
|
||||
fn validate(&self, module: &Module) -> Result<()> {
|
||||
drop(module);
|
||||
fn validate(&self, module: &Module, offsets: &VMOffsets<HostPtr>) -> Result<()> {
|
||||
drop((module, offsets));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Adjusts the tunables prior to creation of any JIT compiler.
|
||||
///
|
||||
/// This method allows the instance allocator control over tunables passed to a `wasmtime_jit::Compiler`.
|
||||
fn adjust_tunables(&self, tunables: &mut wasmtime_environ::Tunables) {
|
||||
drop(tunables);
|
||||
}
|
||||
|
||||
/// Allocates an instance for the given allocation request.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -464,11 +457,9 @@ pub unsafe fn allocate_single_memory_instance(
|
||||
let mut memories = PrimaryMap::default();
|
||||
memories.push(memory);
|
||||
let tables = PrimaryMap::default();
|
||||
let module = req.runtime_info.module();
|
||||
let offsets = VMOffsets::new(HostPtr, module);
|
||||
let layout = Instance::alloc_layout(&offsets);
|
||||
let layout = Instance::alloc_layout(req.runtime_info.offsets());
|
||||
let instance = alloc::alloc(layout) as *mut Instance;
|
||||
Instance::new_at(instance, layout.size(), offsets, req, memories, tables);
|
||||
Instance::new_at(instance, layout.size(), req, memories, tables);
|
||||
Ok(InstanceHandle { instance })
|
||||
}
|
||||
|
||||
@@ -476,7 +467,7 @@ pub unsafe fn allocate_single_memory_instance(
|
||||
///
|
||||
/// See [`InstanceAllocator::deallocate()`] for more details.
|
||||
pub unsafe fn deallocate(handle: &InstanceHandle) {
|
||||
let layout = Instance::alloc_layout(&handle.instance().offsets);
|
||||
let layout = Instance::alloc_layout(handle.instance().offsets());
|
||||
ptr::drop_in_place(handle.instance);
|
||||
alloc::dealloc(handle.instance.cast(), layout);
|
||||
}
|
||||
@@ -485,12 +476,10 @@ unsafe impl InstanceAllocator for OnDemandInstanceAllocator {
|
||||
unsafe fn allocate(&self, mut req: InstanceAllocationRequest) -> Result<InstanceHandle> {
|
||||
let memories = self.create_memories(&mut req.store, &req.runtime_info)?;
|
||||
let tables = Self::create_tables(&mut req.store, &req.runtime_info)?;
|
||||
let module = req.runtime_info.module();
|
||||
let offsets = VMOffsets::new(HostPtr, module);
|
||||
let layout = Instance::alloc_layout(&offsets);
|
||||
let layout = Instance::alloc_layout(req.runtime_info.offsets());
|
||||
let instance_ptr = alloc::alloc(layout) as *mut Instance;
|
||||
|
||||
Instance::new_at(instance_ptr, layout.size(), offsets, req, memories, tables);
|
||||
Instance::new_at(instance_ptr, layout.size(), req, memories, tables);
|
||||
|
||||
Ok(InstanceHandle {
|
||||
instance: instance_ptr,
|
||||
|
||||
@@ -169,7 +169,7 @@ impl InstancePool {
|
||||
// If this fails then it's a configuration error at the `Engine` level
|
||||
// from when this pooling allocator was created and that needs updating
|
||||
// if this is to succeed.
|
||||
let offsets = self.validate_instance_size(module)?;
|
||||
self.validate_instance_size(req.runtime_info.offsets())?;
|
||||
|
||||
let mut memories =
|
||||
PrimaryMap::with_capacity(module.memory_plans.len() - module.num_imported_memories);
|
||||
@@ -192,14 +192,7 @@ impl InstancePool {
|
||||
|
||||
let instance_ptr = self.instance(instance_index) as _;
|
||||
|
||||
Instance::new_at(
|
||||
instance_ptr,
|
||||
self.instance_size,
|
||||
offsets,
|
||||
req,
|
||||
memories,
|
||||
tables,
|
||||
);
|
||||
Instance::new_at(instance_ptr, self.instance_size, req, memories, tables);
|
||||
|
||||
Ok(InstanceHandle {
|
||||
instance: instance_ptr,
|
||||
@@ -485,11 +478,10 @@ impl InstancePool {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_instance_size(&self, module: &Module) -> Result<VMOffsets<HostPtr>> {
|
||||
let offsets = VMOffsets::new(HostPtr, module);
|
||||
let layout = Instance::alloc_layout(&offsets);
|
||||
fn validate_instance_size(&self, offsets: &VMOffsets<HostPtr>) -> Result<()> {
|
||||
let layout = Instance::alloc_layout(offsets);
|
||||
if layout.size() <= self.instance_size {
|
||||
return Ok(offsets);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// If this `module` exceeds the allocation size allotted to it then an
|
||||
@@ -1078,17 +1070,10 @@ impl PoolingInstanceAllocator {
|
||||
}
|
||||
|
||||
unsafe impl InstanceAllocator for PoolingInstanceAllocator {
|
||||
fn validate(&self, module: &Module) -> Result<()> {
|
||||
fn validate(&self, module: &Module, offsets: &VMOffsets<HostPtr>) -> Result<()> {
|
||||
self.instances.validate_memory_plans(module)?;
|
||||
self.instances.validate_table_plans(module)?;
|
||||
|
||||
// Note that this check is not 100% accurate for cross-compiled systems
|
||||
// where the pointer size may change since this check is often performed
|
||||
// at compile time instead of runtime. Given that Wasmtime is almost
|
||||
// always on a 64-bit platform though this is generally ok, and
|
||||
// otherwise this check also happens during instantiation to
|
||||
// double-check at that point.
|
||||
self.instances.validate_instance_size(module)?;
|
||||
self.instances.validate_instance_size(offsets)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1145,26 +1130,22 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{CompiledModuleId, Imports, MemoryImage, StorePtr, VMSharedSignatureIndex};
|
||||
use crate::{
|
||||
CompiledModuleId, Imports, MemoryImage, StorePtr, VMFunctionBody, VMSharedSignatureIndex,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use wasmtime_environ::{DefinedFuncIndex, DefinedMemoryIndex, FunctionLoc, SignatureIndex};
|
||||
use wasmtime_environ::{DefinedFuncIndex, DefinedMemoryIndex};
|
||||
|
||||
pub(crate) fn empty_runtime_info(
|
||||
module: Arc<wasmtime_environ::Module>,
|
||||
) -> Arc<dyn ModuleRuntimeInfo> {
|
||||
struct RuntimeInfo(Arc<wasmtime_environ::Module>);
|
||||
struct RuntimeInfo(Arc<wasmtime_environ::Module>, VMOffsets<HostPtr>);
|
||||
|
||||
impl ModuleRuntimeInfo for RuntimeInfo {
|
||||
fn module(&self) -> &Arc<wasmtime_environ::Module> {
|
||||
&self.0
|
||||
}
|
||||
fn image_base(&self) -> usize {
|
||||
0
|
||||
}
|
||||
fn function_loc(&self, _: DefinedFuncIndex) -> &FunctionLoc {
|
||||
unimplemented!()
|
||||
}
|
||||
fn signature(&self, _: SignatureIndex) -> VMSharedSignatureIndex {
|
||||
fn function(&self, _: DefinedFuncIndex) -> *mut VMFunctionBody {
|
||||
unimplemented!()
|
||||
}
|
||||
fn memory_image(
|
||||
@@ -1183,9 +1164,13 @@ mod test {
|
||||
fn signature_ids(&self) -> &[VMSharedSignatureIndex] {
|
||||
&[]
|
||||
}
|
||||
fn offsets(&self) -> &VMOffsets<HostPtr> {
|
||||
&self.1
|
||||
}
|
||||
}
|
||||
|
||||
Arc::new(RuntimeInfo(module))
|
||||
let offsets = VMOffsets::new(HostPtr, &module);
|
||||
Arc::new(RuntimeInfo(module, offsets))
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
|
||||
Reference in New Issue
Block a user