diff --git a/Cargo.lock b/Cargo.lock index 275ca45fd7a..65725cf9991 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2856,6 +2856,27 @@ dependencies = [ "logos-codegen", ] +[[package]] +name = "loupe" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" +dependencies = [ + "indexmap 1.9.3", + "loupe-derive", + "rustversion", +] + +[[package]] +name = "loupe-derive" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "lz4_flex" version = "0.11.3" @@ -6396,6 +6417,7 @@ dependencies = [ "hashbrown 0.11.2", "indexmap 1.9.3", "js-sys", + "loupe", "macro-wasmer-universal-test", "more-asserts", "rustc-demangle", @@ -6667,6 +6689,7 @@ dependencies = [ "lazy_static", "leb128", "libc", + "loupe", "memmap2 0.6.2", "more-asserts", "region", @@ -7026,6 +7049,7 @@ dependencies = [ "getrandom", "hex", "indexmap 1.9.3", + "loupe", "memoffset 0.9.1", "more-asserts", "rkyv", @@ -7053,6 +7077,7 @@ dependencies = [ "indexmap 1.9.3", "lazy_static", "libc", + "loupe", "mach2", "memoffset 0.9.1", "more-asserts", diff --git a/lib/api/Cargo.toml b/lib/api/Cargo.toml index 5eeb1685e66..a0b2b515180 100644 --- a/lib/api/Cargo.toml +++ b/lib/api/Cargo.toml @@ -35,6 +35,10 @@ tracing = { version = "0.1" } wat = { version = "=1.0.71", optional = true } rustc-demangle = "0.1" shared-buffer = { workspace = true } +loupe = { version = "0.1.3", optional = true, features = [ + "indexmap", + "enable-indexmap", +] } # Dependencies and Development Dependencies for `sys`. [target.'cfg(not(target_arch = "wasm32"))'.dependencies] @@ -67,7 +71,9 @@ macro-wasmer-universal-test = { version = "4.3.7", path = "./macro-wasmer-univer # Dependencies and Develoment Dependencies for `js`. [target.'cfg(target_arch = "wasm32")'.dependencies] # - Mandatory dependencies for `js`. -wasmer-types = { path = "../types", version = "=4.3.7", default-features = false, features = ["std"] } +wasmer-types = { path = "../types", version = "=4.3.7", default-features = false, features = [ + "std", +] } wasm-bindgen = "0.2.74" js-sys = "0.3.51" wasmer-derive = { path = "../derive", version = "=4.3.7" } @@ -99,6 +105,11 @@ default = ["sys-default"] # default = ["js-default"] std = [] core = ["hashbrown"] +artifact-size = [ + "dep:loupe", + "wasmer-vm/artifact-size", + "wasmer-compiler/artifact-size", +] # Features for `sys`. sys = ["wasmer-compiler/translator", "wasmer-compiler/compiler", "std"] @@ -125,9 +136,9 @@ js-serializable-module = [] # Optional enable-serde = [ - "wasmer-vm/enable-serde", - "wasmer-compiler/enable-serde", - "wasmer-types/enable-serde", + "wasmer-vm/enable-serde", + "wasmer-compiler/enable-serde", + "wasmer-types/enable-serde", ] wasmer-artifact-load = ["wasmer-compiler/wasmer-artifact-load"] @@ -137,17 +148,17 @@ static-artifact-create = ["wasmer-compiler/static-artifact-create"] [package.metadata.docs.rs] features = [ - "compiler", - "core", - "cranelift", - "engine", - "jit", - "singlepass", - "static-artifact-create", - "static-artifact-load", - "sys", - "sys-default", - "wasmer-artifact-create", - "wasmer-artifact-load", + "compiler", + "core", + "cranelift", + "engine", + "jit", + "singlepass", + "static-artifact-create", + "static-artifact-load", + "sys", + "sys-default", + "wasmer-artifact-create", + "wasmer-artifact-load", ] rustc-args = ["--cfg", "docsrs"] diff --git a/lib/api/src/exports.rs b/lib/api/src/exports.rs index d2f821145f2..b242ff81336 100644 --- a/lib/api/src/exports.rs +++ b/lib/api/src/exports.rs @@ -58,6 +58,7 @@ pub enum ExportError { /// /// TODO: add examples of using exports #[derive(Clone, Default, PartialEq, Eq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Exports { map: IndexMap, } diff --git a/lib/api/src/externals/function.rs b/lib/api/src/externals/function.rs index 70d18c3ca48..b351b3f545d 100644 --- a/lib/api/src/externals/function.rs +++ b/lib/api/src/externals/function.rs @@ -84,6 +84,7 @@ mod private { /// result in a panic. /// [Closures as host functions tracking issue](https://github.com/wasmerio/wasmer/issues/1840) #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Function(pub(crate) function_impl::Function); impl Function { diff --git a/lib/api/src/externals/global.rs b/lib/api/src/externals/global.rs index 3420562ff46..5021fbf09e0 100644 --- a/lib/api/src/externals/global.rs +++ b/lib/api/src/externals/global.rs @@ -22,6 +22,7 @@ use crate::sys::externals::global as global_impl; /// /// Spec: #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Global(pub(crate) global_impl::Global); impl Global { diff --git a/lib/api/src/externals/memory.rs b/lib/api/src/externals/memory.rs index 3e2b07efa22..5c53b81d54c 100644 --- a/lib/api/src/externals/memory.rs +++ b/lib/api/src/externals/memory.rs @@ -30,6 +30,7 @@ use wasmer_types::{MemoryError, Pages}; /// /// Spec: #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Memory(pub(crate) memory_impl::Memory); impl Memory { diff --git a/lib/api/src/externals/mod.rs b/lib/api/src/externals/mod.rs index c5b46e8972c..462c928c5d3 100644 --- a/lib/api/src/externals/mod.rs +++ b/lib/api/src/externals/mod.rs @@ -28,6 +28,7 @@ use crate::store::{AsStoreMut, AsStoreRef}; /// /// Spec: #[derive(Clone, PartialEq, Eq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::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 49eb38924f8..4253ce0857b 100644 --- a/lib/api/src/externals/table.rs +++ b/lib/api/src/externals/table.rs @@ -23,6 +23,7 @@ use crate::Value; /// /// Spec: #[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Table(pub(crate) table_impl::Table); impl Table { diff --git a/lib/api/src/lib.rs b/lib/api/src/lib.rs old mode 100755 new mode 100644 diff --git a/lib/api/src/module.rs b/lib/api/src/module.rs index 52bf98ae30b..60b5e347af8 100644 --- a/lib/api/src/module.rs +++ b/lib/api/src/module.rs @@ -42,6 +42,7 @@ pub enum IoCompileError { /// Cloning a module is cheap: it does a shallow copy of the compiled /// contents rather than a deep copy. #[derive(Clone, PartialEq, Eq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Module(pub(crate) module_imp::Module); impl Module { diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 41c292f90cb..a6adcceb9a8 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -13,6 +13,7 @@ use wasmer_vm::{ VMFunction, VMFunctionContext, VMFunctionKind, VMTrampoline, }; +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(Debug, Clone, PartialEq, Eq)] pub struct Function { pub(crate) handle: StoreHandle, diff --git a/lib/api/src/sys/externals/global.rs b/lib/api/src/sys/externals/global.rs index 7b5accdbe24..8e159c7c36d 100644 --- a/lib/api/src/sys/externals/global.rs +++ b/lib/api/src/sys/externals/global.rs @@ -7,6 +7,7 @@ use crate::Mutability; use wasmer_vm::{StoreHandle, VMExtern, VMGlobal}; #[derive(Debug, Clone)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Global { handle: StoreHandle, } diff --git a/lib/api/src/sys/externals/memory.rs b/lib/api/src/sys/externals/memory.rs index b61adc4ff68..a3b4f38953f 100644 --- a/lib/api/src/sys/externals/memory.rs +++ b/lib/api/src/sys/externals/memory.rs @@ -19,6 +19,7 @@ use crate::{ }; #[derive(Debug, Clone)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Memory { pub(crate) handle: StoreHandle, } diff --git a/lib/api/src/sys/externals/table.rs b/lib/api/src/sys/externals/table.rs index aba68442415..285135dfd2a 100644 --- a/lib/api/src/sys/externals/table.rs +++ b/lib/api/src/sys/externals/table.rs @@ -6,6 +6,7 @@ use crate::{vm::VMExternTable, ExternRef, Function, RuntimeError}; use wasmer_vm::{StoreHandle, TableElement, Trap, VMExtern, VMTable}; #[derive(Debug, Clone)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Table { handle: StoreHandle, } diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index 3aae35d02ed..c4030c950c2 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -14,6 +14,7 @@ use crate::{ }; #[derive(Clone, PartialEq, Eq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Module { // The field ordering here is actually significant because of the drop // order: we want to drop the artifact before dropping the engine. diff --git a/lib/compiler/Cargo.toml b/lib/compiler/Cargo.toml index 29cee1f45c3..fbd94b3414f 100644 --- a/lib/compiler/Cargo.toml +++ b/lib/compiler/Cargo.toml @@ -23,6 +23,11 @@ thiserror = "1.0" serde_bytes = { version = "0.11", optional = true } smallvec = "1.6" xxhash-rust = { version = "0.8.10", features = ["xxh64"] } +loupe = { version = "0.1.3", optional = true, features = [ + "indexmap", + "enable-indexmap", +] } + backtrace = "0.3" memmap2 = "0.6" @@ -44,7 +49,9 @@ wasmer-vm = { path = "../vm", version = "=4.3.7" } region = { version = "3.0" } [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { version = "0.59", features = ["Win32_System_Diagnostics_Debug"] } +windows-sys = { version = "0.59", features = [ + "Win32_System_Diagnostics_Debug", +] } [features] default = ["std"] @@ -60,15 +67,16 @@ static-artifact-create = ["wasmer-object"] std = ["wasmer-types/std"] core = ["hashbrown", "wasmer-types/core"] enable-serde = ["serde", "serde_bytes", "wasmer-types/enable-serde"] +artifact-size = ["dep:loupe"] [badges] maintenance = { status = "experimental" } [package.metadata.docs.rs] features = [ - "static-artifact-create", - "static-artifact-load", - "wasmer-artifact-create", - "wasmer-artifact-load", + "static-artifact-create", + "static-artifact-load", + "wasmer-artifact-create", + "wasmer-artifact-load", ] rustc-args = ["--cfg", "docsrs"] diff --git a/lib/compiler/src/artifact_builders/artifact_builder.rs b/lib/compiler/src/artifact_builders/artifact_builder.rs index 03ecc47b7c8..13fe0659239 100644 --- a/lib/compiler/src/artifact_builders/artifact_builder.rs +++ b/lib/compiler/src/artifact_builders/artifact_builder.rs @@ -34,6 +34,7 @@ use wasmer_types::{ use wasmer_types::{MetadataHeader, SerializeError}; /// A compiled wasm module, ready to be instantiated. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct ArtifactBuild { serializable: SerializableModule, } @@ -287,8 +288,16 @@ self_cell!( impl {Debug} ); +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for ArtifactBuildFromArchiveCell { + fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + std::mem::size_of_val(self.borrow_owner()) + std::mem::size_of_val(self.borrow_dependent()) + } +} + /// A compiled wasm module that was loaded from a serialized archive. #[derive(Clone, Debug)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct ArtifactBuildFromArchive { cell: Arc, diff --git a/lib/compiler/src/engine/artifact.rs b/lib/compiler/src/engine/artifact.rs index 0864abf46c9..1c2d5393c2d 100644 --- a/lib/compiler/src/engine/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -44,6 +44,7 @@ use wasmer_types::{SerializableModule, SerializeError}; use wasmer_vm::{FunctionBodyPtr, MemoryStyle, TableStyle, VMSharedSignatureIndex, VMTrampoline}; use wasmer_vm::{InstanceAllocator, StoreObjects, TrapHandlerFn, VMConfig, VMExtern, VMInstance}; +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct AllocatedArtifact { // This shows if the frame info has been regestered already or not. // Because the 'GlobalFrameInfoRegistration' ownership can be transfered to EngineInner @@ -55,6 +56,8 @@ pub struct AllocatedArtifact { // so the GloabelFrameInfo and MMap stays in sync and get dropped at the same time frame_info_registration: Option, finished_functions: BoxedSlice, + + #[cfg_attr(feature = "artifact-size", loupe(skip))] finished_function_call_trampolines: BoxedSlice, finished_dynamic_function_trampolines: BoxedSlice, signatures: BoxedSlice, @@ -62,6 +65,7 @@ pub struct AllocatedArtifact { } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[repr(transparent)] /// A unique identifier for an Artifact. pub struct ArtifactId { @@ -91,6 +95,7 @@ impl Default for ArtifactId { } /// A compiled wasm module, ready to be instantiated. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct Artifact { id: ArtifactId, artifact: ArtifactBuildVariant, @@ -102,6 +107,7 @@ pub struct Artifact { /// Artifacts may be created as the result of the compilation of a wasm /// module, corresponding to `ArtifactBuildVariant::Plain`, or loaded /// from an archive, corresponding to `ArtifactBuildVariant::Archived`. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub enum ArtifactBuildVariant { Plain(ArtifactBuild), Archived(ArtifactBuildFromArchive), diff --git a/lib/compiler/src/engine/trap/frame_info.rs b/lib/compiler/src/engine/trap/frame_info.rs index f09dae724a9..58635a91627 100644 --- a/lib/compiler/src/engine/trap/frame_info.rs +++ b/lib/compiler/src/engine/trap/frame_info.rs @@ -54,6 +54,7 @@ pub struct GlobalFrameInfo { /// An RAII structure used to unregister a module's frame information when the /// module is destroyed. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct GlobalFrameInfoRegistration { /// The key that will be removed from the global `ranges` map when this is /// dropped. diff --git a/lib/types/Cargo.toml b/lib/types/Cargo.toml index d36bb7fafd0..ccc41f73b39 100644 --- a/lib/types/Cargo.toml +++ b/lib/types/Cargo.toml @@ -13,7 +13,10 @@ rust-version.workspace = true version.workspace = true [dependencies] -serde = { version = "1.0", features = ["derive", "rc"], optional = true, default-features = false } +serde = { version = "1.0", features = [ + "derive", + "rc", +], optional = true, default-features = false } serde_bytes = { version = "0.11", optional = true } thiserror = "1.0" more-asserts = "0.2" @@ -26,6 +29,8 @@ bytecheck = "0.6.8" xxhash-rust = { version = "0.8.8", features = ["xxh64"] } sha2 = { version = "0.10" } hex = { version = "^0.4" } +loupe = { version = "0.1.3", optional = true } + # `rand` uses `getrandom` transitively, and to be able to # compile the project for `js`, we need to enable this feature @@ -41,6 +46,7 @@ default = ["std"] std = [] core = [] enable-serde = ["serde", "serde/std", "serde_bytes", "indexmap/serde-1"] +artifact-size = ["dep:loupe"] [package.metadata.docs.rs] rustc-args = ["--cfg", "docsrs"] diff --git a/lib/types/src/compilation/address_map.rs b/lib/types/src/compilation/address_map.rs index 0fee3ccd217..0081d60bc6e 100644 --- a/lib/types/src/compilation/address_map.rs +++ b/lib/types/src/compilation/address_map.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize}; /// Single source location to generated address mapping. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, Copy, PartialEq, Eq)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub struct InstructionAddressMap { @@ -23,6 +24,7 @@ pub struct InstructionAddressMap { } /// Function and its instructions addresses mappings. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] diff --git a/lib/types/src/compilation/function.rs b/lib/types/src/compilation/function.rs index aabf1195674..a916f4fbb3b 100644 --- a/lib/types/src/compilation/function.rs +++ b/lib/types/src/compilation/function.rs @@ -22,6 +22,7 @@ use super::unwind::CompiledFunctionUnwindInfoLike; /// /// This structure is only used for reconstructing /// the frame information after a `Trap`. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] @@ -37,6 +38,7 @@ pub struct CompiledFunctionFrameInfo { /// The function body. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub struct FunctionBody { @@ -116,6 +118,7 @@ pub type CustomSections = PrimaryMap; /// In the future this structure may also hold other information useful /// for debugging. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive( RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes, Debug, PartialEq, Eq, Clone, )] diff --git a/lib/types/src/compilation/module.rs b/lib/types/src/compilation/module.rs index 43be092d271..cda598943ee 100644 --- a/lib/types/src/compilation/module.rs +++ b/lib/types/src/compilation/module.rs @@ -12,6 +12,7 @@ use std::sync::Arc; /// possible after translation (such as the features used for compiling, /// or the `MemoryStyle` and `TableStyle`). #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(Debug, Clone, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub struct CompileModuleInfo { diff --git a/lib/types/src/compilation/relocation.rs b/lib/types/src/compilation/relocation.rs index 0b1b1331a10..15294c79aad 100644 --- a/lib/types/src/compilation/relocation.rs +++ b/lib/types/src/compilation/relocation.rs @@ -20,6 +20,7 @@ use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; use serde::{Deserialize, Serialize}; /// Relocation kinds for every ISA. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[derive( RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes, Copy, Clone, Debug, PartialEq, Eq, @@ -92,6 +93,7 @@ impl fmt::Display for RelocationKind { /// A record of a relocation to perform. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub struct Relocation { @@ -211,6 +213,7 @@ impl RelocationLike for ArchivedRelocation { /// Destination function. Can be either user function or some special one, like `memory.grow`. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive( RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes, Debug, Copy, Clone, PartialEq, Eq, )] diff --git a/lib/types/src/compilation/section.rs b/lib/types/src/compilation/section.rs index 14d97f34600..1f0f7b70dea 100644 --- a/lib/types/src/compilation/section.rs +++ b/lib/types/src/compilation/section.rs @@ -29,6 +29,7 @@ use serde::{Deserialize, Serialize}; Default, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct SectionIndex(u32); @@ -37,6 +38,7 @@ entity_impl!(SectionIndex); /// Custom section Protection. /// /// Determines how a custom section may be used. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[derive( RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes, Debug, Clone, PartialEq, Eq, @@ -56,6 +58,7 @@ pub enum CustomSectionProtection { /// This is used so compilers can store arbitrary information /// in the emitted module. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub struct CustomSection { @@ -118,6 +121,7 @@ impl<'a> CustomSectionLike<'a> for ArchivedCustomSection { /// The bytes in the section. #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq, Default)] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub struct SectionBody(#[cfg_attr(feature = "enable-serde", serde(with = "serde_bytes"))] Vec); diff --git a/lib/types/src/compilation/unwind.rs b/lib/types/src/compilation/unwind.rs index 0dae88d9cb6..0747eef9bfb 100644 --- a/lib/types/src/compilation/unwind.rs +++ b/lib/types/src/compilation/unwind.rs @@ -19,6 +19,7 @@ use serde::{Deserialize, Serialize}; /// [unwind info]: https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64?view=vs-2019 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive_attr(derive(rkyv::CheckBytes, Debug))] pub enum CompiledFunctionUnwindInfo { /// Windows UNWIND_INFO. diff --git a/lib/types/src/entity/boxed_slice.rs b/lib/types/src/entity/boxed_slice.rs index eca12d89185..704457eb495 100644 --- a/lib/types/src/entity/boxed_slice.rs +++ b/lib/types/src/entity/boxed_slice.rs @@ -24,6 +24,22 @@ where unused: PhantomData, } +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for BoxedSlice +where + K: EntityRef, + V: loupe::MemoryUsage, +{ + fn size_of_val(&self, tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + std::mem::size_of_val(self) + + self + .elems + .iter() + .map(|value| value.size_of_val(tracker) - std::mem::size_of_val(value)) + .sum::() + } +} + impl BoxedSlice where K: EntityRef, diff --git a/lib/types/src/entity/primary_map.rs b/lib/types/src/entity/primary_map.rs index a810791331e..f1d79ada8a3 100644 --- a/lib/types/src/entity/primary_map.rs +++ b/lib/types/src/entity/primary_map.rs @@ -43,6 +43,22 @@ where pub(crate) unused: PhantomData, } +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for PrimaryMap +where + K: EntityRef, + V: loupe::MemoryUsage, +{ + fn size_of_val(&self, tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + std::mem::size_of_val(self) + + self + .elems + .iter() + .map(|value| value.size_of_val(tracker) - std::mem::size_of_val(value)) + .sum::() + } +} + impl PrimaryMap where K: EntityRef, diff --git a/lib/types/src/entity/secondary_map.rs b/lib/types/src/entity/secondary_map.rs index 554bc4278ae..03d8367e041 100644 --- a/lib/types/src/entity/secondary_map.rs +++ b/lib/types/src/entity/secondary_map.rs @@ -39,6 +39,22 @@ where pub(crate) unused: PhantomData, } +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for SecondaryMap +where + K: EntityRef, + V: Clone + loupe::MemoryUsage, +{ + fn size_of_val(&self, tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + std::mem::size_of_val(self) + + self + .elems + .iter() + .map(|value| value.size_of_val(tracker) - std::mem::size_of_val(value)) + .sum::() + } +} + /// Shared `SecondaryMap` implementation for all value types. impl SecondaryMap where diff --git a/lib/types/src/features.rs b/lib/types/src/features.rs index 54197762db5..4d7591a753c 100644 --- a/lib/types/src/features.rs +++ b/lib/types/src/features.rs @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize}; /// [WebAssembly proposal]: https://github.com/WebAssembly/proposals #[derive(Clone, Debug, Eq, PartialEq, rkyv::CheckBytes)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[archive(as = "Self")] pub struct Features { diff --git a/lib/types/src/indexes.rs b/lib/types/src/indexes.rs index 3bf3883f3f1..e4cd6116e61 100644 --- a/lib/types/src/indexes.rs +++ b/lib/types/src/indexes.rs @@ -21,18 +21,21 @@ use serde::{Deserialize, Serialize}; rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct LocalFunctionIndex(u32); entity_impl!(LocalFunctionIndex); /// Index type of a table defined locally inside the WebAssembly module. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct LocalTableIndex(u32); entity_impl!(LocalTableIndex); /// Index type of a memory defined locally inside the WebAssembly module. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] pub struct LocalMemoryIndex(u32); entity_impl!(LocalMemoryIndex); @@ -53,6 +56,7 @@ entity_impl!(LocalMemoryIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct LocalGlobalIndex(u32); entity_impl!(LocalGlobalIndex); @@ -73,6 +77,7 @@ entity_impl!(LocalGlobalIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct FunctionIndex(u32); entity_impl!(FunctionIndex); @@ -93,6 +98,7 @@ entity_impl!(FunctionIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct TableIndex(u32); entity_impl!(TableIndex); @@ -113,6 +119,7 @@ entity_impl!(TableIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct GlobalIndex(u32); entity_impl!(GlobalIndex); @@ -133,6 +140,7 @@ entity_impl!(GlobalIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct MemoryIndex(u32); entity_impl!(MemoryIndex); @@ -153,6 +161,7 @@ entity_impl!(MemoryIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct SignatureIndex(u32); entity_impl!(SignatureIndex); @@ -173,6 +182,7 @@ entity_impl!(SignatureIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct DataIndex(u32); entity_impl!(DataIndex); @@ -193,6 +203,7 @@ entity_impl!(DataIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct ElemIndex(u32); entity_impl!(ElemIndex); @@ -213,6 +224,7 @@ entity_impl!(ElemIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct CustomSectionIndex(u32); entity_impl!(CustomSectionIndex); @@ -233,6 +245,7 @@ entity_impl!(CustomSectionIndex); rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] #[repr(u8)] pub enum ExportIndex { @@ -261,6 +274,7 @@ pub enum ExportIndex { rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] #[repr(u8)] pub enum ImportIndex { diff --git a/lib/types/src/initializers.rs b/lib/types/src/initializers.rs index 4c8f177d94b..f29934a415b 100644 --- a/lib/types/src/initializers.rs +++ b/lib/types/src/initializers.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize}; /// A WebAssembly table initializer. #[derive(Clone, Debug, Hash, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive_attr(derive(CheckBytes, Debug))] pub struct TableInitializer { /// The index of a table to initialize. @@ -24,6 +25,7 @@ pub struct TableInitializer { /// A memory index and offset within that memory where a data initialization /// should be performed. #[derive(Clone, Debug, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[archive_attr(derive(CheckBytes, Debug))] pub struct DataInitializerLocation { @@ -91,6 +93,7 @@ pub struct DataInitializer<'data> { /// holding a reference to it #[derive(Debug, Clone, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive_attr(derive(CheckBytes, Debug))] pub struct OwnedDataInitializer { /// The location where the initialization is to be performed. diff --git a/lib/types/src/libcalls.rs b/lib/types/src/libcalls.rs index 21222c588d6..67c999b9307 100644 --- a/lib/types/src/libcalls.rs +++ b/lib/types/src/libcalls.rs @@ -21,6 +21,7 @@ use std::fmt; rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] #[repr(u16)] pub enum LibCall { diff --git a/lib/types/src/memory.rs b/lib/types/src/memory.rs index 5999f0c11c3..4896477a22e 100644 --- a/lib/types/src/memory.rs +++ b/lib/types/src/memory.rs @@ -21,6 +21,7 @@ use std::ops::{Add, AddAssign}; rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] #[repr(u8)] pub enum MemoryStyle { diff --git a/lib/types/src/module.rs b/lib/types/src/module.rs index 5ddea198a5a..ea77fe8d5f4 100644 --- a/lib/types/src/module.rs +++ b/lib/types/src/module.rs @@ -27,6 +27,7 @@ use std::iter::ExactSizeIterator; use std::sync::atomic::{AtomicUsize, Ordering::SeqCst}; #[derive(Debug, Clone, RkyvSerialize, RkyvDeserialize, Archive)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive_attr(derive(CheckBytes, Debug))] pub struct ModuleId { id: usize, @@ -106,6 +107,7 @@ mod serde_imports { /// to make sure we don't break compatibility between versions. #[derive(Debug, Clone, Default)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct ModuleInfo { /// A unique identifier (within this process) for this module. /// diff --git a/lib/types/src/module_hash.rs b/lib/types/src/module_hash.rs index 7c4e967f599..38966dba8e6 100644 --- a/lib/types/src/module_hash.rs +++ b/lib/types/src/module_hash.rs @@ -38,6 +38,16 @@ pub enum ModuleHash { Sha256([u8; 32]), } +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for ModuleHash { + fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + match self { + ModuleHash::XXHash(_) => 8 * 8, + ModuleHash::Sha256(_) => 8 * 32, + } + } +} + impl ModuleHash { /// Create a new [`ModuleHash`] from the raw xxhash hash. pub fn xxhash_from_bytes(key: [u8; 8]) -> Self { diff --git a/lib/types/src/serialize.rs b/lib/types/src/serialize.rs index d98af1dac76..a65b6132ad6 100644 --- a/lib/types/src/serialize.rs +++ b/lib/types/src/serialize.rs @@ -17,6 +17,7 @@ use std::mem; /// The compilation related data for a serialized modules #[derive(Archive, Default, RkyvDeserialize, RkyvSerialize)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[allow(missing_docs)] #[archive_attr(derive(CheckBytes, Debug))] pub struct SerializableCompilation { @@ -52,6 +53,7 @@ impl SerializableCompilation { /// Serializable struct that is able to serialize from and to a `ArtifactInfo`. #[derive(Archive, RkyvDeserialize, RkyvSerialize)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[allow(missing_docs)] #[archive_attr(derive(CheckBytes, Debug))] pub struct SerializableModule { diff --git a/lib/types/src/stack/sourceloc.rs b/lib/types/src/stack/sourceloc.rs index e91586f4073..66af03a4318 100644 --- a/lib/types/src/stack/sourceloc.rs +++ b/lib/types/src/stack/sourceloc.rs @@ -21,6 +21,7 @@ use serde::{Deserialize, Serialize}; derive(Serialize, Deserialize), serde(transparent) )] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, rkyv::CheckBytes)] diff --git a/lib/types/src/stack/trap.rs b/lib/types/src/stack/trap.rs index b13c14b7df6..cf6ae88f70e 100644 --- a/lib/types/src/stack/trap.rs +++ b/lib/types/src/stack/trap.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; /// Information about trap. #[cfg_attr(feature = "enable-serde", derive(Deserialize, Serialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive( RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes, Clone, Copy, Debug, PartialEq, Eq, )] diff --git a/lib/types/src/store_id.rs b/lib/types/src/store_id.rs index 414a4af1d0f..7b6e380160b 100644 --- a/lib/types/src/store_id.rs +++ b/lib/types/src/store_id.rs @@ -12,6 +12,13 @@ use std::{ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct StoreId(NonZeroUsize); +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for StoreId { + fn size_of_val(&self, _visited: &mut dyn loupe::MemoryUsageTracker) -> usize { + std::mem::size_of_val(self) + } +} + impl Default for StoreId { // Allocates a unique ID for a new context. fn default() -> Self { diff --git a/lib/types/src/table.rs b/lib/types/src/table.rs index 0b155d1f881..0837af841a6 100644 --- a/lib/types/src/table.rs +++ b/lib/types/src/table.rs @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize}; Debug, Clone, Hash, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive, CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] #[repr(u8)] pub enum TableStyle { diff --git a/lib/types/src/trapcode.rs b/lib/types/src/trapcode.rs index ae8066d89c4..52249a444fa 100644 --- a/lib/types/src/trapcode.rs +++ b/lib/types/src/trapcode.rs @@ -27,6 +27,7 @@ use thiserror::Error; rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[repr(u32)] #[archive(as = "Self")] pub enum TrapCode { diff --git a/lib/types/src/types.rs b/lib/types/src/types.rs index 3b9e4af215f..65ba989de79 100644 --- a/lib/types/src/types.rs +++ b/lib/types/src/types.rs @@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize}; /// A list of all possible value types in WebAssembly. #[derive(Copy, Debug, Clone, Eq, PartialEq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes)] #[archive(as = "Self")] #[repr(u8)] @@ -67,6 +68,13 @@ impl fmt::Display for Type { #[archive(as = "Self")] pub struct V128(pub(crate) [u8; 16]); +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for V128 { + fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + 16 * 8 + } +} + impl V128 { /// Get the bytes corresponding to the V128 value pub fn bytes(&self) -> &[u8; 16] { @@ -241,6 +249,7 @@ impl ExternType { /// WebAssembly functions can have 0 or more parameters and results. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[archive_attr(derive(CheckBytes, Debug))] pub struct FunctionType { @@ -327,6 +336,7 @@ impl From<&Self> for FunctionType { /// Indicator of whether a global is mutable or not #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CheckBytes)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[archive(as = "Self")] @@ -367,6 +377,7 @@ impl From for bool { /// WebAssembly global. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CheckBytes)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[archive(as = "Self")] pub struct GlobalType { @@ -412,6 +423,7 @@ impl fmt::Display for GlobalType { /// Globals are initialized via the `const` operators or by referring to another import. #[derive(Debug, Clone, Copy, PartialEq)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive, rkyv::CheckBytes)] #[archive(as = "Self")] #[repr(u8)] @@ -446,6 +458,7 @@ pub enum GlobalInit { /// which `call_indirect` can invoke other functions. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[archive_attr(derive(CheckBytes, Debug))] pub struct TableType { @@ -487,6 +500,7 @@ impl fmt::Display for TableType { /// chunks of addressable memory. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(RkyvSerialize, RkyvDeserialize, Archive)] #[archive_attr(derive(CheckBytes, Debug))] pub struct MemoryType { diff --git a/lib/types/src/units.rs b/lib/types/src/units.rs index 60e488b4a31..fc6671f5344 100644 --- a/lib/types/src/units.rs +++ b/lib/types/src/units.rs @@ -34,6 +34,7 @@ pub const WASM_MIN_PAGES: u32 = 0x100; rkyv::CheckBytes, )] #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[archive(as = "Self")] pub struct Pages(pub u32); diff --git a/lib/vm/Cargo.toml b/lib/vm/Cargo.toml index 0fcf37541f3..04c65486b26 100644 --- a/lib/vm/Cargo.toml +++ b/lib/vm/Cargo.toml @@ -33,12 +33,18 @@ fnv = "1.0.3" # - Optional shared dependencies. tracing = { version = "0.1", optional = true } crossbeam-queue = "0.3.8" +loupe = { version = "0.1.3", optional = true } [target.'cfg(target_vendor = "apple")'.dependencies] mach2 = "0.4.2" [target.'cfg(target_os = "windows")'.dependencies] -windows-sys = { version = "0.59", features = ["Win32_System_Diagnostics_Debug", "Win32_System_Threading", "Win32_System_Kernel", "Win32_System_Memory"] } +windows-sys = { version = "0.59", features = [ + "Win32_System_Diagnostics_Debug", + "Win32_System_Threading", + "Win32_System_Kernel", + "Win32_System_Memory", +] } [build-dependencies] cc = "1.0" @@ -48,7 +54,8 @@ maintenance = { status = "actively-developed" } [features] default = [] -enable-serde = ["serde", "indexmap/serde-1", "wasmer-types/enable-serde" ] +enable-serde = ["serde", "indexmap/serde-1", "wasmer-types/enable-serde"] +artifact-size = ["dep:loupe", "wasmer-types/artifact-size"] [package.metadata.docs.rs] rustc-args = ["--cfg", "docsrs"] diff --git a/lib/vm/src/export.rs b/lib/vm/src/export.rs index 3a670b14b14..462725ccb6d 100644 --- a/lib/vm/src/export.rs +++ b/lib/vm/src/export.rs @@ -12,6 +12,7 @@ use std::any::Any; use wasmer_types::FunctionType; /// The value of an export passed from one instance to another. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub enum VMExtern { /// A function export value. Function(InternalStoreHandle), diff --git a/lib/vm/src/lib.rs b/lib/vm/src/lib.rs index 726e304b8b5..a49f115250b 100644 --- a/lib/vm/src/lib.rs +++ b/lib/vm/src/lib.rs @@ -90,6 +90,7 @@ pub struct VMFunctionBody(u8); /// A safe wrapper around `VMFunctionBody`. #[derive(Clone, Copy, Debug)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[repr(transparent)] pub struct FunctionBodyPtr(pub *const VMFunctionBody); diff --git a/lib/vm/src/store.rs b/lib/vm/src/store.rs index 8813ee26c15..09f25e6bb44 100644 --- a/lib/vm/src/store.rs +++ b/lib/vm/src/store.rs @@ -105,6 +105,7 @@ impl StoreObjects { /// /// Internally this is just an integer index into a context. A reference to the /// context must be passed in separately to access the actual object. +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] pub struct StoreHandle { id: StoreId, internal: InternalStoreHandle, @@ -199,6 +200,13 @@ pub struct InternalStoreHandle { marker: PhantomData T>, } +#[cfg(feature = "artifact-size")] +impl loupe::MemoryUsage for InternalStoreHandle { + fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize { + std::mem::size_of_val(&self) + } +} + impl Clone for InternalStoreHandle { fn clone(&self) -> Self { *self diff --git a/lib/vm/src/vmcontext.rs b/lib/vm/src/vmcontext.rs index c75d6b5f69e..bea67b71190 100644 --- a/lib/vm/src/vmcontext.rs +++ b/lib/vm/src/vmcontext.rs @@ -538,6 +538,7 @@ impl VMGlobalDefinition { /// An index into the shared signature registry, usable for checking signatures /// at indirect calls. #[repr(C)] +#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))] #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)] pub struct VMSharedSignatureIndex(u32);