Use malloc/free to allocate Instance structure (#948)
Previously `Instance` was always allocated with `mmap`. This was done to future-proof `Instance` for allowing storing the memory itself inline with an `Instance` allocation, but this can actually be done with `alloc`/`dealloc` since they take an alignment. By using `malloc`/`free` we can avoid fragmentation as well as hook into standard leak tracking mechanisms.
This commit is contained in:
@@ -6,7 +6,6 @@ use crate::export::Export;
|
|||||||
use crate::imports::Imports;
|
use crate::imports::Imports;
|
||||||
use crate::jit_int::GdbJitImageRegistration;
|
use crate::jit_int::GdbJitImageRegistration;
|
||||||
use crate::memory::LinearMemory;
|
use crate::memory::LinearMemory;
|
||||||
use crate::mmap::Mmap;
|
|
||||||
use crate::signalhandlers;
|
use crate::signalhandlers;
|
||||||
use crate::table::Table;
|
use crate::table::Table;
|
||||||
use crate::traphandlers::{wasmtime_call, Trap};
|
use crate::traphandlers::{wasmtime_call, Trap};
|
||||||
@@ -18,6 +17,7 @@ use crate::vmcontext::{
|
|||||||
use crate::TrapRegistration;
|
use crate::TrapRegistration;
|
||||||
use memoffset::offset_of;
|
use memoffset::offset_of;
|
||||||
use more_asserts::assert_lt;
|
use more_asserts::assert_lt;
|
||||||
|
use std::alloc::{self, Layout};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
@@ -74,9 +74,6 @@ pub(crate) struct Instance {
|
|||||||
/// import from each other.
|
/// import from each other.
|
||||||
dependencies: HashSet<InstanceHandle>,
|
dependencies: HashSet<InstanceHandle>,
|
||||||
|
|
||||||
/// The underlying mmap that holds this `Instance`.
|
|
||||||
mmap: Cell<Mmap>,
|
|
||||||
|
|
||||||
/// The `Module` this `Instance` was instantiated from.
|
/// The `Module` this `Instance` was instantiated from.
|
||||||
module: Arc<Module>,
|
module: Arc<Module>,
|
||||||
|
|
||||||
@@ -511,6 +508,14 @@ impl Instance {
|
|||||||
.unwrap_or_else(|| panic!("no table for index {}", table_index.index()))
|
.unwrap_or_else(|| panic!("no table for index {}", table_index.index()))
|
||||||
.set(index, val)
|
.set(index, val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn alloc_layout(&self) -> Layout {
|
||||||
|
let size = mem::size_of_val(self)
|
||||||
|
.checked_add(usize::try_from(self.offsets.size_of_vmctx()).unwrap())
|
||||||
|
.unwrap();
|
||||||
|
let align = mem::align_of_val(self);
|
||||||
|
Layout::from_size_align(size, align).unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A handle holding an `Instance` of a WebAssembly module.
|
/// A handle holding an `Instance` of a WebAssembly module.
|
||||||
@@ -564,20 +569,10 @@ impl InstanceHandle {
|
|||||||
|
|
||||||
let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, &module);
|
let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, &module);
|
||||||
|
|
||||||
let mut instance_mmap = Mmap::with_at_least(
|
|
||||||
mem::size_of::<Instance>()
|
|
||||||
.checked_add(usize::try_from(offsets.size_of_vmctx()).unwrap())
|
|
||||||
.unwrap(),
|
|
||||||
)
|
|
||||||
.map_err(InstantiationError::Resource)?;
|
|
||||||
|
|
||||||
let handle = {
|
let handle = {
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
|
||||||
let instance_ptr = instance_mmap.as_mut_ptr() as *mut Instance;
|
|
||||||
let instance = Instance {
|
let instance = Instance {
|
||||||
refcount: Cell::new(1),
|
refcount: Cell::new(1),
|
||||||
dependencies: imports.dependencies,
|
dependencies: imports.dependencies,
|
||||||
mmap: Cell::new(instance_mmap),
|
|
||||||
module,
|
module,
|
||||||
offsets,
|
offsets,
|
||||||
memories,
|
memories,
|
||||||
@@ -589,6 +584,11 @@ impl InstanceHandle {
|
|||||||
trap_registration,
|
trap_registration,
|
||||||
vmctx: VMContext {},
|
vmctx: VMContext {},
|
||||||
};
|
};
|
||||||
|
let layout = instance.alloc_layout();
|
||||||
|
let instance_ptr = alloc::alloc(layout) as *mut Instance;
|
||||||
|
if instance_ptr.is_null() {
|
||||||
|
alloc::handle_alloc_error(layout);
|
||||||
|
}
|
||||||
ptr::write(instance_ptr, instance);
|
ptr::write(instance_ptr, instance);
|
||||||
InstanceHandle {
|
InstanceHandle {
|
||||||
instance: instance_ptr,
|
instance: instance_ptr,
|
||||||
@@ -790,9 +790,11 @@ impl Drop for InstanceHandle {
|
|||||||
let count = instance.refcount.get();
|
let count = instance.refcount.get();
|
||||||
instance.refcount.set(count - 1);
|
instance.refcount.set(count - 1);
|
||||||
if count == 1 {
|
if count == 1 {
|
||||||
let mmap = instance.mmap.replace(Mmap::new());
|
let layout = instance.alloc_layout();
|
||||||
unsafe { ptr::drop_in_place(self.instance) };
|
unsafe {
|
||||||
mem::drop(mmap);
|
ptr::drop_in_place(self.instance);
|
||||||
|
alloc::dealloc(self.instance.cast(), layout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user