@@ -138,98 +138,66 @@ impl dyn Database {
138138}
139139
140140#[ cfg( feature = "salsa_unstable" ) ]
141- pub use memory_usage:: IngredientInfo ;
142-
143- #[ cfg( feature = "salsa_unstable" ) ]
144- pub ( crate ) use memory_usage:: { MemoInfo , SlotInfo } ;
141+ pub use memory_usage:: { MemoMemoryInfo , MemoryUsageVisitor , StructMemoryInfo } ;
145142
146143#[ cfg( feature = "salsa_unstable" ) ]
147144mod memory_usage {
148145 use crate :: Database ;
149- use hashbrown:: HashMap ;
150146
151- impl dyn Database {
152- /// Returns information about any Salsa structs.
153- pub fn structs_info ( & self ) -> Vec < IngredientInfo > {
154- self . zalsa ( )
155- . ingredients ( )
156- . filter_map ( |ingredient| {
157- let mut size_of_fields = 0 ;
158- let mut size_of_metadata = 0 ;
159- let mut instances = 0 ;
160- let mut heap_size_of_fields = None ;
161-
162- for slot in ingredient. memory_usage ( self ) ? {
163- instances += 1 ;
164- size_of_fields += slot. size_of_fields ;
165- size_of_metadata += slot. size_of_metadata ;
166-
167- if let Some ( slot_heap_size) = slot. heap_size_of_fields {
168- heap_size_of_fields =
169- Some ( heap_size_of_fields. unwrap_or_default ( ) + slot_heap_size) ;
170- }
171- }
172-
173- Some ( IngredientInfo {
174- count : instances,
175- size_of_fields,
176- size_of_metadata,
177- heap_size_of_fields,
178- debug_name : ingredient. debug_name ( ) ,
179- } )
180- } )
181- . collect ( )
147+ pub trait MemoryUsageVisitor : std:: any:: Any {
148+ fn visit_tracked_struct ( & mut self , info : StructMemoryInfo ) {
149+ self . visit_struct ( info) ;
182150 }
183151
184- /// Returns information about any memoized Salsa queries.
185- ///
186- /// The returned map holds memory usage information for memoized values of a given query, keyed
187- /// by the query function name.
188- pub fn queries_info ( & self ) -> HashMap < & ' static str , IngredientInfo > {
189- let mut queries = HashMap :: new ( ) ;
190-
191- for input_ingredient in self . zalsa ( ) . ingredients ( ) {
192- let Some ( input_info) = input_ingredient. memory_usage ( self ) else {
193- continue ;
194- } ;
195-
196- for input in input_info {
197- for memo in input. memos {
198- let info = queries. entry ( memo. debug_name ) . or_insert ( IngredientInfo {
199- debug_name : memo. output . debug_name ,
200- ..Default :: default ( )
201- } ) ;
202-
203- info. count += 1 ;
204- info. size_of_fields += memo. output . size_of_fields ;
205- info. size_of_metadata += memo. output . size_of_metadata ;
206-
207- if let Some ( memo_heap_size) = memo. output . heap_size_of_fields {
208- info. heap_size_of_fields =
209- Some ( info. heap_size_of_fields . unwrap_or_default ( ) + memo_heap_size) ;
210- }
211- }
212- }
213- }
152+ fn visit_memo ( & mut self , info : MemoMemoryInfo ) {
153+ let _ = info;
154+ }
155+
156+ fn visit_input_struct ( & mut self , info : StructMemoryInfo ) {
157+ self . visit_struct ( info) ;
158+ }
159+
160+ fn visit_interned_struct ( & mut self , info : StructMemoryInfo ) {
161+ self . visit_struct ( info) ;
162+ }
163+
164+ fn visit_struct ( & mut self , info : StructMemoryInfo ) {
165+ let _ = info;
166+ }
214167
215- queries
168+ fn add_detail ( & mut self , name : & ' static str , size : usize ) {
169+ let ( _, _) = ( name, size) ;
216170 }
217171 }
218172
219- /// Information about instances of a particular Salsa ingredient.
220- #[ derive( Default , Debug , PartialEq , Eq , PartialOrd , Ord ) ]
221- pub struct IngredientInfo {
222- debug_name : & ' static str ,
223- count : usize ,
224- size_of_metadata : usize ,
225- size_of_fields : usize ,
226- heap_size_of_fields : Option < usize > ,
173+ impl dyn Database {
174+ /// Collects information about the memory usage of salsa structs and query functions.
175+ pub fn memory_usage ( & self , visitor : & mut dyn MemoryUsageVisitor ) {
176+ for ingredient in self . zalsa ( ) . ingredients ( ) {
177+ ingredient. memory_usage ( self , visitor) ;
178+ }
179+ }
180+ }
181+
182+ /// Memory usage information about a particular instance of struct, input, output, or memo.
183+ #[ derive( Debug , PartialEq , Eq ) ]
184+ pub struct MemoMemoryInfo {
185+ pub ( crate ) query_debug_name : & ' static str ,
186+ pub ( crate ) result_debug_name : & ' static str ,
187+ pub ( crate ) size_of_metadata : usize ,
188+ pub ( crate ) size_of_fields : usize ,
189+ pub ( crate ) heap_size_of_fields : Option < usize > ,
227190 }
228191
229- impl IngredientInfo {
192+ impl MemoMemoryInfo {
230193 /// Returns the debug name of the ingredient.
231- pub fn debug_name ( & self ) -> & ' static str {
232- self . debug_name
194+ pub fn query_debug_name ( & self ) -> & ' static str {
195+ self . query_debug_name
196+ }
197+
198+ /// Returns the debug name of the ingredient.
199+ pub fn result_debug_name ( & self ) -> & ' static str {
200+ self . result_debug_name
233201 }
234202
235203 /// Returns the total stack size of the fields of any instances of this ingredient, in bytes.
@@ -248,25 +216,37 @@ mod memory_usage {
248216 pub fn size_of_metadata ( & self ) -> usize {
249217 self . size_of_metadata
250218 }
251-
252- /// Returns the number of instances of this ingredient.
253- pub fn count ( & self ) -> usize {
254- self . count
255- }
256219 }
257220
258- /// Memory usage information about a particular instance of struct, input or output.
259- pub struct SlotInfo {
221+ # [ derive ( Debug , PartialEq , Eq ) ]
222+ pub struct StructMemoryInfo {
260223 pub ( crate ) debug_name : & ' static str ,
261224 pub ( crate ) size_of_metadata : usize ,
262225 pub ( crate ) size_of_fields : usize ,
263226 pub ( crate ) heap_size_of_fields : Option < usize > ,
264- pub ( crate ) memos : Vec < MemoInfo > ,
265227 }
266228
267- /// Memory usage information about a particular memo.
268- pub struct MemoInfo {
269- pub ( crate ) debug_name : & ' static str ,
270- pub ( crate ) output : SlotInfo ,
229+ impl StructMemoryInfo {
230+ /// Returns the debug name of the ingredient.
231+ pub fn debug_name ( & self ) -> & ' static str {
232+ self . debug_name
233+ }
234+
235+ /// Returns the total stack size of the fields of any instances of this ingredient, in bytes.
236+ pub fn size_of_fields ( & self ) -> usize {
237+ self . size_of_fields
238+ }
239+
240+ /// Returns the total heap size of the fields of any instances of this ingredient, in bytes.
241+ ///
242+ /// Returns `None` if the ingredient doesn't specify a `heap_size` function.
243+ pub fn heap_size_of_fields ( & self ) -> Option < usize > {
244+ self . heap_size_of_fields
245+ }
246+
247+ /// Returns the total size of Salsa metadata of any instances of this ingredient, in bytes.
248+ pub fn size_of_metadata ( & self ) -> usize {
249+ self . size_of_metadata
250+ }
271251 }
272252}
0 commit comments