@@ -13,6 +13,7 @@ use std::fmt;
1313use std:: fs:: { self , File } ;
1414use std:: hash;
1515use std:: io:: Read ;
16+ use std:: io:: Write ;
1617use std:: mem:: ManuallyDrop ;
1718use std:: path:: { Path , PathBuf } ;
1819use std:: process:: { self , Command } ;
@@ -178,6 +179,7 @@ pub enum Profiler {
178179 Massif ,
179180 Eprintln ,
180181 LlvmLines ,
182+ MonoItems ,
181183}
182184
183185impl Profiler {
@@ -198,6 +200,7 @@ impl Profiler {
198200 "massif" => Ok ( Profiler :: Massif ) ,
199201 "eprintln" => Ok ( Profiler :: Eprintln ) ,
200202 "llvm-lines" => Ok ( Profiler :: LlvmLines ) ,
203+ "mono-items" => Ok ( Profiler :: MonoItems ) ,
201204 _ => Err ( anyhow ! ( "'{}' is not a known profiler" , name) ) ,
202205 }
203206 }
@@ -218,6 +221,7 @@ impl Profiler {
218221 Profiler :: Massif => "massif" ,
219222 Profiler :: Eprintln => "eprintln" ,
220223 Profiler :: LlvmLines => "llvm-lines" ,
224+ Profiler :: MonoItems => "mono-items" ,
221225 }
222226 }
223227
@@ -237,6 +241,7 @@ impl Profiler {
237241 | Profiler :: Callgrind
238242 | Profiler :: DHAT
239243 | Profiler :: Massif
244+ | Profiler :: MonoItems
240245 | Profiler :: Eprintln => {
241246 if build_kind == BuildKind :: Doc {
242247 Some ( "rustdoc" )
@@ -265,6 +270,7 @@ impl Profiler {
265270 | Profiler :: Callgrind
266271 | Profiler :: DHAT
267272 | Profiler :: Massif
273+ | Profiler :: MonoItems
268274 | Profiler :: Eprintln => true ,
269275 Profiler :: LlvmLines => scenario_kind == ScenarioKind :: Full ,
270276 }
@@ -1132,6 +1138,51 @@ impl<'a> Processor for ProfileProcessor<'a> {
11321138 fs:: copy ( & tmp_eprintln_file, & eprintln_file) ?;
11331139 }
11341140
1141+ // mono item results are redirected (via rustc-fake) to a file
1142+ // called `mono-items`. We copy it from the temp dir to the output
1143+ // dir, giving it a new name in the process.
1144+ Profiler :: MonoItems => {
1145+ let tmp_file = filepath ( data. cwd . as_ref ( ) , "mono-items" ) ;
1146+ let out_dir = self . output_dir . join ( & out_file ( "mono-items" ) ) ;
1147+ let _ = fs:: create_dir_all ( & out_dir) ;
1148+ let result_file = filepath ( & out_dir, "raw" ) ;
1149+
1150+ fs:: copy ( & tmp_file, & result_file) ?;
1151+
1152+ let mut by_cgu: HashMap < & str , Vec < ( & str , & str ) > > = HashMap :: new ( ) ;
1153+ let mono_items = std:: fs:: read_to_string ( & tmp_file) ?;
1154+ for line in mono_items. lines ( ) {
1155+ let line = if let Some ( line) = line. strip_prefix ( "MONO_ITEM " ) {
1156+ line
1157+ } else {
1158+ continue ;
1159+ } ;
1160+
1161+ let ( name, cgus) = if let Some ( parts) = line. split_once ( " @@ " ) {
1162+ parts
1163+ } else {
1164+ continue ;
1165+ } ;
1166+
1167+ for cgu in cgus. split ( ' ' ) {
1168+ let cgu_name_end = cgu. rfind ( '[' ) . expect ( & cgu) ;
1169+ let cgu_name = & cgu[ ..cgu_name_end] ;
1170+ let linkage = & cgu[ cgu_name_end + 1 ..cgu. len ( ) - 1 ] ;
1171+ by_cgu. entry ( cgu_name) . or_default ( ) . push ( ( name, linkage) ) ;
1172+ }
1173+ }
1174+
1175+ for ( cgu, items) in & by_cgu {
1176+ let cgu_file = filepath ( & out_dir, cgu) ;
1177+ let mut file = std:: io:: BufWriter :: new (
1178+ fs:: File :: create ( & cgu_file) . with_context ( || format ! ( "{:?}" , cgu_file) ) ?,
1179+ ) ;
1180+ for ( name, linkage) in items {
1181+ writeln ! ( & mut file, "{} {}" , name, linkage) ?;
1182+ }
1183+ }
1184+ }
1185+
11351186 // `cargo llvm-lines` writes its output to stdout. We copy that
11361187 // output into a file in the output dir.
11371188 Profiler :: LlvmLines => {
0 commit comments