Skip to content

Commit 49d64c7

Browse files
MonoItem collector
1 parent 18f5b87 commit 49d64c7

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

collector/src/execute.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::fmt;
1313
use std::fs::{self, File};
1414
use std::hash;
1515
use std::io::Read;
16+
use std::io::Write;
1617
use std::mem::ManuallyDrop;
1718
use std::path::{Path, PathBuf};
1819
use std::process::{self, Command};
@@ -178,6 +179,7 @@ pub enum Profiler {
178179
Massif,
179180
Eprintln,
180181
LlvmLines,
182+
MonoItems,
181183
}
182184

183185
impl 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 => {

collector/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ fn main_result() -> anyhow::Result<i32> {
537537
(@arg PROFILER: +required +takes_value
538538
"One of: 'self-profile', 'time-passes', 'perf-record',\n\
539539
'oprofile', 'cachegrind', 'callgrind', 'dhat', 'massif',\n\
540-
'eprintln', 'llvm-lines'")
540+
'eprintln', 'llvm-lines', 'mono-items'")
541541
(@arg RUSTC: +required +takes_value "The path to the local rustc to benchmark")
542542
(@arg ID: +required +takes_value "Identifier to associate benchmark results with")
543543

collector/src/rustc-fake.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,15 @@ fn main() {
284284
assert!(cmd.status().expect("failed to spawn").success());
285285
}
286286

287+
"mono-items" => {
288+
// Lazy item collection is the default (i.e., without this
289+
// option)
290+
args.push("-Zprint-mono-items=lazy".into());
291+
let mut cmd = bash_command(tool, args, "1> mono-items");
292+
293+
assert!(cmd.status().expect("failed to spawn").success());
294+
}
295+
287296
_ => {
288297
panic!("unknown wrapper: {}", wrapper);
289298
}

0 commit comments

Comments
 (0)