Skip to content

Commit

Permalink
feat: Implement MemoryUsage for Instance.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hywan committed Mar 19, 2021
1 parent 170850b commit 6a8fa5d
Show file tree
Hide file tree
Showing 16 changed files with 64 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ wasmer-cache = { version = "1.0.2", path = "lib/cache", optional = true }
wasmer-types = { version = "1.0.2", path = "lib/wasmer-types" }
wasmer-middlewares = { version = "1.0.2", path = "lib/middlewares", optional = true }
cfg-if = "1.0"
loupe = { path = "../loupe/crates/loupe" }

[workspace]
members = [
Expand Down
10 changes: 10 additions & 0 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//! cargo run --example hello-world --release --features "cranelift"
//! ```
use loupe::size_of_val;
use wasmer::{imports, wat2wasm, Function, Instance, Module, NativeFunc, Store};
use wasmer_compiler_cranelift::Cranelift;
use wasmer_engine_jit::JIT;
Expand Down Expand Up @@ -45,10 +46,15 @@ fn main() -> anyhow::Result<()> {
// (`Cranelift`) and pass it to an engine (`JIT`). We then pass the engine to
// the store and are now ready to compile and run WebAssembly!
let store = Store::new(&JIT::new(Cranelift::default()).engine());
dbg!(size_of_val(&store));

// We then use our store and Wasm bytes to compile a `Module`.
// A `Module` is a compiled WebAssembly module that isn't ready to execute yet.
let module = Module::new(&store, wasm_bytes)?;

dbg!(size_of_val(&store));
dbg!(size_of_val(&module));

// Next we'll set up our `Module` so that we can execute it.

// We define a function to act as our "env" "say_hello" function imported in the
Expand All @@ -71,6 +77,10 @@ fn main() -> anyhow::Result<()> {
// An `Instance` is a compiled WebAssembly module that has been set up
// and is ready to execute.
let instance = Instance::new(&module, &import_object)?;

dbg!(size_of_val(&instance));
dbg!(&instance.exports);

// We get the `NativeFunc` with no parameters and no results from the instance.
//
// Recall that the Wasm module exported a function named "run", this is getting
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::import_object::LikeNamespace;
use crate::native::NativeFunc;
use crate::WasmTypeList;
use indexmap::IndexMap;
use loupe_derive::MemoryUsage;
use std::fmt;
use std::iter::{ExactSizeIterator, FromIterator};
use std::sync::Arc;
Expand Down Expand Up @@ -61,7 +62,7 @@ pub enum ExportError {
/// the types of instances.
///
/// TODO: add examples of using exports
#[derive(Clone, Default)]
#[derive(Clone, Default, MemoryUsage)]
pub struct Exports {
map: Arc<IndexMap<String, Extern>>,
}
Expand Down
10 changes: 6 additions & 4 deletions lib/api/src/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub use inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, Witho
#[cfg(feature = "deprecated")]
pub use inner::{UnsafeMutableEnv, WithUnsafeMutableEnv};

use loupe_derive::MemoryUsage;
use std::cmp::max;
use std::ffi::c_void;
use std::fmt;
Expand All @@ -22,21 +23,22 @@ use wasmer_vm::{
};

/// A function defined in the Wasm module
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, MemoryUsage)]
pub struct WasmFunctionDefinition {
// Address of the trampoline to do the call.
#[memoryusage(ignore)]
pub(crate) trampoline: VMTrampoline,
}

/// A function defined in the Host
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, MemoryUsage)]
pub struct HostFunctionDefinition {
/// If the host function has a custom environment attached
pub(crate) has_env: bool,
}

/// The inner helper
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, MemoryUsage)]
pub enum FunctionDefinition {
/// A function defined in the Wasm side
Wasm(WasmFunctionDefinition),
Expand All @@ -61,7 +63,7 @@ pub enum FunctionDefinition {
/// with native functions. Attempting to create a native `Function` with one will
/// result in a panic.
/// [Closures as host functions tracking issue](https://github.com/wasmerio/wasmer/issues/1840)
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, MemoryUsage)]
pub struct Function {
pub(crate) store: Store,
pub(crate) definition: FunctionDefinition,
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/externals/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::types::Val;
use crate::GlobalType;
use crate::Mutability;
use crate::RuntimeError;
use loupe_derive::MemoryUsage;
use std::fmt;
use std::sync::Arc;
use wasmer_engine::{Export, ExportGlobal};
Expand All @@ -16,7 +17,7 @@ use wasmer_vm::{Global as RuntimeGlobal, VMExportGlobal};
/// It consists of an individual value and a flag indicating whether it is mutable.
///
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#global-instances>
#[derive(Clone)]
#[derive(Clone, MemoryUsage)]
pub struct Global {
store: Store,
global: Arc<RuntimeGlobal>,
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::exports::{ExportError, Exportable};
use crate::externals::Extern;
use crate::store::Store;
use crate::{MemoryType, MemoryView};
use loupe_derive::MemoryUsage;
use std::convert::TryInto;
use std::slice;
use std::sync::Arc;
Expand All @@ -23,7 +24,7 @@ use wasmer_vm::{Memory as RuntimeMemory, MemoryError, VMExportMemory};
/// mutable from both host and WebAssembly.
///
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances>
#[derive(Debug, Clone)]
#[derive(Debug, Clone, MemoryUsage)]
pub struct Memory {
store: Store,
memory: Arc<dyn RuntimeMemory>,
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/externals/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ pub use self::table::Table;
use crate::exports::{ExportError, Exportable};
use crate::store::{Store, StoreObject};
use crate::ExternType;
use loupe_derive::MemoryUsage;
use std::fmt;
use wasmer_engine::Export;

/// An `Extern` is the runtime representation of an entity that
/// can be imported or exported.
///
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#external-values>
#[derive(Clone)]
#[derive(Clone, MemoryUsage)]
pub enum Extern {
/// A external [`Function`].
Function(Function),
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/externals/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::store::Store;
use crate::types::{Val, ValFuncRef};
use crate::RuntimeError;
use crate::TableType;
use loupe_derive::MemoryUsage;
use std::sync::Arc;
use wasmer_engine::{Export, ExportTable};
use wasmer_vm::{Table as RuntimeTable, VMCallerCheckedAnyfunc, VMExportTable};
Expand All @@ -17,7 +18,7 @@ use wasmer_vm::{Table as RuntimeTable, VMCallerCheckedAnyfunc, VMExportTable};
/// mutable from both host and WebAssembly.
///
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#table-instances>
#[derive(Clone)]
#[derive(Clone, MemoryUsage)]
pub struct Table {
store: Store,
table: Arc<dyn RuntimeTable>,
Expand Down
3 changes: 2 additions & 1 deletion lib/api/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::externals::Extern;
use crate::module::Module;
use crate::store::Store;
use crate::{HostEnvInitError, LinkError, RuntimeError};
use loupe_derive::MemoryUsage;
use std::fmt;
use std::sync::{Arc, Mutex};
use thiserror::Error;
Expand All @@ -17,7 +18,7 @@ use wasmer_vm::{InstanceHandle, VMContext};
/// interacting with WebAssembly.
///
/// Spec: <https://webassembly.github.io/spec/core/exec/runtime.html#module-instances>
#[derive(Clone)]
#[derive(Clone, MemoryUsage)]
pub struct Instance {
handle: Arc<Mutex<InstanceHandle>>,
module: Module,
Expand Down
14 changes: 10 additions & 4 deletions lib/engine/src/export.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use loupe_derive::MemoryUsage;
use std::sync::Arc;
use wasmer_vm::{
ImportInitializerFuncPtr, VMExport, VMExportFunction, VMExportGlobal, VMExportMemory,
VMExportTable,
};

use std::sync::Arc;

/// The value of an export passed from one instance to another.
#[derive(Debug, Clone)]
pub enum Export {
Expand Down Expand Up @@ -54,7 +54,7 @@ impl From<VMExport> for Export {
///
/// This struct owns the original `host_env`, thus when it gets dropped
/// it calls the `drop` function on it.
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, MemoryUsage)]
pub struct ExportFunctionMetadata {
/// This field is stored here to be accessible by `Drop`.
///
Expand All @@ -69,20 +69,26 @@ pub struct ExportFunctionMetadata {
/// See `wasmer_vm::export::VMExportFunction::vmctx` for the version of
/// this pointer that is used by the VM when creating an `Instance`.
pub(crate) host_env: *mut std::ffi::c_void,

/// Function pointer to `WasmerEnv::init_with_instance(&mut self, instance: &Instance)`.
///
/// This function is called to finish setting up the environment after
/// we create the `api::Instance`.
// This one is optional for now because dynamic host envs need the rest
// of this without the init fn
#[memoryusage(ignore)]
pub(crate) import_init_function_ptr: Option<ImportInitializerFuncPtr>,

/// A function analogous to `Clone::clone` that returns a leaked `Box`.
#[memoryusage(ignore)]
pub(crate) host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void,

/// The destructor to free the host environment.
///
/// # Safety
/// - This function should only be called in when properly synchronized.
/// For example, in the `Drop` implementation of this type.
#[memoryusage(ignore)]
pub(crate) host_env_drop_fn: unsafe fn(*mut std::ffi::c_void),
}

Expand Down Expand Up @@ -132,7 +138,7 @@ impl Drop for ExportFunctionMetadata {

/// A function export value with an extra function pointer to initialize
/// host environments.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, MemoryUsage)]
pub struct ExportFunction {
/// The VM function, containing most of the data.
pub vm_function: VMExportFunction,
Expand Down
4 changes: 3 additions & 1 deletion lib/vm/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::instance::InstanceRef;
use crate::memory::{Memory, MemoryStyle};
use crate::table::{Table, TableStyle};
use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline};
use loupe_derive::MemoryUsage;
use std::sync::Arc;
use wasmer_types::{FunctionType, MemoryType, TableType};

Expand All @@ -26,7 +27,7 @@ pub enum VMExport {
}

/// A function export value.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, MemoryUsage)]
pub struct VMExportFunction {
/// The address of the native-code function.
pub address: *const VMFunctionBody,
Expand All @@ -46,6 +47,7 @@ pub struct VMExportFunction {
///
/// May be `None` when the function is a host function (`FunctionType`
/// == `Dynamic` or `vmctx` == `nullptr`).
#[memoryusage(ignore)]
pub call_trampoline: Option<VMTrampoline>,

/// A “reference” to the instance through the
Expand Down
7 changes: 6 additions & 1 deletion lib/vm/src/instance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::vmcontext::{
use crate::{FunctionBodyPtr, ModuleInfo, VMOffsets};
use crate::{VMExportFunction, VMExportGlobal, VMExportMemory, VMExportTable};
use loupe::{MemoryUsage, MemoryUsageTracker};
use loupe_derive::MemoryUsage;
use memoffset::offset_of;
use more_asserts::assert_lt;
use std::any::Any;
Expand Down Expand Up @@ -57,6 +58,7 @@ pub type ImportInitializerFuncPtr<ResultErr = *mut ffi::c_void> =
/// contain various data. That's why the type has a C representation
/// to ensure that the `vmctx` field is last. See the documentation of
/// the `vmctx` field to learn more.
#[derive(MemoryUsage)]
#[repr(C)]
pub(crate) struct Instance {
/// The `ModuleInfo` this `Instance` was instantiated from.
Expand All @@ -78,6 +80,7 @@ pub(crate) struct Instance {
functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,

/// Pointers to function call trampolines in executable memory.
#[memoryusage(ignore)]
function_call_trampolines: BoxedSlice<SignatureIndex, VMTrampoline>,

/// Passive elements in this instantiation. As `elem.drop`s happen, these
Expand All @@ -92,6 +95,7 @@ pub(crate) struct Instance {
host_state: Box<dyn Any>,

/// Handler run when `SIGBUS`, `SIGFPE`, `SIGILL`, or `SIGSEGV` are caught by the instance thread.
#[memoryusage(ignore)]
pub(crate) signal_handler: Cell<Option<Box<SignalHandler>>>,

/// Functions to operate on host environments in the imports
Expand All @@ -105,6 +109,7 @@ pub(crate) struct Instance {
/// field is last, and represents a dynamically-sized array that
/// extends beyond the nominal end of the struct (similar to a
/// flexible array member).
#[memoryusage(ignore)]
vmctx: VMContext,
}

Expand Down Expand Up @@ -785,7 +790,7 @@ impl Instance {
///
/// This is more or less a public facade of the private `Instance`,
/// providing useful higher-level API.
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, MemoryUsage)]
pub struct InstanceHandle {
/// The [`InstanceRef`]. See its documentation to learn more.
instance: InstanceRef,
Expand Down
12 changes: 12 additions & 0 deletions lib/vm/src/instance/ref.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use super::Instance;
use loupe::{MemoryUsage, MemoryUsageTracker};
use std::alloc::Layout;
use std::mem;
use std::ptr::{self, NonNull};
use std::sync::{atomic, Arc};

Expand Down Expand Up @@ -208,3 +210,13 @@ impl Drop for InstanceRef {
unsafe { Self::deallocate_instance(self) };
}
}

impl MemoryUsage for InstanceRef {
fn size_of_val(&self, tracker: &mut dyn MemoryUsageTracker) -> usize {
mem::size_of_val(self) + self.strong.size_of_val(tracker) - mem::size_of_val(&self.strong)
+ self.instance_layout.size_of_val(tracker)
- mem::size_of_val(&self.instance_layout)
+ self.as_ref().size_of_val(tracker)
- mem::size_of_val(&self.instance)
}
}
2 changes: 1 addition & 1 deletion lib/vm/src/vmcontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ mod test_vmfunction_body {
}

/// A function kind is a calling convention into and out of wasm code.
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, MemoryUsage)]
#[repr(C)]
pub enum VMFunctionKind {
/// A static function has the native signature:
Expand Down
3 changes: 2 additions & 1 deletion lib/vm/src/vmoffsets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use crate::module::ModuleInfo;
use crate::VMBuiltinFunctionIndex;
use loupe_derive::MemoryUsage;
use more_asserts::assert_lt;
use std::convert::TryFrom;
use wasmer_types::{
Expand All @@ -33,7 +34,7 @@ const fn align(offset: u32, width: u32) -> u32 {
/// related structs that JIT code accesses directly.
///
/// [`VMContext`]: crate::vmcontext::VMContext
#[derive(Clone, Debug)]
#[derive(Clone, Debug, MemoryUsage)]
pub struct VMOffsets {
/// The size in bytes of a pointer on the target.
pub pointer_size: u8,
Expand Down

0 comments on commit 6a8fa5d

Please sign in to comment.