@@ -307,65 +307,16 @@ fn inject_tracing(
307307/// Renders the tracing to a file. Adapted from
308308/// https://github.com/dfinity/ic-repl/blob/master/src/tracing.rs
309309pub ( super ) fn write_traces_to_file (
310- input : Vec < ( i32 , i64 ) > ,
310+ input : InstructionTraceGraphNode ,
311311 names : & BTreeMap < i32 , String > ,
312312 bench_fn : & str ,
313313 filename : PathBuf ,
314314) -> Result < ( ) , String > {
315315 use inferno:: flamegraph:: { from_reader, Options } ;
316- let mut stack = Vec :: new ( ) ;
317- let mut prefix = Vec :: new ( ) ;
318- let mut result = Vec :: new ( ) ;
319- let mut prev = None ;
320- for ( id, count) in input. into_iter ( ) {
321- if id >= 0 {
322- stack. push ( ( id, count, 0 ) ) ;
323- let name = if id < i32:: MAX {
324- match names. get ( & id) {
325- Some ( name) => name. clone ( ) ,
326- None => "func_" . to_string ( ) + & id. to_string ( ) ,
327- }
328- } else {
329- bench_fn. to_string ( )
330- } ;
331- prefix. push ( name) ;
332- } else {
333- let end_id = reverse_func_id ( id) ;
334- match stack. pop ( ) {
335- None => return Err ( "pop empty stack" . to_string ( ) ) ,
336- Some ( ( start_id, start, children) ) => {
337- if start_id != end_id {
338- return Err ( "func id mismatch" . to_string ( ) ) ;
339- }
340- let cost = count - start;
341- let frame = prefix. join ( ";" ) ;
342- prefix. pop ( ) . unwrap ( ) ;
343- if let Some ( ( parent, parent_cost, children_cost) ) = stack. pop ( ) {
344- stack. push ( ( parent, parent_cost, children_cost + cost) ) ;
345- }
346- match prev {
347- Some ( prev) if prev == frame => {
348- // Add an empty spacer to avoid collapsing adjacent same-named calls
349- // See https://github.com/jonhoo/inferno/issues/185#issuecomment-671393504
350- result. push ( format ! ( "{};spacer 0" , prefix. join( ";" ) ) ) ;
351- }
352- _ => ( ) ,
353- }
354- result. push ( format ! ( "{} {}" , frame, cost - children) ) ;
355- prev = Some ( frame) ;
356- }
357- }
358- }
359- }
360- let is_trace_incomplete = !stack. is_empty ( ) ;
316+ let mut result = convert_trace_graph_to_flamegraph ( input, names, bench_fn) ;
361317 let mut opt = Options :: default ( ) ;
362318 opt. count_name = "instructions" . to_string ( ) ;
363- let bench_fn = if is_trace_incomplete {
364- bench_fn. to_string ( ) + " (incomplete)"
365- } else {
366- bench_fn. to_string ( )
367- } ;
368- opt. title = bench_fn;
319+ opt. title = bench_fn. to_string ( ) ;
369320 opt. flame_chart = true ;
370321 opt. no_sort = true ;
371322 // Reserve result order to make flamegraph from left to right.
@@ -379,6 +330,49 @@ pub(super) fn write_traces_to_file(
379330 Ok ( ( ) )
380331}
381332
333+ fn convert_trace_graph_to_flamegraph (
334+ input : InstructionTraceGraphNode ,
335+ names : & BTreeMap < i32 , String > ,
336+ bench_fn : & str ,
337+ ) -> Vec < String > {
338+ let mut flamegraph = Vec :: new ( ) ;
339+ let mut prefix = Vec :: new ( ) ;
340+ convert_trace_node_to_flamegraph ( input, names, bench_fn, & mut prefix, & mut flamegraph) ;
341+ flamegraph
342+ }
343+
344+ fn convert_trace_node_to_flamegraph (
345+ input : InstructionTraceGraphNode ,
346+ names : & BTreeMap < i32 , String > ,
347+ bench_fn : & str ,
348+ prefix : & mut Vec < String > ,
349+ flamegraph : & mut Vec < String > ,
350+ ) {
351+ let InstructionTraceGraphNode {
352+ func_id,
353+ cost,
354+ children,
355+ } = input;
356+ prefix. push ( func_id_to_name ( func_id, names, bench_fn) ) ;
357+
358+ for child in children {
359+ convert_trace_node_to_flamegraph ( child, names, bench_fn, prefix, flamegraph) ;
360+ }
361+ flamegraph. push ( format ! ( "{} {}" , prefix. join( ";" ) , cost) ) ;
362+ prefix. pop ( ) ;
363+ }
364+
365+ fn func_id_to_name ( func_id : i32 , names : & BTreeMap < i32 , String > , bench_fn : & str ) -> String {
366+ if func_id < i32:: MAX {
367+ match names. get ( & func_id) {
368+ Some ( name) => name. clone ( ) ,
369+ None => "func_" . to_string ( ) + & func_id. to_string ( ) ,
370+ }
371+ } else {
372+ bench_fn. to_string ( )
373+ }
374+ }
375+
382376/// Extracts function names from the module to be a map from function id to function name.
383377fn extract_function_names ( module : & Module ) -> BTreeMap < i32 , String > {
384378 module
0 commit comments