Implement the pooling instance allocator.

This commit implements the pooling instance allocator.

The allocation strategy can be set with `Config::with_allocation_strategy`.

The pooling strategy uses the pooling instance allocator to preallocate a
contiguous region of memory for instantiating modules that adhere to various
limits.

The intention of the pooling instance allocator is to reserve as much of the
host address space needed for instantiating modules ahead of time and to reuse
committed memory pages wherever possible.
This commit is contained in:
Peter Huene
2020-12-08 16:00:48 -08:00
parent 16ca5e16d9
commit e71ccbf9bc
16 changed files with 2374 additions and 20 deletions

View File

@@ -164,7 +164,7 @@ impl RuntimeLinearMemory for MmapMemory {
/// Return a `VMMemoryDefinition` for exposing the memory to compiled wasm code.
fn vmmemory(&self) -> VMMemoryDefinition {
let mut mmap = self.mmap.borrow_mut();
let mmap = self.mmap.borrow();
VMMemoryDefinition {
base: mmap.alloc.as_mut_ptr(),
current_length: mmap.size as usize * WASM_PAGE_SIZE as usize,
@@ -177,7 +177,7 @@ enum MemoryStorage {
base: *mut u8,
size: Cell<u32>,
maximum: u32,
make_accessible: Option<fn(*mut u8, usize) -> bool>,
make_accessible: unsafe fn(*mut u8, usize) -> bool,
},
Dynamic(Box<dyn RuntimeLinearMemory>),
}
@@ -203,13 +203,13 @@ impl Memory {
plan: &MemoryPlan,
base: *mut u8,
maximum: u32,
make_accessible: Option<fn(*mut u8, usize) -> bool>,
make_accessible: unsafe fn(*mut u8, usize) -> bool,
) -> Result<Self, String> {
if plan.memory.minimum > 0 {
if let Some(make_accessible) = &make_accessible {
if !make_accessible(base, plan.memory.minimum as usize * WASM_PAGE_SIZE as usize) {
return Err("memory cannot be made accessible".into());
}
if unsafe {
!make_accessible(base, plan.memory.minimum as usize * WASM_PAGE_SIZE as usize)
} {
return Err("memory cannot be made accessible".into());
}
}
@@ -258,10 +258,8 @@ impl Memory {
let start = usize::try_from(old_size).unwrap() * WASM_PAGE_SIZE as usize;
let len = usize::try_from(delta).unwrap() * WASM_PAGE_SIZE as usize;
if let Some(make_accessible) = make_accessible {
if !make_accessible(unsafe { base.add(start) }, len) {
return None;
}
if unsafe { !make_accessible(base.add(start), len) } {
return None;
}
size.set(new_size);