1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Copyright 2016-2017 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A an allocator-agnostic crate for measuring the runtime size of a value
//! including the size of any heap allocations that are owned by that value.
//!
//! - The core abstraction is provided by the [`MallocSizeOf`] trait which should be implemented for all
//! types whose size you wish to measure.
//! - A derive macro for implementing this trait on structs is provided by the [malloc_size_of_derive](https://docs.rs/malloc_size_of_derive) crate
//! - Additionally there are [`MallocUnconditionalSizeOf`], [`MallocConditionalSizeOf`] traits for measuring
//! types where ownership is shared (such as `Arc` and `Rc`).
//! - Each of these traits also has a "shallow" variant ([`MallocShallowSizeOf`], [`MallocUnconditionalShallowSizeOf`], and [`MallocConditionalShallowSizeOf`]) which only measure the heap size of the value passed
//! and not any nested allocations.
//!
//! All of these traits rely on being provided with an instance of [`MallocSizeOfOps`] which allows size computations
//! to call into the allocator to ask it for the underlyinhg size of the allocations backing data structures.
//!
//! This crate is used by both Servo and Firefox for memory usage calculation.
//!
//! ## Features
//!
//! - It isn't bound to a particular heap allocator.
//! - It provides traits for both "shallow" and "deep" measurement, which gives
//! flexibility in the cases where the traits can't be used.
//! - It allows for measuring blocks even when only an interior pointer can be
//! obtained for heap allocations, e.g. `HashSet` and `HashMap`. (This relies
//! on the heap allocator having suitable support, which `jemalloc` has.)
//! - It allows handling of types like `Rc` and `Arc` by providing traits that
//! are different to the ones for non-graph structures.
//!
//! ## Suggested usage
//!
//! - When possible, use the `MallocSizeOf` trait. (Deriving support is
//! provided by the `malloc_size_of_derive` crate.)
//! - If you need an additional synchronization argument, provide a function
//! that is like the standard trait method, but with the extra argument.
//! - If you need multiple measurements for a type, provide a function named
//! `add_size_of` that takes a mutable reference to a struct that contains
//! the multiple measurement fields.
//! - When deep measurement (via `MallocSizeOf`) cannot be implemented for a
//! type, shallow measurement (via `MallocShallowSizeOf`) in combination with
//! iteration can be a useful substitute.
//! - `Rc` and `Arc` are always tricky, which is why `MallocSizeOf` is not (and
//! should not be) implemented for them.
//! - If an `Rc` or `Arc` is known to be a "primary" reference and can always
//! be measured, it should be measured via the `MallocUnconditionalSizeOf`
//! trait.
//! - If an `Rc` or `Arc` should be measured only if it hasn't been seen
//! before, it should be measured via the `MallocConditionalSizeOf` trait.
//! - Using universal function call syntax is a good idea when measuring boxed
//! fields in structs, because it makes it clear that the Box is being
//! measured as well as the thing it points to. E.g.
//! `<Box<_> as MallocSizeOf>::size_of(field, ops)`.
extern crate alloc;
use Box;
use c_void;
/// Trait for measuring the "deep" heap usage of a data structure. This is the
/// most commonly-used of the traits.
/// Trait for measuring the "shallow" heap usage of a container.
/// Like `MallocSizeOf`, but with a different name so it cannot be used
/// accidentally with derive(MallocSizeOf). For use with types like `Rc` and
/// `Arc` when appropriate (e.g. when measuring a "primary" reference).
/// `MallocUnconditionalSizeOf` combined with `MallocShallowSizeOf`.
/// Like `MallocSizeOf`, but only measures if the value hasn't already been
/// measured. For use with types like `Rc` and `Arc` when appropriate (e.g.
/// when there is no "primary" reference).
/// `MallocConditionalSizeOf` combined with `MallocShallowSizeOf`.
/// A C function that takes a pointer to a heap allocation and returns its size.
type VoidPtrToSizeFn = unsafe extern "C" fn ;
/// A closure implementing a stateful predicate on pointers.
type VoidPtrToBoolFnMut = dyn FnMut ;
/// Operations used when measuring heap usage of data structures.