@@ -68,13 +68,13 @@ pub fn print_hir_stats(tcx: TyCtxt<'_>) {
6868 collector. print ( "HIR STATS" , "hir-stats" ) ;
6969}
7070
71- pub fn print_ast_stats ( krate : & ast:: Crate , title : & str , prefix : & str ) {
71+ pub fn print_ast_stats ( krate : & ast:: Crate ) {
7272 use rustc_ast:: visit:: Visitor ;
7373
7474 let mut collector =
7575 StatCollector { tcx : None , nodes : FxHashMap :: default ( ) , seen : FxHashSet :: default ( ) } ;
7676 collector. visit_crate ( krate) ;
77- collector. print ( title , prefix ) ;
77+ collector. print ( "POST EXPANSION AST STATS" , "ast-stats" ) ;
7878}
7979
8080impl < ' k > StatCollector < ' k > {
@@ -117,28 +117,45 @@ impl<'k> StatCollector<'k> {
117117 }
118118
119119 fn print ( & self , title : & str , prefix : & str ) {
120+ use std:: fmt:: Write ;
121+
120122 // We will soon sort, so the initial order does not matter.
121123 #[ allow( rustc:: potential_query_instability) ]
122124 let mut nodes: Vec < _ > = self . nodes . iter ( ) . collect ( ) ;
123125 nodes. sort_by_cached_key ( |( label, node) | ( node. stats . accum_size ( ) , label. to_owned ( ) ) ) ;
124126
127+ let name_w = 18 ;
128+ let acc_size1_w = 10 ;
129+ let acc_size2_w = 8 ; // " (NN.N%)"
130+ let acc_size_w = acc_size1_w + acc_size2_w;
131+ let count_w = 14 ;
132+ let item_size_w = 14 ;
133+ let banner_w = name_w + acc_size_w + count_w + item_size_w;
134+
125135 let total_size = nodes. iter ( ) . map ( |( _, node) | node. stats . accum_size ( ) ) . sum ( ) ;
126136 let total_count = nodes. iter ( ) . map ( |( _, node) | node. stats . count ) . sum ( ) ;
127137
128- eprintln ! ( "{prefix} {title}" ) ;
129- eprintln ! (
130- "{} {:<18}{:>18}{:>14}{:>14}" ,
131- prefix, "Name" , "Accumulated Size" , "Count" , "Item Size"
138+ // We write all the text into a string and print it with a single
139+ // `eprint!`. This is an attempt to minimize interleaved text if multiple
140+ // rustc processes are printing macro-stats at the same time (e.g. with
141+ // `RUSTFLAGS='-Zinput-stats' cargo build`). It still doesn't guarantee
142+ // non-interleaving, though.
143+ let mut s = String :: new ( ) ;
144+ _ = writeln ! ( s, "{prefix} {title}" ) ;
145+ _ = writeln ! (
146+ s,
147+ "{prefix} {:<name_w$}{:>acc_size_w$}{:>count_w$}{:>item_size_w$}" ,
148+ "Name" , "Accumulated Size" , "Count" , "Item Size"
132149 ) ;
133- eprintln ! ( "{prefix} ----------------------------------------------------------------" ) ;
150+ _ = writeln ! ( s , "{prefix} {}" , "-" . repeat ( banner_w ) ) ;
134151
135152 let percent = |m, n| ( m * 100 ) as f64 / n as f64 ;
136153
137154 for ( label, node) in nodes {
138155 let size = node. stats . accum_size ( ) ;
139- eprintln ! (
140- "{} {:<18}{:>10} ({:4.1}%){:>14}{:>14}" ,
141- prefix,
156+ _ = writeln ! (
157+ s ,
158+ "{ prefix} {:<name_w$}{:>acc_size1_w$} ({:4.1}%){:>count_w$}{:>item_size_w$}" ,
142159 label,
143160 usize_with_underscores( size) ,
144161 percent( size, total_size) ,
@@ -155,9 +172,9 @@ impl<'k> StatCollector<'k> {
155172
156173 for ( label, subnode) in subnodes {
157174 let size = subnode. accum_size ( ) ;
158- eprintln ! (
159- "{} - {:<18}{:>10} ({:4.1}%){:>14}" ,
160- prefix,
175+ _ = writeln ! (
176+ s ,
177+ "{ prefix} - {:<name_w$}{:>acc_size1_w$} ({:4.1}%){:>count_w$}" ,
161178 label,
162179 usize_with_underscores( size) ,
163180 percent( size, total_size) ,
@@ -166,15 +183,17 @@ impl<'k> StatCollector<'k> {
166183 }
167184 }
168185 }
169- eprintln ! ( "{prefix} ----------------------------------------------------------------" ) ;
170- eprintln ! (
171- "{} {:<18}{:>10} {:>14}" ,
172- prefix,
186+ _ = writeln ! ( s , "{prefix} {}" , "-" . repeat ( banner_w ) ) ;
187+ _ = writeln ! (
188+ s ,
189+ "{ prefix} {:<name_w$}{:>acc_size1_w$}{:>acc_size2_w$}{:>count_w$}" ,
173190 "Total" ,
174191 usize_with_underscores( total_size) ,
192+ "" ,
175193 usize_with_underscores( total_count) ,
176194 ) ;
177- eprintln ! ( "{prefix}" ) ;
195+ _ = writeln ! ( s, "{prefix}" ) ;
196+ eprint ! ( "{s}" ) ;
178197 }
179198}
180199
0 commit comments