Browse Source

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.
pull/952/head
Alex Crichton 5 years ago
committed by GitHub
parent
commit
b15b5cd05a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      crates/runtime/src/instance.rs

36
crates/runtime/src/instance.rs

@ -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);
}
} }
} }
} }

Loading…
Cancel
Save