@@ -13,6 +13,7 @@ use std::fmt;
13
13
use std:: fs:: { self , File } ;
14
14
use std:: hash;
15
15
use std:: io:: Read ;
16
+ use std:: io:: Write ;
16
17
use std:: mem:: ManuallyDrop ;
17
18
use std:: path:: { Path , PathBuf } ;
18
19
use std:: process:: { self , Command } ;
@@ -178,6 +179,7 @@ pub enum Profiler {
178
179
Massif ,
179
180
Eprintln ,
180
181
LlvmLines ,
182
+ MonoItems ,
181
183
}
182
184
183
185
impl Profiler {
@@ -198,6 +200,7 @@ impl Profiler {
198
200
"massif" => Ok ( Profiler :: Massif ) ,
199
201
"eprintln" => Ok ( Profiler :: Eprintln ) ,
200
202
"llvm-lines" => Ok ( Profiler :: LlvmLines ) ,
203
+ "mono-items" => Ok ( Profiler :: MonoItems ) ,
201
204
_ => Err ( anyhow ! ( "'{}' is not a known profiler" , name) ) ,
202
205
}
203
206
}
@@ -218,6 +221,7 @@ impl Profiler {
218
221
Profiler :: Massif => "massif" ,
219
222
Profiler :: Eprintln => "eprintln" ,
220
223
Profiler :: LlvmLines => "llvm-lines" ,
224
+ Profiler :: MonoItems => "mono-items" ,
221
225
}
222
226
}
223
227
@@ -237,6 +241,7 @@ impl Profiler {
237
241
| Profiler :: Callgrind
238
242
| Profiler :: DHAT
239
243
| Profiler :: Massif
244
+ | Profiler :: MonoItems
240
245
| Profiler :: Eprintln => {
241
246
if build_kind == BuildKind :: Doc {
242
247
Some ( "rustdoc" )
@@ -265,6 +270,7 @@ impl Profiler {
265
270
| Profiler :: Callgrind
266
271
| Profiler :: DHAT
267
272
| Profiler :: Massif
273
+ | Profiler :: MonoItems
268
274
| Profiler :: Eprintln => true ,
269
275
Profiler :: LlvmLines => scenario_kind == ScenarioKind :: Full ,
270
276
}
@@ -1132,6 +1138,51 @@ impl<'a> Processor for ProfileProcessor<'a> {
1132
1138
fs:: copy ( & tmp_eprintln_file, & eprintln_file) ?;
1133
1139
}
1134
1140
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
+
1135
1186
// `cargo llvm-lines` writes its output to stdout. We copy that
1136
1187
// output into a file in the output dir.
1137
1188
Profiler :: LlvmLines => {
0 commit comments