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:
Alex Crichton
2022-12-01 16:22:08 -06:00
committed by GitHub
parent ed6769084b
commit 03715dda9d
14 changed files with 142 additions and 176 deletions

View File

@@ -86,9 +86,9 @@ impl Engine {
#[cfg(compiler)]
let compiler = config.build_compiler()?;
drop(&mut config); // silence warnings without `cfg(compiler)`
let allocator = config.build_allocator()?;
allocator.adjust_tunables(&mut config.tunables);
let profiler = config.build_profiler()?;
Ok(Engine {

View File

@@ -14,12 +14,13 @@ use std::path::Path;
use std::sync::Arc;
use wasmparser::{Parser, ValidPayload, Validator};
use wasmtime_environ::{
DefinedFuncIndex, DefinedMemoryIndex, FunctionLoc, ModuleEnvironment, ModuleTranslation,
ModuleTypes, ObjectKind, PrimaryMap, SignatureIndex, WasmFunctionInfo,
DefinedFuncIndex, DefinedMemoryIndex, HostPtr, ModuleEnvironment, ModuleTranslation,
ModuleTypes, ObjectKind, PrimaryMap, VMOffsets, WasmFunctionInfo,
};
use wasmtime_jit::{CodeMemory, CompiledModule, CompiledModuleInfo};
use wasmtime_runtime::{
CompiledModuleId, MemoryImage, MmapVec, ModuleMemoryImages, VMSharedSignatureIndex,
CompiledModuleId, MemoryImage, MmapVec, ModuleMemoryImages, VMFunctionBody,
VMSharedSignatureIndex,
};
mod registry;
@@ -123,6 +124,9 @@ struct ModuleInner {
/// Flag indicating whether this module can be serialized or not.
serializable: bool,
/// Runtime offset information for `VMContext`.
offsets: VMOffsets<HostPtr>,
}
impl Module {
@@ -664,7 +668,8 @@ impl Module {
)?;
// Validate the module can be used with the current allocator
engine.allocator().validate(module.module())?;
let offsets = VMOffsets::new(HostPtr, module.module());
engine.allocator().validate(module.module(), &offsets)?;
Ok(Self {
inner: Arc::new(ModuleInner {
@@ -673,6 +678,7 @@ impl Module {
memory_images: OnceCell::new(),
module,
serializable,
offsets,
}),
})
}
@@ -1098,16 +1104,12 @@ impl wasmtime_runtime::ModuleRuntimeInfo for ModuleInner {
self.module.module()
}
fn signature(&self, index: SignatureIndex) -> VMSharedSignatureIndex {
self.code.signatures().as_module_map()[index]
}
fn image_base(&self) -> usize {
self.module.text().as_ptr() as usize
}
fn function_loc(&self, index: DefinedFuncIndex) -> &FunctionLoc {
self.module.func_loc(index)
fn function(&self, index: DefinedFuncIndex) -> *mut VMFunctionBody {
self.module
.finished_function(index)
.as_ptr()
.cast::<VMFunctionBody>()
.cast_mut()
}
fn memory_image(&self, memory: DefinedMemoryIndex) -> Result<Option<&Arc<MemoryImage>>> {
@@ -1126,6 +1128,10 @@ impl wasmtime_runtime::ModuleRuntimeInfo for ModuleInner {
fn signature_ids(&self) -> &[VMSharedSignatureIndex] {
self.code.signatures().as_module_map().values().as_slice()
}
fn offsets(&self) -> &VMOffsets<HostPtr> {
&self.offsets
}
}
impl wasmtime_runtime::ModuleInfo for ModuleInner {
@@ -1160,26 +1166,22 @@ impl wasmtime_runtime::ModuleInfo for ModuleInner {
/// default-callee instance).
pub(crate) struct BareModuleInfo {
module: Arc<wasmtime_environ::Module>,
image_base: usize,
one_signature: Option<(SignatureIndex, VMSharedSignatureIndex)>,
one_signature: Option<VMSharedSignatureIndex>,
offsets: VMOffsets<HostPtr>,
}
impl BareModuleInfo {
pub(crate) fn empty(module: Arc<wasmtime_environ::Module>) -> Self {
BareModuleInfo {
module,
image_base: 0,
one_signature: None,
}
BareModuleInfo::maybe_imported_func(module, None)
}
pub(crate) fn maybe_imported_func(
module: Arc<wasmtime_environ::Module>,
one_signature: Option<(SignatureIndex, VMSharedSignatureIndex)>,
one_signature: Option<VMSharedSignatureIndex>,
) -> Self {
BareModuleInfo {
offsets: VMOffsets::new(HostPtr, &module),
module,
image_base: 0,
one_signature,
}
}
@@ -1194,19 +1196,7 @@ impl wasmtime_runtime::ModuleRuntimeInfo for BareModuleInfo {
&self.module
}
fn signature(&self, index: SignatureIndex) -> VMSharedSignatureIndex {
let (signature_id, signature) = self
.one_signature
.expect("Signature for one function should be present if queried");
assert_eq!(index, signature_id);
signature
}
fn image_base(&self) -> usize {
self.image_base
}
fn function_loc(&self, _index: DefinedFuncIndex) -> &FunctionLoc {
fn function(&self, _index: DefinedFuncIndex) -> *mut VMFunctionBody {
unreachable!()
}
@@ -1224,10 +1214,14 @@ impl wasmtime_runtime::ModuleRuntimeInfo for BareModuleInfo {
fn signature_ids(&self) -> &[VMSharedSignatureIndex] {
match &self.one_signature {
Some((_, id)) => std::slice::from_ref(id),
Some(id) => std::slice::from_ref(id),
None => &[],
}
}
fn offsets(&self) -> &VMOffsets<HostPtr> {
&self.offsets
}
}
/// Helper method to construct a `ModuleMemoryImages` for an associated

View File

@@ -161,7 +161,7 @@ impl LoadedCode {
// functions.
None => return,
};
let start = unsafe { (*func).as_ptr() as usize };
let start = func.as_ptr() as usize;
match self.modules.entry(start) {
// This module is already present, and it should be the same as
@@ -279,9 +279,9 @@ fn test_frame_info() -> Result<(), anyhow::Error> {
Instance::new(&mut store, &module, &[])?;
for (i, alloc) in module.compiled_module().finished_functions() {
let (start, end) = unsafe {
let ptr = (*alloc).as_ptr();
let len = (*alloc).len();
let (start, end) = {
let ptr = alloc.as_ptr();
let len = alloc.len();
(ptr as usize, ptr as usize + len)
};
for pc in start..end {

View File

@@ -17,7 +17,7 @@ use crate::{GlobalType, MemoryType, TableType, Val};
use anyhow::Result;
use std::any::Any;
use std::sync::Arc;
use wasmtime_environ::{GlobalIndex, MemoryIndex, Module, SignatureIndex, TableIndex};
use wasmtime_environ::{GlobalIndex, MemoryIndex, Module, TableIndex};
use wasmtime_runtime::{
Imports, InstanceAllocationRequest, InstanceAllocator, OnDemandInstanceAllocator, SharedMemory,
StorePtr, VMFunctionImport, VMSharedSignatureIndex,
@@ -28,7 +28,7 @@ fn create_handle(
store: &mut StoreOpaque,
host_state: Box<dyn Any + Send + Sync>,
func_imports: &[VMFunctionImport],
one_signature: Option<(SignatureIndex, VMSharedSignatureIndex)>,
one_signature: Option<VMSharedSignatureIndex>,
) -> Result<InstanceId> {
let mut imports = Imports::default();
imports.functions = func_imports;

View File

@@ -39,8 +39,8 @@ pub fn create_global(store: &mut StoreOpaque, gt: &GlobalType, val: Val) -> Resu
// our global with a `ref.func` to grab that imported function.
let f = f.caller_checked_anyfunc(store);
let f = unsafe { f.as_ref() };
let sig_id = SignatureIndex::from_u32(u32::max_value() - 1);
one_signature = Some((sig_id, f.type_index));
let sig_id = SignatureIndex::from_u32(0);
one_signature = Some(f.type_index);
module.types.push(ModuleType::Function(sig_id));
let func_index = module.push_escaped_function(sig_id, AnyfuncIndex::from_u32(0));
module.num_imported_funcs = 1;