From b15b5cd05add81a16a8c5e264d8c8fa6f4c61764 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 18 Feb 2020 12:33:48 -0600 Subject: [PATCH] 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. --- crates/runtime/src/instance.rs | 36 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/crates/runtime/src/instance.rs b/crates/runtime/src/instance.rs index c1195ffa21..0e851d3705 100644 --- a/crates/runtime/src/instance.rs +++ b/crates/runtime/src/instance.rs @@ -6,7 +6,6 @@ use crate::export::Export; use crate::imports::Imports; use crate::jit_int::GdbJitImageRegistration; use crate::memory::LinearMemory; -use crate::mmap::Mmap; use crate::signalhandlers; use crate::table::Table; use crate::traphandlers::{wasmtime_call, Trap}; @@ -18,6 +17,7 @@ use crate::vmcontext::{ use crate::TrapRegistration; use memoffset::offset_of; use more_asserts::assert_lt; +use std::alloc::{self, Layout}; use std::any::Any; use std::cell::Cell; use std::collections::HashSet; @@ -74,9 +74,6 @@ pub(crate) struct Instance { /// import from each other. dependencies: HashSet, - /// The underlying mmap that holds this `Instance`. - mmap: Cell, - /// The `Module` this `Instance` was instantiated from. module: Arc, @@ -511,6 +508,14 @@ impl Instance { .unwrap_or_else(|| panic!("no table for index {}", table_index.index())) .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. @@ -564,20 +569,10 @@ impl InstanceHandle { let offsets = VMOffsets::new(mem::size_of::<*const u8>() as u8, &module); - let mut instance_mmap = Mmap::with_at_least( - mem::size_of::() - .checked_add(usize::try_from(offsets.size_of_vmctx()).unwrap()) - .unwrap(), - ) - .map_err(InstantiationError::Resource)?; - let handle = { - #[allow(clippy::cast_ptr_alignment)] - let instance_ptr = instance_mmap.as_mut_ptr() as *mut Instance; let instance = Instance { refcount: Cell::new(1), dependencies: imports.dependencies, - mmap: Cell::new(instance_mmap), module, offsets, memories, @@ -589,6 +584,11 @@ impl InstanceHandle { trap_registration, 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); InstanceHandle { instance: instance_ptr, @@ -790,9 +790,11 @@ impl Drop for InstanceHandle { let count = instance.refcount.get(); instance.refcount.set(count - 1); if count == 1 { - let mmap = instance.mmap.replace(Mmap::new()); - unsafe { ptr::drop_in_place(self.instance) }; - mem::drop(mmap); + let layout = instance.alloc_layout(); + unsafe { + ptr::drop_in_place(self.instance); + alloc::dealloc(self.instance.cast(), layout); + } } } }