Rename InstanceAllocator -> InstanceRef, use alloc name for builder

This commit is contained in:
Mark McCaskey
2020-12-11 12:19:25 -08:00
parent 9473e2e9d5
commit 569bfd5e67
5 changed files with 65 additions and 65 deletions

View File

@@ -12,7 +12,7 @@ use wasmer_types::{
SignatureIndex, TableIndex, SignatureIndex, TableIndex,
}; };
use wasmer_vm::{ use wasmer_vm::{
FunctionBodyPtr, InstanceBuilder, InstanceHandle, MemoryStyle, ModuleInfo, TableStyle, FunctionBodyPtr, InstanceAllocator, InstanceHandle, MemoryStyle, ModuleInfo, TableStyle,
VMSharedSignatureIndex, VMTrampoline, VMSharedSignatureIndex, VMTrampoline,
}; };
@@ -115,8 +115,8 @@ pub trait Artifact: Send + Sync + Upcastable {
// Get pointers to where metadata about local memories should live in VM memory. // Get pointers to where metadata about local memories should live in VM memory.
// Get pointers to where metadata about local tables should live in VM memory. // Get pointers to where metadata about local tables should live in VM memory.
let (unprepared, memory_definition_locations, table_definition_locations) = let (allocator, memory_definition_locations, table_definition_locations) =
InstanceBuilder::new(&*module); InstanceAllocator::new(&*module);
let finished_memories = tunables let finished_memories = tunables
.create_memories(&module, self.memory_styles(), &memory_definition_locations) .create_memories(&module, self.memory_styles(), &memory_definition_locations)
.map_err(InstantiationError::Link)? .map_err(InstantiationError::Link)?
@@ -133,7 +133,7 @@ pub trait Artifact: Send + Sync + Upcastable {
self.register_frame_info(); self.register_frame_info();
let handle = InstanceHandle::new( let handle = InstanceHandle::new(
unprepared, allocator,
module, module,
self.finished_functions().clone(), self.finished_functions().clone(),
self.finished_function_call_trampolines().clone(), self.finished_function_call_trampolines().clone(),

View File

@@ -2,7 +2,7 @@
// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md // Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md
use crate::global::Global; use crate::global::Global;
use crate::instance::InstanceAllocator; use crate::instance::InstanceRef;
use crate::memory::{Memory, MemoryStyle}; use crate::memory::{Memory, MemoryStyle};
use crate::table::{Table, TableStyle}; use crate::table::{Table, TableStyle};
use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline}; use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline};
@@ -49,8 +49,8 @@ pub struct VMExportFunction {
pub call_trampoline: Option<VMTrampoline>, pub call_trampoline: Option<VMTrampoline>,
/// A “reference” to the instance through the /// A “reference” to the instance through the
/// `InstanceAllocator`. `None` if it is a host function. /// `InstanceRef`. `None` if it is a host function.
pub instance_allocator: Option<InstanceAllocator>, pub instance_allocator: Option<InstanceRef>,
} }
/// # Safety /// # Safety
@@ -74,8 +74,8 @@ pub struct VMExportTable {
pub from: Arc<dyn Table>, pub from: Arc<dyn Table>,
/// A “reference” to the instance through the /// A “reference” to the instance through the
/// `InstanceAllocator`. `None` if it is a host function. /// `InstanceRef`. `None` if it is a host function.
pub instance_allocator: Option<InstanceAllocator>, pub instance_allocator: Option<InstanceRef>,
} }
/// # Safety /// # Safety
@@ -120,8 +120,8 @@ pub struct VMExportMemory {
pub from: Arc<dyn Memory>, pub from: Arc<dyn Memory>,
/// A “reference” to the instance through the /// A “reference” to the instance through the
/// `InstanceAllocator`. `None` if it is a host function. /// `InstanceRef`. `None` if it is a host function.
pub instance_allocator: Option<InstanceAllocator>, pub instance_allocator: Option<InstanceRef>,
} }
/// # Safety /// # Safety
@@ -166,8 +166,8 @@ pub struct VMExportGlobal {
pub from: Arc<Global>, pub from: Arc<Global>,
/// A “reference” to the instance through the /// A “reference” to the instance through the
/// `InstanceAllocator`. `None` if it is a host function. /// `InstanceRef`. `None` if it is a host function.
pub instance_allocator: Option<InstanceAllocator>, pub instance_allocator: Option<InstanceRef>,
} }
/// # Safety /// # Safety

View File

@@ -1,4 +1,4 @@
use super::{Instance, InstanceAllocator}; use super::{Instance, InstanceRef};
use crate::vmcontext::{VMMemoryDefinition, VMTableDefinition}; use crate::vmcontext::{VMMemoryDefinition, VMTableDefinition};
use crate::{ModuleInfo, VMOffsets}; use crate::{ModuleInfo, VMOffsets};
use std::alloc::{self, Layout}; use std::alloc::{self, Layout};
@@ -14,11 +14,11 @@ use wasmer_types::{LocalMemoryIndex, LocalTableIndex};
/// This type will free the allocated memory if it's dropped before /// This type will free the allocated memory if it's dropped before
/// being used. /// being used.
/// ///
/// The [`InstanceBuilder::instance_layout`] computes the correct /// The [`InstanceAllocator::instance_layout`] computes the correct
/// layout to represent the wanted [`Instance`]. /// layout to represent the wanted [`Instance`].
/// ///
/// Then we use this layout to allocate an empty `Instance` properly. /// Then we use this layout to allocate an empty `Instance` properly.
pub struct InstanceBuilder { pub struct InstanceAllocator {
/// The buffer that will contain the [`Instance`] and dynamic fields. /// The buffer that will contain the [`Instance`] and dynamic fields.
instance_ptr: NonNull<Instance>, instance_ptr: NonNull<Instance>,
/// The layout of the `instance_ptr` buffer. /// The layout of the `instance_ptr` buffer.
@@ -32,7 +32,7 @@ pub struct InstanceBuilder {
consumed: bool, consumed: bool,
} }
impl Drop for InstanceBuilder { impl Drop for InstanceAllocator {
fn drop(&mut self) { fn drop(&mut self) {
if !self.consumed { if !self.consumed {
// If `consumed` has not been set, then we still have ownership // If `consumed` has not been set, then we still have ownership
@@ -45,7 +45,7 @@ impl Drop for InstanceBuilder {
} }
} }
impl InstanceBuilder { impl InstanceAllocator {
/// Allocates instance data for use with [`InstanceHandle::new`]. /// Allocates instance data for use with [`InstanceHandle::new`].
/// ///
/// Returns a wrapper type around the allocation and 2 vectors of /// Returns a wrapper type around the allocation and 2 vectors of
@@ -56,7 +56,7 @@ impl InstanceBuilder {
pub fn new( pub fn new(
module: &ModuleInfo, module: &ModuleInfo,
) -> ( ) -> (
InstanceBuilder, InstanceAllocator,
Vec<NonNull<VMMemoryDefinition>>, Vec<NonNull<VMMemoryDefinition>>,
Vec<NonNull<VMTableDefinition>>, Vec<NonNull<VMTableDefinition>>,
) { ) {
@@ -72,7 +72,7 @@ impl InstanceBuilder {
alloc::handle_alloc_error(instance_layout); alloc::handle_alloc_error(instance_layout);
}; };
let unprepared = Self { let allocator = Self {
instance_ptr, instance_ptr,
instance_layout, instance_layout,
offsets, offsets,
@@ -83,10 +83,10 @@ impl InstanceBuilder {
// Both of these calls are safe because we allocate the pointer // Both of these calls are safe because we allocate the pointer
// above with the same `offsets` that these functions use. // above with the same `offsets` that these functions use.
// Thus there will be enough valid memory for both of them. // Thus there will be enough valid memory for both of them.
let memories = unsafe { unprepared.memory_definition_locations() }; let memories = unsafe { allocator.memory_definition_locations() };
let tables = unsafe { unprepared.table_definition_locations() }; let tables = unsafe { allocator.table_definition_locations() };
(unprepared, memories, tables) (allocator, memories, tables)
} }
/// Calculate the appropriate layout for the [`Instance`]. /// Calculate the appropriate layout for the [`Instance`].
@@ -170,7 +170,7 @@ impl InstanceBuilder {
} }
/// Finish preparing by writing the [`Instance`] into memory. /// Finish preparing by writing the [`Instance`] into memory.
pub(crate) fn write_instance(mut self, instance: Instance) -> InstanceAllocator { pub(crate) fn write_instance(mut self, instance: Instance) -> InstanceRef {
// prevent the old state's drop logic from being called as we // prevent the old state's drop logic from being called as we
// transition into the new state. // transition into the new state.
self.consumed = true; self.consumed = true;
@@ -178,7 +178,7 @@ impl InstanceBuilder {
unsafe { unsafe {
// `instance` is moved at `instance_ptr`. This pointer has // `instance` is moved at `instance_ptr`. This pointer has
// been allocated by `Self::allocate_instance` (so by // been allocated by `Self::allocate_instance` (so by
// `InstanceAllocator::allocate_instance`. // `InstanceRef::allocate_instance`.
ptr::write(self.instance_ptr.as_ptr(), instance); ptr::write(self.instance_ptr.as_ptr(), instance);
// Now `instance_ptr` is correctly initialized! // Now `instance_ptr` is correctly initialized!
} }
@@ -187,7 +187,7 @@ impl InstanceBuilder {
// This is correct because of the invariants of `Self` and // This is correct because of the invariants of `Self` and
// because we write `Instance` to the pointer in this function. // because we write `Instance` to the pointer in this function.
unsafe { InstanceAllocator::new(instance, instance_layout) } unsafe { InstanceRef::new(instance, instance_layout) }
} }
/// Get the [`VMOffsets`] for the allocated buffer. /// Get the [`VMOffsets`] for the allocated buffer.

View File

@@ -3,13 +3,13 @@
//! An `Instance` contains all the runtime state used by execution of //! An `Instance` contains all the runtime state used by execution of
//! a WebAssembly module (except its callstack and register state). An //! a WebAssembly module (except its callstack and register state). An
//! `InstanceAllocator` is a wrapper around `Instance` that manages //! `InstanceRef` is a wrapper around `Instance` that manages
//! how it is allocated and deallocated. An `InstanceHandle` is a //! how it is allocated and deallocated. An `InstanceHandle` is a
//! wrapper around an `InstanceAllocator`. //! wrapper around an `InstanceRef`.
mod builder; mod allocator;
pub use builder::InstanceBuilder; pub use allocator::InstanceAllocator;
use crate::export::VMExport; use crate::export::VMExport;
use crate::global::Global; use crate::global::Global;
@@ -693,15 +693,15 @@ impl Instance {
} }
/// TODO: update these docs /// TODO: update these docs
/// An `InstanceAllocator` is responsible to allocate, to deallocate, /// An `InstanceRef` is responsible to allocate, to deallocate,
/// and to give access to an `Instance`, in such a way that `Instance` /// and to give access to an `Instance`, in such a way that `Instance`
/// is unique, can be shared, safely, across threads, without /// is unique, can be shared, safely, across threads, without
/// duplicating the pointer in multiple locations. `InstanceAllocator` /// duplicating the pointer in multiple locations. `InstanceRef`
/// must be the only “owner” of an `Instance`. /// must be the only “owner” of an `Instance`.
/// ///
/// Consequently, one must not share `Instance` but /// Consequently, one must not share `Instance` but
/// `InstanceAllocator`. It acts like an Atomically Reference Counted /// `InstanceRef`. It acts like an Atomically Reference Counted
/// to `Instance`. In short, `InstanceAllocator` is roughly a /// to `Instance`. In short, `InstanceRef` is roughly a
/// simplified version of `std::sync::Arc`. /// simplified version of `std::sync::Arc`.
/// ///
/// It is important to remind that `Instance` is dynamically-sized /// It is important to remind that `Instance` is dynamically-sized
@@ -712,12 +712,12 @@ impl Instance {
/// 1. Define the correct layout for `Instance` (size and alignment), /// 1. Define the correct layout for `Instance` (size and alignment),
/// 2. Allocate it properly. /// 2. Allocate it properly.
/// ///
/// This allocation must be freed with [`InstanceAllocator::deallocate_instance`] /// This allocation must be freed with [`InstanceRef::deallocate_instance`]
/// if and only if it has been set correctly. The `Drop` implementation of /// if and only if it has been set correctly. The `Drop` implementation of
/// [`InstanceAllocator`] calls its `deallocate_instance` method without /// [`InstanceRef`] calls its `deallocate_instance` method without
/// checking if this property holds, only when `Self.strong` is equal to 1. /// checking if this property holds, only when `Self.strong` is equal to 1.
/// ///
/// Note for the curious reader: [`InstanceBuilder::new`] /// Note for the curious reader: [`InstanceAllocator::new`]
/// and [`InstanceHandle::new`] will respectively allocate a proper /// and [`InstanceHandle::new`] will respectively allocate a proper
/// `Instance` and will fill it correctly. /// `Instance` and will fill it correctly.
/// ///
@@ -730,7 +730,7 @@ impl Instance {
/// dynamically-sized, and the `instance` field must be last. /// dynamically-sized, and the `instance` field must be last.
#[derive(Debug)] #[derive(Debug)]
#[repr(C)] #[repr(C)]
pub struct InstanceAllocator { pub struct InstanceRef {
/// Number of `Self` in the nature. It increases when `Self` is /// Number of `Self` in the nature. It increases when `Self` is
/// cloned, and it decreases when `Self` is dropped. /// cloned, and it decreases when `Self` is dropped.
strong: Arc<atomic::AtomicUsize>, strong: Arc<atomic::AtomicUsize>,
@@ -739,7 +739,7 @@ pub struct InstanceAllocator {
instance_layout: Layout, instance_layout: Layout,
/// The `Instance` itself. It must be the last field of /// The `Instance` itself. It must be the last field of
/// `InstanceAllocator` since `Instance` is dyamically-sized. /// `InstanceRef` since `Instance` is dyamically-sized.
/// ///
/// `Instance` must not be dropped manually by Rust, because it's /// `Instance` must not be dropped manually by Rust, because it's
/// allocated manually with `alloc` and a specific layout (Rust /// allocated manually with `alloc` and a specific layout (Rust
@@ -751,8 +751,8 @@ pub struct InstanceAllocator {
instance: NonNull<Instance>, instance: NonNull<Instance>,
} }
impl InstanceAllocator { impl InstanceRef {
/// Create a new `InstanceAllocator`. It allocates nothing. It /// Create a new `InstanceRef`. It allocates nothing. It
/// fills nothing. The `Instance` must be already valid and /// fills nothing. The `Instance` must be already valid and
/// filled. `self_ptr` and `self_layout` must be the pointer and /// filled. `self_ptr` and `self_layout` must be the pointer and
/// the layout returned by `Self::allocate_self` used to build /// the layout returned by `Self::allocate_self` used to build
@@ -762,7 +762,7 @@ impl InstanceAllocator {
/// ///
/// `instance` must a non-null, non-dangling, properly aligned, /// `instance` must a non-null, non-dangling, properly aligned,
/// and correctly initialized pointer to `Instance`. See /// and correctly initialized pointer to `Instance`. See
/// [`InstanceBuilder::new`] for an example of how to correctly use /// [`InstanceAllocator::new`] for an example of how to correctly use
/// this API. /// this API.
/// TODO: update docs /// TODO: update docs
pub(crate) unsafe fn new(instance: NonNull<Instance>, instance_layout: Layout) -> Self { pub(crate) unsafe fn new(instance: NonNull<Instance>, instance_layout: Layout) -> Self {
@@ -773,7 +773,7 @@ impl InstanceAllocator {
} }
} }
/// A soft limit on the amount of references that may be made to an `InstanceAllocator`. /// A soft limit on the amount of references that may be made to an `InstanceRef`.
/// ///
/// Going above this limit will make the program to panic at exactly /// Going above this limit will make the program to panic at exactly
/// `MAX_REFCOUNT` references. /// `MAX_REFCOUNT` references.
@@ -793,7 +793,7 @@ impl InstanceAllocator {
} }
/// Get the number of strong references pointing to this /// Get the number of strong references pointing to this
/// `InstanceAllocator`. /// `InstanceRef`.
pub fn strong_count(&self) -> usize { pub fn strong_count(&self) -> usize {
self.strong.load(atomic::Ordering::SeqCst) self.strong.load(atomic::Ordering::SeqCst)
} }
@@ -814,13 +814,13 @@ impl InstanceAllocator {
} }
/// TODO: Review this super carefully. /// TODO: Review this super carefully.
unsafe impl Send for InstanceAllocator {} unsafe impl Send for InstanceRef {}
unsafe impl Sync for InstanceAllocator {} unsafe impl Sync for InstanceRef {}
impl Clone for InstanceAllocator { impl Clone for InstanceRef {
/// Makes a clone of `InstanceAllocator`. /// Makes a clone of `InstanceRef`.
/// ///
/// This creates another `InstanceAllocator` using the same /// This creates another `InstanceRef` using the same
/// `instance` pointer, increasing the strong reference count. /// `instance` pointer, increasing the strong reference count.
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@@ -840,7 +840,7 @@ impl Clone for InstanceAllocator {
let old_size = self.strong.fetch_add(1, atomic::Ordering::Relaxed); let old_size = self.strong.fetch_add(1, atomic::Ordering::Relaxed);
// However we need to guard against massive refcounts in case // However we need to guard against massive refcounts in case
// someone is `mem::forget`ing `InstanceAllocator`. If we // someone is `mem::forget`ing `InstanceRef`. If we
// don't do this the count can overflow and users will // don't do this the count can overflow and users will
// use-after free. We racily saturate to `isize::MAX` on the // use-after free. We racily saturate to `isize::MAX` on the
// assumption that there aren't ~2 billion threads // assumption that there aren't ~2 billion threads
@@ -851,7 +851,7 @@ impl Clone for InstanceAllocator {
// and we don't care to support it. // and we don't care to support it.
if old_size > Self::MAX_REFCOUNT { if old_size > Self::MAX_REFCOUNT {
panic!("Too many references of `InstanceAllocator`"); panic!("Too many references of `InstanceRef`");
} }
Self { Self {
@@ -862,16 +862,16 @@ impl Clone for InstanceAllocator {
} }
} }
impl PartialEq for InstanceAllocator { impl PartialEq for InstanceRef {
/// Two `InstanceAllocator` are equal if and only if /// Two `InstanceRef` are equal if and only if
/// `Self.instance` points to the same location. /// `Self.instance` points to the same location.
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.instance == other.instance self.instance == other.instance
} }
} }
impl Drop for InstanceAllocator { impl Drop for InstanceRef {
/// Drop the `InstanceAllocator`. /// Drop the `InstanceRef`.
/// ///
/// This will decrement the strong reference count. If it reaches /// This will decrement the strong reference count. If it reaches
/// 1, then the `Self.instance` will be deallocated with /// 1, then the `Self.instance` will be deallocated with
@@ -905,24 +905,24 @@ impl Drop for InstanceAllocator {
// Now we can deallocate the instance. Note that we don't // Now we can deallocate the instance. Note that we don't
// check the pointer to `Instance` is correctly initialized, // check the pointer to `Instance` is correctly initialized,
// but the way `InstanceHandle` creates the // but the way `InstanceHandle` creates the
// `InstanceAllocator` ensures that. // `InstanceRef` ensures that.
unsafe { Self::deallocate_instance(self) }; unsafe { Self::deallocate_instance(self) };
} }
} }
/// A handle holding an `InstanceAllocator`, which holds an `Instance` /// A handle holding an `InstanceRef`, which holds an `Instance`
/// of a WebAssembly module. /// of a WebAssembly module.
/// ///
/// This is more or less a public facade of the private `Instance`, /// This is more or less a public facade of the private `Instance`,
/// providing useful higher-level API. /// providing useful higher-level API.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct InstanceHandle { pub struct InstanceHandle {
/// The `InstanceAllocator`. See its documentation to learn more. /// The `InstanceRef`. See its documentation to learn more.
instance: InstanceAllocator, instance: InstanceRef,
} }
impl InstanceHandle { impl InstanceHandle {
/// Create a new `InstanceHandle` pointing at a new `InstanceAllocator`. /// Create a new `InstanceHandle` pointing at a new `InstanceRef`.
/// ///
/// # Safety /// # Safety
/// ///
@@ -945,7 +945,7 @@ impl InstanceHandle {
/// all the local memories. /// all the local memories.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub unsafe fn new( pub unsafe fn new(
unprepared: InstanceBuilder, allocator: InstanceAllocator,
module: Arc<ModuleInfo>, module: Arc<ModuleInfo>,
finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>, finished_functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,
finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>, finished_function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,
@@ -965,7 +965,7 @@ impl InstanceHandle {
let passive_data = RefCell::new(module.passive_data.clone()); let passive_data = RefCell::new(module.passive_data.clone());
let handle = { let handle = {
let offsets = unprepared.offsets().clone(); let offsets = allocator.offsets().clone();
// Create the `Instance`. The unique, the One. // Create the `Instance`. The unique, the One.
let instance = Instance { let instance = Instance {
module, module,
@@ -983,7 +983,7 @@ impl InstanceHandle {
vmctx: VMContext {}, vmctx: VMContext {},
}; };
let instance_allocator = unprepared.write_instance(instance); let instance_allocator = allocator.write_instance(instance);
Self { Self {
instance: instance_allocator, instance: instance_allocator,
@@ -1041,7 +1041,7 @@ impl InstanceHandle {
} }
/// Return a reference to the contained `Instance`. /// Return a reference to the contained `Instance`.
pub(crate) fn instance(&self) -> &InstanceAllocator { pub(crate) fn instance(&self) -> &InstanceRef {
&self.instance &self.instance
} }

View File

@@ -39,7 +39,7 @@ pub mod libcalls;
pub use crate::export::*; pub use crate::export::*;
pub use crate::global::*; pub use crate::global::*;
pub use crate::imports::Imports; pub use crate::imports::Imports;
pub use crate::instance::{ImportInitializerFuncPtr, InstanceBuilder, InstanceHandle}; pub use crate::instance::{ImportInitializerFuncPtr, InstanceAllocator, InstanceHandle};
pub use crate::memory::{LinearMemory, Memory, MemoryError, MemoryStyle}; pub use crate::memory::{LinearMemory, Memory, MemoryError, MemoryStyle};
pub use crate::mmap::Mmap; pub use crate::mmap::Mmap;
pub use crate::module::{ExportsIterator, ImportsIterator, ModuleInfo}; pub use crate::module::{ExportsIterator, ImportsIterator, ModuleInfo};