Add heap size support for salsa structs (#943)
Some checks are pending
Test / Test (push) Waiting to run
Test / Miri (push) Waiting to run
Book / Book (push) Waiting to run
Book / Deploy (push) Blocked by required conditions
Release-plz / Release-plz release (push) Waiting to run
Release-plz / Release-plz PR (push) Waiting to run
Test / Shuttle (push) Waiting to run
Test / Benchmarks (push) Waiting to run

* Improve unstable size analysis support

 1. Include an option `panic_if_missing` that will panic if there is an ingredient with no `heap_size()` defined, to ensure coverage.
 2. Add `heap_size()` to tracked structs, interneds an inputs.

* Make heap size a separate field, remove panic argument

* Remove stale comment

---------

Co-authored-by: Chayim Refael Friedman <chayimfr@gmail.com>
This commit is contained in:
Micha Reiser 2025-08-06 09:01:18 +02:00 committed by GitHub
parent 5b2a97b56c
commit ea38537827
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 136 additions and 60 deletions

View file

@ -50,6 +50,9 @@ macro_rules! setup_input_struct {
// If true, generate a debug impl. // If true, generate a debug impl.
generate_debug_impl: $generate_debug_impl:tt, generate_debug_impl: $generate_debug_impl:tt,
// The function used to implement `C::heap_size`.
heap_size_fn: $($heap_size_fn:path)?,
// Annoyingly macro-rules hygiene does not extend to items defined in the macro. // Annoyingly macro-rules hygiene does not extend to items defined in the macro.
// We have the procedural macro generate names for those items that are // We have the procedural macro generate names for those items that are
// not used elsewhere in the user's code. // not used elsewhere in the user's code.
@ -98,6 +101,12 @@ macro_rules! setup_input_struct {
type Revisions = [$zalsa::Revision; $N]; type Revisions = [$zalsa::Revision; $N];
type Durabilities = [$zalsa::Durability; $N]; type Durabilities = [$zalsa::Durability; $N];
$(
fn heap_size(value: &Self::Fields) -> Option<usize> {
Some($heap_size_fn(value))
}
)?
} }
impl $Configuration { impl $Configuration {

View file

@ -66,6 +66,9 @@ macro_rules! setup_interned_struct {
// If true, generate a debug impl. // If true, generate a debug impl.
generate_debug_impl: $generate_debug_impl:tt, generate_debug_impl: $generate_debug_impl:tt,
// The function used to implement `C::heap_size`.
heap_size_fn: $($heap_size_fn:path)?,
// Annoyingly macro-rules hygiene does not extend to items defined in the macro. // Annoyingly macro-rules hygiene does not extend to items defined in the macro.
// We have the procedural macro generate names for those items that are // We have the procedural macro generate names for those items that are
// not used elsewhere in the user's code. // not used elsewhere in the user's code.
@ -146,6 +149,12 @@ macro_rules! setup_interned_struct {
)? )?
type Fields<'a> = $StructDataIdent<'a>; type Fields<'a> = $StructDataIdent<'a>;
type Struct<'db> = $Struct< $($db_lt_arg)? >; type Struct<'db> = $Struct< $($db_lt_arg)? >;
$(
fn heap_size(value: &Self::Fields<'_>) -> Option<usize> {
Some($heap_size_fn(value))
}
)?
} }
impl $Configuration { impl $Configuration {

View file

@ -240,8 +240,8 @@ macro_rules! setup_tracked_fn {
$($values_equal)+ $($values_equal)+
$( $(
fn heap_size(value: &Self::Output<'_>) -> usize { fn heap_size(value: &Self::Output<'_>) -> Option<usize> {
$heap_size_fn(value) Some($heap_size_fn(value))
} }
)? )?

View file

@ -88,6 +88,9 @@ macro_rules! setup_tracked_struct {
// If true, generate a debug impl. // If true, generate a debug impl.
generate_debug_impl: $generate_debug_impl:tt, generate_debug_impl: $generate_debug_impl:tt,
// The function used to implement `C::heap_size`.
heap_size_fn: $($heap_size_fn:path)?,
// Annoyingly macro-rules hygiene does not extend to items defined in the macro. // Annoyingly macro-rules hygiene does not extend to items defined in the macro.
// We have the procedural macro generate names for those items that are // We have the procedural macro generate names for those items that are
// not used elsewhere in the user's code. // not used elsewhere in the user's code.
@ -185,6 +188,12 @@ macro_rules! setup_tracked_struct {
)* false )* false
} }
} }
$(
fn heap_size(value: &Self::Fields<'_>) -> Option<usize> {
Some($heap_size_fn(value))
}
)?
} }
impl $Configuration { impl $Configuration {

View file

@ -65,7 +65,7 @@ impl crate::options::AllowedOptions for InputStruct {
const REVISIONS: bool = false; const REVISIONS: bool = false;
const HEAP_SIZE: bool = false; const HEAP_SIZE: bool = true;
const SELF_TY: bool = false; const SELF_TY: bool = false;
} }
@ -112,6 +112,7 @@ impl Macro {
let field_attrs = salsa_struct.field_attrs(); let field_attrs = salsa_struct.field_attrs();
let is_singleton = self.args.singleton.is_some(); let is_singleton = self.args.singleton.is_some();
let generate_debug_impl = salsa_struct.generate_debug_impl(); let generate_debug_impl = salsa_struct.generate_debug_impl();
let heap_size_fn = self.args.heap_size_fn.iter();
let zalsa = self.hygiene.ident("zalsa"); let zalsa = self.hygiene.ident("zalsa");
let zalsa_struct = self.hygiene.ident("zalsa_struct"); let zalsa_struct = self.hygiene.ident("zalsa_struct");
@ -140,6 +141,7 @@ impl Macro {
num_fields: #num_fields, num_fields: #num_fields,
is_singleton: #is_singleton, is_singleton: #is_singleton,
generate_debug_impl: #generate_debug_impl, generate_debug_impl: #generate_debug_impl,
heap_size_fn: #(#heap_size_fn)*,
unused_names: [ unused_names: [
#zalsa, #zalsa,
#zalsa_struct, #zalsa_struct,

View file

@ -65,7 +65,7 @@ impl crate::options::AllowedOptions for InternedStruct {
const REVISIONS: bool = true; const REVISIONS: bool = true;
const HEAP_SIZE: bool = false; const HEAP_SIZE: bool = true;
const SELF_TY: bool = false; const SELF_TY: bool = false;
} }
@ -131,6 +131,8 @@ impl Macro {
(None, quote!(#struct_ident), static_lifetime) (None, quote!(#struct_ident), static_lifetime)
}; };
let heap_size_fn = self.args.heap_size_fn.iter();
let zalsa = self.hygiene.ident("zalsa"); let zalsa = self.hygiene.ident("zalsa");
let zalsa_struct = self.hygiene.ident("zalsa_struct"); let zalsa_struct = self.hygiene.ident("zalsa_struct");
let Configuration = self.hygiene.ident("Configuration"); let Configuration = self.hygiene.ident("Configuration");
@ -161,6 +163,7 @@ impl Macro {
field_attrs: [#([#(#field_unused_attrs),*]),*], field_attrs: [#([#(#field_unused_attrs),*]),*],
num_fields: #num_fields, num_fields: #num_fields,
generate_debug_impl: #generate_debug_impl, generate_debug_impl: #generate_debug_impl,
heap_size_fn: #(#heap_size_fn)*,
unused_names: [ unused_names: [
#zalsa, #zalsa,
#zalsa_struct, #zalsa_struct,

View file

@ -61,7 +61,7 @@ impl crate::options::AllowedOptions for TrackedStruct {
const REVISIONS: bool = false; const REVISIONS: bool = false;
const HEAP_SIZE: bool = false; const HEAP_SIZE: bool = true;
const SELF_TY: bool = false; const SELF_TY: bool = false;
} }
@ -141,6 +141,8 @@ impl Macro {
} }
}); });
let heap_size_fn = self.args.heap_size_fn.iter();
let num_tracked_fields = salsa_struct.num_tracked_fields(); let num_tracked_fields = salsa_struct.num_tracked_fields();
let generate_debug_impl = salsa_struct.generate_debug_impl(); let generate_debug_impl = salsa_struct.generate_debug_impl();
@ -188,6 +190,9 @@ impl Macro {
num_tracked_fields: #num_tracked_fields, num_tracked_fields: #num_tracked_fields,
generate_debug_impl: #generate_debug_impl, generate_debug_impl: #generate_debug_impl,
heap_size_fn: #(#heap_size_fn)*,
unused_names: [ unused_names: [
#zalsa, #zalsa,
#zalsa_struct, #zalsa_struct,

View file

@ -172,17 +172,24 @@ mod memory_usage {
let mut size_of_fields = 0; let mut size_of_fields = 0;
let mut size_of_metadata = 0; let mut size_of_metadata = 0;
let mut instances = 0; let mut instances = 0;
let mut heap_size_of_fields = None;
for slot in ingredient.memory_usage(self)? { for slot in ingredient.memory_usage(self)? {
instances += 1; instances += 1;
size_of_fields += slot.size_of_fields; size_of_fields += slot.size_of_fields;
size_of_metadata += slot.size_of_metadata; size_of_metadata += slot.size_of_metadata;
if let Some(slot_heap_size) = slot.heap_size_of_fields {
heap_size_of_fields =
Some(heap_size_of_fields.unwrap_or_default() + slot_heap_size);
}
} }
Some(IngredientInfo { Some(IngredientInfo {
count: instances, count: instances,
size_of_fields, size_of_fields,
size_of_metadata, size_of_metadata,
heap_size_of_fields,
debug_name: ingredient.debug_name(), debug_name: ingredient.debug_name(),
}) })
}) })
@ -211,6 +218,11 @@ mod memory_usage {
info.count += 1; info.count += 1;
info.size_of_fields += memo.output.size_of_fields; info.size_of_fields += memo.output.size_of_fields;
info.size_of_metadata += memo.output.size_of_metadata; info.size_of_metadata += memo.output.size_of_metadata;
if let Some(memo_heap_size) = memo.output.heap_size_of_fields {
info.heap_size_of_fields =
Some(info.heap_size_of_fields.unwrap_or_default() + memo_heap_size);
}
} }
} }
} }
@ -226,6 +238,7 @@ mod memory_usage {
count: usize, count: usize,
size_of_metadata: usize, size_of_metadata: usize,
size_of_fields: usize, size_of_fields: usize,
heap_size_of_fields: Option<usize>,
} }
impl IngredientInfo { impl IngredientInfo {
@ -234,11 +247,18 @@ mod memory_usage {
self.debug_name self.debug_name
} }
/// Returns the total size of the fields of any instances of this ingredient, in bytes. /// Returns the total stack size of the fields of any instances of this ingredient, in bytes.
pub fn size_of_fields(&self) -> usize { pub fn size_of_fields(&self) -> usize {
self.size_of_fields self.size_of_fields
} }
/// Returns the total heap size of the fields of any instances of this ingredient, in bytes.
///
/// Returns `None` if the ingredient doesn't specify a `heap_size` function.
pub fn heap_size_of_fields(&self) -> Option<usize> {
self.heap_size_of_fields
}
/// Returns the total size of Salsa metadata of any instances of this ingredient, in bytes. /// Returns the total size of Salsa metadata of any instances of this ingredient, in bytes.
pub fn size_of_metadata(&self) -> usize { pub fn size_of_metadata(&self) -> usize {
self.size_of_metadata self.size_of_metadata
@ -255,6 +275,7 @@ mod memory_usage {
pub(crate) debug_name: &'static str, pub(crate) debug_name: &'static str,
pub(crate) size_of_metadata: usize, pub(crate) size_of_metadata: usize,
pub(crate) size_of_fields: usize, pub(crate) size_of_fields: usize,
pub(crate) heap_size_of_fields: Option<usize>,
pub(crate) memos: Vec<MemoInfo>, pub(crate) memos: Vec<MemoInfo>,
} }

View file

@ -75,8 +75,8 @@ pub trait Configuration: Any {
fn id_to_input(zalsa: &Zalsa, key: Id) -> Self::Input<'_>; fn id_to_input(zalsa: &Zalsa, key: Id) -> Self::Input<'_>;
/// Returns the size of any heap allocations in the output value, in bytes. /// Returns the size of any heap allocations in the output value, in bytes.
fn heap_size(_value: &Self::Output<'_>) -> usize { fn heap_size(_value: &Self::Output<'_>) -> Option<usize> {
0 None
} }
/// Invoked when we need to compute the value for the given key, either because we've never /// Invoked when we need to compute the value for the given key, either because we've never

View file

@ -321,14 +321,19 @@ where
#[cfg(feature = "salsa_unstable")] #[cfg(feature = "salsa_unstable")]
fn memory_usage(&self) -> crate::database::MemoInfo { fn memory_usage(&self) -> crate::database::MemoInfo {
let size_of = std::mem::size_of::<Memo<C>>() + self.revisions.allocation_size(); let size_of = std::mem::size_of::<Memo<C>>() + self.revisions.allocation_size();
let heap_size = self.value.as_ref().map(C::heap_size).unwrap_or(0); let heap_size = if let Some(value) = self.value.as_ref() {
C::heap_size(value)
} else {
Some(0)
};
crate::database::MemoInfo { crate::database::MemoInfo {
debug_name: C::DEBUG_NAME, debug_name: C::DEBUG_NAME,
output: crate::database::SlotInfo { output: crate::database::SlotInfo {
size_of_metadata: size_of - std::mem::size_of::<C::Output<'static>>(), size_of_metadata: size_of - std::mem::size_of::<C::Output<'static>>(),
debug_name: std::any::type_name::<C::Output<'static>>(), debug_name: std::any::type_name::<C::Output<'static>>(),
size_of_fields: std::mem::size_of::<C::Output<'static>>() + heap_size, size_of_fields: std::mem::size_of::<C::Output<'static>>(),
heap_size_of_fields: heap_size,
memos: Vec::new(), memos: Vec::new(),
}, },
} }

View file

@ -40,6 +40,11 @@ pub trait Configuration: Any {
/// A array of [`Durability`], one per each of the value fields. /// A array of [`Durability`], one per each of the value fields.
type Durabilities: Send + Sync + fmt::Debug + IndexMut<usize, Output = Durability>; type Durabilities: Send + Sync + fmt::Debug + IndexMut<usize, Output = Durability>;
/// Returns the size of any heap allocations in the output value, in bytes.
fn heap_size(_value: &Self::Fields) -> Option<usize> {
None
}
} }
pub struct JarImpl<C: Configuration> { pub struct JarImpl<C: Configuration> {
@ -307,6 +312,7 @@ where
/// The `MemoTable` must belong to a `Value` of the correct type. /// The `MemoTable` must belong to a `Value` of the correct type.
#[cfg(feature = "salsa_unstable")] #[cfg(feature = "salsa_unstable")]
unsafe fn memory_usage(&self, memo_table_types: &MemoTableTypes) -> crate::database::SlotInfo { unsafe fn memory_usage(&self, memo_table_types: &MemoTableTypes) -> crate::database::SlotInfo {
let heap_size = C::heap_size(&self.fields);
// SAFETY: The caller guarantees this is the correct types table. // SAFETY: The caller guarantees this is the correct types table.
let memos = unsafe { memo_table_types.attach_memos(&self.memos) }; let memos = unsafe { memo_table_types.attach_memos(&self.memos) };
@ -314,6 +320,7 @@ where
debug_name: C::DEBUG_NAME, debug_name: C::DEBUG_NAME,
size_of_metadata: std::mem::size_of::<Self>() - std::mem::size_of::<C::Fields>(), size_of_metadata: std::mem::size_of::<Self>() - std::mem::size_of::<C::Fields>(),
size_of_fields: std::mem::size_of::<C::Fields>(), size_of_fields: std::mem::size_of::<C::Fields>(),
heap_size_of_fields: heap_size,
memos: memos.memory_usage(), memos: memos.memory_usage(),
} }
} }

View file

@ -44,6 +44,11 @@ pub trait Configuration: Sized + 'static {
/// The end user struct /// The end user struct
type Struct<'db>: Copy + FromId + AsId; type Struct<'db>: Copy + FromId + AsId;
/// Returns the size of any heap allocations in the output value, in bytes.
fn heap_size(_value: &Self::Fields<'_>) -> Option<usize> {
None
}
} }
pub trait InternedData: Sized + Eq + Hash + Clone + Sync + Send {} pub trait InternedData: Sized + Eq + Hash + Clone + Sync + Send {}
@ -199,6 +204,7 @@ where
/// lock must be held for the shard containing the value. /// lock must be held for the shard containing the value.
#[cfg(all(not(feature = "shuttle"), feature = "salsa_unstable"))] #[cfg(all(not(feature = "shuttle"), feature = "salsa_unstable"))]
unsafe fn memory_usage(&self, memo_table_types: &MemoTableTypes) -> crate::database::SlotInfo { unsafe fn memory_usage(&self, memo_table_types: &MemoTableTypes) -> crate::database::SlotInfo {
let heap_size = C::heap_size(self.fields());
// SAFETY: The caller guarantees we hold the lock for the shard containing the value, so we // SAFETY: The caller guarantees we hold the lock for the shard containing the value, so we
// have at-least read-only access to the value's memos. // have at-least read-only access to the value's memos.
let memos = unsafe { &*self.memos.get() }; let memos = unsafe { &*self.memos.get() };
@ -209,6 +215,7 @@ where
debug_name: C::DEBUG_NAME, debug_name: C::DEBUG_NAME,
size_of_metadata: std::mem::size_of::<Self>() - std::mem::size_of::<C::Fields<'_>>(), size_of_metadata: std::mem::size_of::<Self>() - std::mem::size_of::<C::Fields<'_>>(),
size_of_fields: std::mem::size_of::<C::Fields<'_>>(), size_of_fields: std::mem::size_of::<C::Fields<'_>>(),
heap_size_of_fields: heap_size,
memos: memos.memory_usage(), memos: memos.memory_usage(),
} }
} }

View file

@ -14,7 +14,7 @@ pub struct MemoTable {
} }
impl MemoTable { impl MemoTable {
/// Create a `MemoTable` with slots for memos from the provided `MemoTableTypes`. /// Create a `MemoTable` with slots for memos from the provided `MemoTableTypes`.
/// ///
/// # Safety /// # Safety
/// ///
@ -127,6 +127,7 @@ impl Memo for DummyMemo {
debug_name: "dummy", debug_name: "dummy",
size_of_metadata: 0, size_of_metadata: 0,
size_of_fields: 0, size_of_fields: 0,
heap_size_of_fields: None,
memos: Vec::new(), memos: Vec::new(),
}, },
} }

View file

@ -90,6 +90,11 @@ pub trait Configuration: Sized + 'static {
old_fields: *mut Self::Fields<'db>, old_fields: *mut Self::Fields<'db>,
new_fields: Self::Fields<'db>, new_fields: Self::Fields<'db>,
) -> bool; ) -> bool;
/// Returns the size of any heap allocations in the output value, in bytes.
fn heap_size(_value: &Self::Fields<'_>) -> Option<usize> {
None
}
} }
// ANCHOR_END: Configuration // ANCHOR_END: Configuration
@ -935,6 +940,7 @@ where
/// The `MemoTable` must belong to a `Value` of the correct type. /// The `MemoTable` must belong to a `Value` of the correct type.
#[cfg(feature = "salsa_unstable")] #[cfg(feature = "salsa_unstable")]
unsafe fn memory_usage(&self, memo_table_types: &MemoTableTypes) -> crate::database::SlotInfo { unsafe fn memory_usage(&self, memo_table_types: &MemoTableTypes) -> crate::database::SlotInfo {
let heap_size = C::heap_size(self.fields());
// SAFETY: The caller guarantees this is the correct types table. // SAFETY: The caller guarantees this is the correct types table.
let memos = unsafe { memo_table_types.attach_memos(&self.memos) }; let memos = unsafe { memo_table_types.attach_memos(&self.memos) };
@ -942,6 +948,7 @@ where
debug_name: C::DEBUG_NAME, debug_name: C::DEBUG_NAME,
size_of_metadata: mem::size_of::<Self>() - mem::size_of::<C::Fields<'_>>(), size_of_metadata: mem::size_of::<Self>() - mem::size_of::<C::Fields<'_>>(),
size_of_fields: mem::size_of::<C::Fields<'_>>(), size_of_fields: mem::size_of::<C::Fields<'_>>(),
heap_size_of_fields: heap_size,
memos: memos.memory_usage(), memos: memos.memory_usage(),
} }
} }

View file

@ -25,7 +25,4 @@ struct InputWithTrackedField {
field: u32, field: u32,
} }
#[salsa::input(heap_size = size)]
struct InputWithHeapSize(u32);
fn main() {} fn main() {}

View file

@ -47,12 +47,6 @@ error: `#[tracked]` cannot be used with `#[salsa::input]`
25 | | field: u32, 25 | | field: u32,
| |______________^ | |______________^
error: `heap_size` option not allowed here
--> tests/compile-fail/input_struct_incompatibles.rs:28:16
|
28 | #[salsa::input(heap_size = size)]
| ^^^^^^^^^
error: cannot find attribute `tracked` in this scope error: cannot find attribute `tracked` in this scope
--> tests/compile-fail/input_struct_incompatibles.rs:24:7 --> tests/compile-fail/input_struct_incompatibles.rs:24:7
| |

View file

@ -39,9 +39,4 @@ struct InternedWithZeroRevisions {
field: u32, field: u32,
} }
#[salsa::interned(heap_size = size)]
struct AccWithHeapSize {
field: u32,
}
fn main() {} fn main() {}

View file

@ -41,12 +41,6 @@ error: `#[tracked]` cannot be used with `#[salsa::interned]`
34 | | field: u32, 34 | | field: u32,
| |______________^ | |______________^
error: `heap_size` option not allowed here
--> tests/compile-fail/interned_struct_incompatibles.rs:42:19
|
42 | #[salsa::interned(heap_size = size)]
| ^^^^^^^^^
error: cannot find attribute `tracked` in this scope error: cannot find attribute `tracked` in this scope
--> tests/compile-fail/interned_struct_incompatibles.rs:33:7 --> tests/compile-fail/interned_struct_incompatibles.rs:33:7
| |

View file

@ -33,9 +33,4 @@ struct TrackedStructWithRevisions {
field: u32, field: u32,
} }
#[salsa::tracked(heap_size = size)]
struct TrackedStructWithHeapSize {
field: u32,
}
fn main() {} fn main() {}

View file

@ -39,9 +39,3 @@ error: `revisions` option not allowed here
| |
31 | #[salsa::tracked(revisions = 12)] 31 | #[salsa::tracked(revisions = 12)]
| ^^^^^^^^^ | ^^^^^^^^^
error: `heap_size` option not allowed here
--> tests/compile-fail/tracked_struct_incompatibles.rs:36:18
|
36 | #[salsa::tracked(heap_size = size)]
| ^^^^^^^^^

View file

@ -2,19 +2,19 @@
use expect_test::expect; use expect_test::expect;
#[salsa::input] #[salsa::input(heap_size = string_tuple_size_of)]
struct MyInput { struct MyInput {
field: u32, field: String,
} }
#[salsa::tracked] #[salsa::tracked(heap_size = string_tuple_size_of)]
struct MyTracked<'db> { struct MyTracked<'db> {
field: u32, field: String,
} }
#[salsa::interned] #[salsa::interned(heap_size = string_tuple_size_of)]
struct MyInterned<'db> { struct MyInterned<'db> {
field: u32, field: String,
} }
#[salsa::tracked] #[salsa::tracked]
@ -32,12 +32,16 @@ fn input_to_string<'db>(_db: &'db dyn salsa::Database) -> String {
"a".repeat(1000) "a".repeat(1000)
} }
#[salsa::tracked(heap_size = string_heap_size)] #[salsa::tracked(heap_size = string_size_of)]
fn input_to_string_get_size<'db>(_db: &'db dyn salsa::Database) -> String { fn input_to_string_get_size<'db>(_db: &'db dyn salsa::Database) -> String {
"a".repeat(1000) "a".repeat(1000)
} }
fn string_heap_size(x: &String) -> usize { fn string_size_of(x: &String) -> usize {
x.capacity()
}
fn string_tuple_size_of((x,): &(String,)) -> usize {
x.capacity() x.capacity()
} }
@ -56,9 +60,9 @@ fn input_to_tracked_tuple<'db>(
fn test() { fn test() {
let db = salsa::DatabaseImpl::new(); let db = salsa::DatabaseImpl::new();
let input1 = MyInput::new(&db, 1); let input1 = MyInput::new(&db, "a".repeat(50));
let input2 = MyInput::new(&db, 2); let input2 = MyInput::new(&db, "a".repeat(150));
let input3 = MyInput::new(&db, 3); let input3 = MyInput::new(&db, "a".repeat(250));
let _tracked1 = input_to_tracked(&db, input1); let _tracked1 = input_to_tracked(&db, input1);
let _tracked2 = input_to_tracked(&db, input2); let _tracked2 = input_to_tracked(&db, input2);
@ -79,32 +83,43 @@ fn test() {
IngredientInfo { IngredientInfo {
debug_name: "MyInput", debug_name: "MyInput",
count: 3, count: 3,
size_of_metadata: 84, size_of_metadata: 96,
size_of_fields: 12, size_of_fields: 72,
heap_size_of_fields: Some(
450,
),
}, },
IngredientInfo { IngredientInfo {
debug_name: "MyTracked", debug_name: "MyTracked",
count: 4, count: 4,
size_of_metadata: 112, size_of_metadata: 128,
size_of_fields: 16, size_of_fields: 96,
heap_size_of_fields: Some(
300,
),
}, },
IngredientInfo { IngredientInfo {
debug_name: "MyInterned", debug_name: "MyInterned",
count: 3, count: 3,
size_of_metadata: 156, size_of_metadata: 168,
size_of_fields: 12, size_of_fields: 72,
heap_size_of_fields: Some(
450,
),
}, },
IngredientInfo { IngredientInfo {
debug_name: "input_to_string::interned_arguments", debug_name: "input_to_string::interned_arguments",
count: 1, count: 1,
size_of_metadata: 56, size_of_metadata: 56,
size_of_fields: 0, size_of_fields: 0,
heap_size_of_fields: None,
}, },
IngredientInfo { IngredientInfo {
debug_name: "input_to_string_get_size::interned_arguments", debug_name: "input_to_string_get_size::interned_arguments",
count: 1, count: 1,
size_of_metadata: 56, size_of_metadata: 56,
size_of_fields: 0, size_of_fields: 0,
heap_size_of_fields: None,
}, },
]"#]]; ]"#]];
@ -124,6 +139,7 @@ fn test() {
count: 3, count: 3,
size_of_metadata: 192, size_of_metadata: 192,
size_of_fields: 24, size_of_fields: 24,
heap_size_of_fields: None,
}, },
), ),
( (
@ -133,6 +149,7 @@ fn test() {
count: 1, count: 1,
size_of_metadata: 40, size_of_metadata: 40,
size_of_fields: 24, size_of_fields: 24,
heap_size_of_fields: None,
}, },
), ),
( (
@ -141,7 +158,10 @@ fn test() {
debug_name: "alloc::string::String", debug_name: "alloc::string::String",
count: 1, count: 1,
size_of_metadata: 40, size_of_metadata: 40,
size_of_fields: 1024, size_of_fields: 24,
heap_size_of_fields: Some(
1000,
),
}, },
), ),
( (
@ -151,6 +171,7 @@ fn test() {
count: 2, count: 2,
size_of_metadata: 192, size_of_metadata: 192,
size_of_fields: 16, size_of_fields: 16,
heap_size_of_fields: None,
}, },
), ),
( (
@ -160,6 +181,7 @@ fn test() {
count: 1, count: 1,
size_of_metadata: 132, size_of_metadata: 132,
size_of_fields: 16, size_of_fields: 16,
heap_size_of_fields: None,
}, },
), ),
]"#]]; ]"#]];