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:
@@ -77,22 +77,23 @@ pub fn create_function(
|
||||
engine: &Engine,
|
||||
) -> Result<(InstanceHandle, VMTrampoline)> {
|
||||
let mut obj = engine.compiler().object()?;
|
||||
engine
|
||||
.compiler()
|
||||
.emit_trampoline_obj(ft.as_wasm_func_type(), stub_fn as usize, &mut obj)?;
|
||||
let (t1, t2) = engine.compiler().emit_trampoline_obj(
|
||||
ft.as_wasm_func_type(),
|
||||
stub_fn as usize,
|
||||
&mut obj,
|
||||
)?;
|
||||
let obj = obj.write()?;
|
||||
|
||||
// Copy the results of JIT compilation into executable memory, and this will
|
||||
// also take care of unwind table registration.
|
||||
let mut code_memory = CodeMemory::new();
|
||||
let alloc = code_memory.allocate_for_object_unparsed(&obj)?;
|
||||
let mut trampolines = alloc.trampolines();
|
||||
let (host_i, host_trampoline) = trampolines.next().unwrap();
|
||||
assert_eq!(host_i.as_u32(), 0);
|
||||
let (wasm_i, wasm_trampoline) = trampolines.next().unwrap();
|
||||
assert_eq!(wasm_i.as_u32(), 1);
|
||||
assert!(trampolines.next().is_none());
|
||||
let host_trampoline = host_trampoline.as_ptr();
|
||||
let wasm_trampoline = wasm_trampoline as *mut [_];
|
||||
drop(trampolines);
|
||||
let (alloc, _obj) = code_memory.allocate_for_object_unparsed(&obj)?;
|
||||
|
||||
// Extract the host/wasm trampolines from the results of compilation since
|
||||
// we know their start/length.
|
||||
let host_trampoline = alloc[t1.start as usize..][..t1.length as usize].as_ptr();
|
||||
let wasm_trampoline = &mut alloc[t2.start as usize..][..t2.length as usize];
|
||||
let wasm_trampoline = wasm_trampoline as *mut [u8] as *mut [VMFunctionBody];
|
||||
|
||||
code_memory.publish();
|
||||
|
||||
@@ -104,8 +105,7 @@ pub fn create_function(
|
||||
sig,
|
||||
Box::new(TrampolineState { func, code_memory }),
|
||||
)?;
|
||||
let host_trampoline =
|
||||
std::mem::transmute::<*const VMFunctionBody, VMTrampoline>(host_trampoline);
|
||||
let host_trampoline = std::mem::transmute::<*const u8, VMTrampoline>(host_trampoline);
|
||||
Ok((instance, host_trampoline))
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,8 @@ pub unsafe fn create_raw_function(
|
||||
host_state: Box<dyn Any + Send + Sync>,
|
||||
) -> Result<InstanceHandle> {
|
||||
let mut module = Module::new();
|
||||
let mut finished_functions = PrimaryMap::new();
|
||||
let mut functions = PrimaryMap::new();
|
||||
functions.push(Default::default());
|
||||
|
||||
let sig_id = SignatureIndex::from_u32(u32::max_value() - 1);
|
||||
module.types.push(ModuleType::Function(sig_id));
|
||||
@@ -124,12 +125,12 @@ pub unsafe fn create_raw_function(
|
||||
module
|
||||
.exports
|
||||
.insert(String::new(), EntityIndex::Function(func_id));
|
||||
finished_functions.push(func);
|
||||
|
||||
Ok(
|
||||
OnDemandInstanceAllocator::default().allocate(InstanceAllocationRequest {
|
||||
module: Arc::new(module),
|
||||
finished_functions: &finished_functions,
|
||||
functions: &functions,
|
||||
image_base: (*func).as_ptr() as usize,
|
||||
imports: Imports::default(),
|
||||
shared_signatures: sig.into(),
|
||||
host_state,
|
||||
|
||||
Reference in New Issue
Block a user