Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement MemoryUsage for Instance #2201

Merged
merged 8 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ criterion = "0.3"
lazy_static = "1.4"
wasmer-engine-dummy = { path = "tests/lib/engine-dummy" }
tempfile = "3.1"
loupe = "0.1"

[features]
# Don't add the compiler features in default, please add them on the Makefile
Expand Down
2 changes: 2 additions & 0 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand All @@ -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
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::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::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.
#[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),
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::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::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::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::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::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::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
#[loupe(skip)]
pub(crate) import_init_function_ptr: Option<ImportInitializerFuncPtr>,

/// 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),
}

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::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`).
#[loupe(skip)]
pub call_trampoline: Option<VMTrampoline>,

/// A “reference” to the instance through the
Expand Down
6 changes: 5 additions & 1 deletion lib/vm/src/instance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,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 +79,7 @@ pub(crate) struct Instance {
functions: BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>,

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

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

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

/// Functions to operate on host environments in the imports
Expand All @@ -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,
}

Expand Down Expand Up @@ -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,
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)
Hywan marked this conversation as resolved.
Show resolved Hide resolved
}
}
2 changes: 1 addition & 1 deletion lib/vm/src/vmcontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
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::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