diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b2fa3b4cf6..7b922670793 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - [#2135](https://github.com/wasmerio/wasmer/pull/2135) [Documentation](./PACKAGING.md) for linux distribution maintainers ### Changed +- [#2201](https://github.com/wasmerio/wasmer/pull/2201) Implement `loupe::MemoryUsage` for `wasmer::Instance`. - [#2200](https://github.com/wasmerio/wasmer/pull/2200) Implement `loupe::MemoryUsage` for `wasmer::Module`. - [#2199](https://github.com/wasmerio/wasmer/pull/2199) Implement `loupe::MemoryUsage` for `wasmer::Store`. - [#2140](https://github.com/wasmerio/wasmer/pull/2140) Reduce the number of dependencies in the `wasmer.dll` shared library by statically compiling CRT. diff --git a/examples/hello_world.rs b/examples/hello_world.rs index dbe559226e3..55142db1c14 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -45,6 +45,7 @@ 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()); + // 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)?; @@ -71,6 +72,7 @@ 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)?; + // 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 diff --git a/lib/api/src/exports.rs b/lib/api/src/exports.rs index 606a052e52a..4bfea97ede7 100644 --- a/lib/api/src/exports.rs +++ b/lib/api/src/exports.rs @@ -3,6 +3,7 @@ use crate::import_object::LikeNamespace; use crate::native::NativeFunc; use crate::WasmTypeList; use indexmap::IndexMap; +use loupe::MemoryUsage; use std::fmt; use std::iter::{ExactSizeIterator, FromIterator}; use std::sync::Arc; @@ -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>, } diff --git a/lib/api/src/externals/function.rs b/lib/api/src/externals/function.rs index f925852af5c..a396c1ca2c2 100644 --- a/lib/api/src/externals/function.rs +++ b/lib/api/src/externals/function.rs @@ -10,6 +10,7 @@ pub use inner::{FromToNativeWasmType, HostFunction, WasmTypeList, WithEnv, Witho #[cfg(feature = "deprecated")] pub use inner::{UnsafeMutableEnv, WithUnsafeMutableEnv}; +use loupe::MemoryUsage; use std::cmp::max; use std::ffi::c_void; use std::fmt; @@ -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. + #[loupe(skip)] 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), @@ -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, diff --git a/lib/api/src/externals/global.rs b/lib/api/src/externals/global.rs index 49f2a4c1234..4f85aba5db6 100644 --- a/lib/api/src/externals/global.rs +++ b/lib/api/src/externals/global.rs @@ -5,6 +5,7 @@ use crate::types::Val; use crate::GlobalType; use crate::Mutability; use crate::RuntimeError; +use loupe::MemoryUsage; use std::fmt; use std::sync::Arc; use wasmer_engine::{Export, ExportGlobal}; @@ -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: -#[derive(Clone)] +#[derive(Clone, MemoryUsage)] pub struct Global { store: Store, global: Arc, diff --git a/lib/api/src/externals/memory.rs b/lib/api/src/externals/memory.rs index 423345a27a3..8cfe9f876b3 100644 --- a/lib/api/src/externals/memory.rs +++ b/lib/api/src/externals/memory.rs @@ -2,6 +2,7 @@ use crate::exports::{ExportError, Exportable}; use crate::externals::Extern; use crate::store::Store; use crate::{MemoryType, MemoryView}; +use loupe::MemoryUsage; use std::convert::TryInto; use std::slice; use std::sync::Arc; @@ -23,7 +24,7 @@ use wasmer_vm::{Memory as RuntimeMemory, MemoryError, VMExportMemory}; /// mutable from both host and WebAssembly. /// /// Spec: -#[derive(Debug, Clone)] +#[derive(Debug, Clone, MemoryUsage)] pub struct Memory { store: Store, memory: Arc, diff --git a/lib/api/src/externals/mod.rs b/lib/api/src/externals/mod.rs index c8f15e3c16b..ead70f2ec15 100644 --- a/lib/api/src/externals/mod.rs +++ b/lib/api/src/externals/mod.rs @@ -16,6 +16,7 @@ pub use self::table::Table; use crate::exports::{ExportError, Exportable}; use crate::store::{Store, StoreObject}; use crate::ExternType; +use loupe::MemoryUsage; use std::fmt; use wasmer_engine::Export; @@ -23,7 +24,7 @@ use wasmer_engine::Export; /// can be imported or exported. /// /// Spec: -#[derive(Clone)] +#[derive(Clone, MemoryUsage)] pub enum Extern { /// A external [`Function`]. Function(Function), diff --git a/lib/api/src/externals/table.rs b/lib/api/src/externals/table.rs index 8e2f43696dc..6423c6cd933 100644 --- a/lib/api/src/externals/table.rs +++ b/lib/api/src/externals/table.rs @@ -4,6 +4,7 @@ use crate::store::Store; use crate::types::{Val, ValFuncRef}; use crate::RuntimeError; use crate::TableType; +use loupe::MemoryUsage; use std::sync::Arc; use wasmer_engine::{Export, ExportTable}; use wasmer_vm::{Table as RuntimeTable, VMCallerCheckedAnyfunc, VMExportTable}; @@ -17,7 +18,7 @@ use wasmer_vm::{Table as RuntimeTable, VMCallerCheckedAnyfunc, VMExportTable}; /// mutable from both host and WebAssembly. /// /// Spec: -#[derive(Clone)] +#[derive(Clone, MemoryUsage)] pub struct Table { store: Store, table: Arc, diff --git a/lib/api/src/instance.rs b/lib/api/src/instance.rs index 93c0b42fe49..592fd2eeca9 100644 --- a/lib/api/src/instance.rs +++ b/lib/api/src/instance.rs @@ -3,6 +3,7 @@ use crate::externals::Extern; use crate::module::Module; use crate::store::Store; use crate::{HostEnvInitError, LinkError, RuntimeError}; +use loupe::MemoryUsage; use std::fmt; use std::sync::{Arc, Mutex}; use thiserror::Error; @@ -17,7 +18,7 @@ use wasmer_vm::{InstanceHandle, VMContext}; /// interacting with WebAssembly. /// /// Spec: -#[derive(Clone)] +#[derive(Clone, MemoryUsage)] pub struct Instance { handle: Arc>, module: Module, diff --git a/lib/engine/src/export.rs b/lib/engine/src/export.rs index e3342265abf..d0014eb8c2c 100644 --- a/lib/engine/src/export.rs +++ b/lib/engine/src/export.rs @@ -1,10 +1,10 @@ +use loupe::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 { @@ -54,7 +54,7 @@ impl From 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`. /// @@ -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 + #[loupe(skip)] pub(crate) import_init_function_ptr: Option, + /// A function analogous to `Clone::clone` that returns a leaked `Box`. + #[loupe(skip)] 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. + #[loupe(skip)] pub(crate) host_env_drop_fn: unsafe fn(*mut std::ffi::c_void), } @@ -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, diff --git a/lib/vm/src/export.rs b/lib/vm/src/export.rs index e5d3475ea10..806178ab47f 100644 --- a/lib/vm/src/export.rs +++ b/lib/vm/src/export.rs @@ -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::MemoryUsage; use std::sync::Arc; use wasmer_types::{FunctionType, MemoryType, TableType}; @@ -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, @@ -46,6 +47,7 @@ pub struct VMExportFunction { /// /// May be `None` when the function is a host function (`FunctionType` /// == `Dynamic` or `vmctx` == `nullptr`). + #[loupe(skip)] pub call_trampoline: Option, /// A “reference” to the instance through the diff --git a/lib/vm/src/instance/mod.rs b/lib/vm/src/instance/mod.rs index 986ee9d5156..c0b4ae7a0a2 100644 --- a/lib/vm/src/instance/mod.rs +++ b/lib/vm/src/instance/mod.rs @@ -57,6 +57,7 @@ pub type ImportInitializerFuncPtr = /// 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. @@ -78,6 +79,7 @@ pub(crate) struct Instance { functions: BoxedSlice, /// Pointers to function call trampolines in executable memory. + #[loupe(skip)] function_call_trampolines: BoxedSlice, /// Passive elements in this instantiation. As `elem.drop`s happen, these @@ -92,6 +94,7 @@ pub(crate) struct Instance { host_state: Box, /// Handler run when `SIGBUS`, `SIGFPE`, `SIGILL`, or `SIGSEGV` are caught by the instance thread. + #[loupe(skip)] pub(crate) signal_handler: Cell>>, /// Functions to operate on host environments in the imports @@ -105,6 +108,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). + #[loupe(skip)] vmctx: VMContext, } @@ -785,7 +789,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, diff --git a/lib/vm/src/instance/ref.rs b/lib/vm/src/instance/ref.rs index c9081bba6cb..77daeddc634 100644 --- a/lib/vm/src/instance/ref.rs +++ b/lib/vm/src/instance/ref.rs @@ -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}; @@ -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) + } +} diff --git a/lib/vm/src/vmcontext.rs b/lib/vm/src/vmcontext.rs index 9479f8121bd..65657e23fde 100644 --- a/lib/vm/src/vmcontext.rs +++ b/lib/vm/src/vmcontext.rs @@ -175,7 +175,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: diff --git a/lib/vm/src/vmoffsets.rs b/lib/vm/src/vmoffsets.rs index a786114705a..6a6fa5b26fb 100644 --- a/lib/vm/src/vmoffsets.rs +++ b/lib/vm/src/vmoffsets.rs @@ -8,6 +8,7 @@ use crate::module::ModuleInfo; use crate::VMBuiltinFunctionIndex; +use loupe::MemoryUsage; use more_asserts::assert_lt; use std::convert::TryFrom; use wasmer_types::{ @@ -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,