Skip to content

Commit ba56068

Browse files
committed
Pooling allocator: add a reuse-affinity policy.
This policy attempts to reuse the same instance slot for subsequent instantiations of the same module. This is particularly useful when using a pooling backend such as memfd that benefits from this reuse: for example, in the memfd case, instantiating the same module into the same slot allows us to avoid several calls to mmap() because the same mappings can be reused. The policy tracks a freelist per "compiled module ID", and when allocating a slot for an instance, tries these three options in order: 1. A slot from the freelist for this module (i.e., last used for another instantiation of this particular module), or 3. A slot that was last used by some other module or never before. The "victim" slot for choice 2 is randomly chosen. The data structures are carefully designed so that all updates are O(1), and there is no retry-loop in any of the random selection. This policy is now the default when the memfd backend is selected via the `memfd-allocator` feature flag.
1 parent 570dee6 commit ba56068

11 files changed

Lines changed: 567 additions & 126 deletions

File tree

crates/runtime/src/instance.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::vmcontext::{
1111
VMCallerCheckedAnyfunc, VMContext, VMFunctionImport, VMGlobalDefinition, VMGlobalImport,
1212
VMInterrupts, VMMemoryDefinition, VMMemoryImport, VMTableDefinition, VMTableImport,
1313
};
14-
use crate::{ExportFunction, ExportGlobal, ExportMemory, ExportTable, Store};
14+
use crate::{CompiledModuleId, ExportFunction, ExportGlobal, ExportMemory, ExportTable, Store};
1515
use anyhow::Error;
1616
use memoffset::offset_of;
1717
use more_asserts::assert_lt;
@@ -54,6 +54,9 @@ pub(crate) struct Instance {
5454
/// The `Module` this `Instance` was instantiated from.
5555
module: Arc<Module>,
5656

57+
/// The unique ID for the `Module` this `Instance` was instantiated from.
58+
unique_id: Option<CompiledModuleId>,
59+
5760
/// Offsets in the `vmctx` region, precomputed from the `module` above.
5861
offsets: VMOffsets<HostPtr>,
5962

@@ -100,13 +103,15 @@ impl Instance {
100103
/// Helper for allocators; not a public API.
101104
pub(crate) fn create_raw(
102105
module: &Arc<Module>,
106+
unique_id: Option<CompiledModuleId>,
103107
wasm_data: &'static [u8],
104108
memories: PrimaryMap<DefinedMemoryIndex, Memory>,
105109
tables: PrimaryMap<DefinedTableIndex, Table>,
106110
host_state: Box<dyn Any + Send + Sync>,
107111
) -> Instance {
108112
Instance {
109113
module: module.clone(),
114+
unique_id,
110115
offsets: VMOffsets::new(HostPtr, &module),
111116
memories,
112117
tables,

crates/runtime/src/instance/allocator.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::vmcontext::{
77
VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMGlobalDefinition, VMSharedSignatureIndex,
88
};
99
use crate::ModuleMemFds;
10-
use crate::Store;
10+
use crate::{CompiledModuleId, Store};
1111
use anyhow::Result;
1212
use std::alloc;
1313
use std::any::Any;
@@ -45,6 +45,9 @@ pub struct InstanceAllocationRequest<'a> {
4545
/// The module being instantiated.
4646
pub module: Arc<Module>,
4747

48+
/// The unique ID of the module being allocated within this engine.
49+
pub unique_id: Option<CompiledModuleId>,
50+
4851
/// The base address of where JIT functions are located.
4952
pub image_base: usize,
5053

@@ -738,8 +741,14 @@ unsafe impl InstanceAllocator for OnDemandInstanceAllocator {
738741
let host_state = std::mem::replace(&mut req.host_state, Box::new(()));
739742

740743
let mut handle = {
741-
let instance =
742-
Instance::create_raw(&req.module, &*req.wasm_data, memories, tables, host_state);
744+
let instance = Instance::create_raw(
745+
&req.module,
746+
req.unique_id,
747+
&*req.wasm_data,
748+
memories,
749+
tables,
750+
host_state,
751+
);
743752
let layout = instance.alloc_layout();
744753
let instance_ptr = alloc::alloc(layout) as *mut Instance;
745754
if instance_ptr.is_null() {

0 commit comments

Comments
 (0)