Remove some allocations in CodeMemory (#3253)
* Remove some allocations in `CodeMemory` This commit removes the `FinishedFunctions` type as well as allocations associated with trampolines when allocating inside of a `CodeMemory`. The main goal of this commit is to improve the time spent in `CodeMemory` where currently today a good portion of time is spent simply parsing symbol names and trying to extract function indices from them. Instead this commit implements a new strategy (different from #3236) where compilation records offset/length information for all functions/trampolines so this doesn't need to be re-learned from the object file later. A consequence of this commit is that this offset information will be decoded/encoded through `bincode` unconditionally, but we can also optimize that later if necessary as well. Internally this involved quite a bit of refactoring since the previous map for `FinishedFunctions` was relatively heavily relied upon. * comments
This commit is contained in:
@@ -4,7 +4,7 @@ use crate::memory::{DefaultMemoryCreator, Memory};
|
||||
use crate::table::Table;
|
||||
use crate::traphandlers::Trap;
|
||||
use crate::vmcontext::{
|
||||
VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMGlobalDefinition,
|
||||
VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMGlobalDefinition,
|
||||
VMSharedSignatureIndex,
|
||||
};
|
||||
use crate::Store;
|
||||
@@ -18,8 +18,8 @@ use std::slice;
|
||||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
use wasmtime_environ::{
|
||||
DefinedFuncIndex, DefinedMemoryIndex, DefinedTableIndex, EntityRef, EntitySet, GlobalInit,
|
||||
HostPtr, MemoryInitialization, MemoryInitializer, Module, ModuleType, PrimaryMap,
|
||||
DefinedFuncIndex, DefinedMemoryIndex, DefinedTableIndex, EntityRef, EntitySet, FunctionInfo,
|
||||
GlobalInit, HostPtr, MemoryInitialization, MemoryInitializer, Module, ModuleType, PrimaryMap,
|
||||
SignatureIndex, TableInitializer, TrapCode, VMOffsets, WasmType, WASM_PAGE_SIZE,
|
||||
};
|
||||
|
||||
@@ -34,8 +34,12 @@ pub struct InstanceAllocationRequest<'a> {
|
||||
/// The module being instantiated.
|
||||
pub module: Arc<Module>,
|
||||
|
||||
/// The finished (JIT) functions for the module.
|
||||
pub finished_functions: &'a PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
|
||||
/// The base address of where JIT functions are located.
|
||||
pub image_base: usize,
|
||||
|
||||
/// Descriptors about each compiled function, such as the offset from
|
||||
/// `image_base`.
|
||||
pub functions: &'a PrimaryMap<DefinedFuncIndex, FunctionInfo>,
|
||||
|
||||
/// The imports to use for the instantiation.
|
||||
pub imports: Imports<'a>,
|
||||
@@ -483,7 +487,8 @@ unsafe fn initialize_vmcontext(instance: &mut Instance, req: InstanceAllocationR
|
||||
|
||||
let (func_ptr, vmctx) = if let Some(def_index) = instance.module.defined_func_index(index) {
|
||||
(
|
||||
NonNull::new(req.finished_functions[def_index] as *mut _).unwrap(),
|
||||
NonNull::new((req.image_base + req.functions[def_index].start as usize) as *mut _)
|
||||
.unwrap(),
|
||||
instance.vmctx_ptr(),
|
||||
)
|
||||
} else {
|
||||
|
||||
@@ -1393,7 +1393,7 @@ mod test {
|
||||
|
||||
let mut handles = Vec::new();
|
||||
let module = Arc::new(Module::default());
|
||||
let finished_functions = &PrimaryMap::new();
|
||||
let functions = &PrimaryMap::new();
|
||||
|
||||
for _ in (0..3).rev() {
|
||||
handles.push(
|
||||
@@ -1402,7 +1402,8 @@ mod test {
|
||||
PoolingAllocationStrategy::NextAvailable,
|
||||
InstanceAllocationRequest {
|
||||
module: module.clone(),
|
||||
finished_functions,
|
||||
image_base: 0,
|
||||
functions,
|
||||
imports: Imports {
|
||||
functions: &[],
|
||||
tables: &[],
|
||||
@@ -1425,7 +1426,8 @@ mod test {
|
||||
PoolingAllocationStrategy::NextAvailable,
|
||||
InstanceAllocationRequest {
|
||||
module: module.clone(),
|
||||
finished_functions,
|
||||
functions,
|
||||
image_base: 0,
|
||||
imports: Imports {
|
||||
functions: &[],
|
||||
tables: &[],
|
||||
|
||||
@@ -512,7 +512,7 @@ mod test {
|
||||
|
||||
let mut handles = Vec::new();
|
||||
let module = Arc::new(module);
|
||||
let finished_functions = &PrimaryMap::new();
|
||||
let functions = &PrimaryMap::new();
|
||||
|
||||
// Allocate the maximum number of instances with the maximum number of memories
|
||||
for _ in 0..instances.max_instances {
|
||||
@@ -522,7 +522,8 @@ mod test {
|
||||
PoolingAllocationStrategy::Random,
|
||||
InstanceAllocationRequest {
|
||||
module: module.clone(),
|
||||
finished_functions,
|
||||
image_base: 0,
|
||||
functions,
|
||||
imports: Imports {
|
||||
functions: &[],
|
||||
tables: &[],
|
||||
|
||||
Reference in New Issue
Block a user