Skip to content

Commit 7206038

Browse files
committed
Replace summarize binary invocation in collector with the measureme crate
Also removes support for parsing the old 3 file self-profile results.
1 parent a3de32d commit 7206038

File tree

4 files changed

+37
-105
lines changed

4 files changed

+37
-105
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

collector/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ object = "0.32.1"
4141
tabled = { version = "0.14.0" , features = ["ansi-str"]}
4242
humansize = "2.1.3"
4343
regex = "1.7.1"
44+
analyzeme = { git = "https://github.com/rust-lang/measureme", branch = "stable" }
4445

4546
benchlib = { path = "benchlib" }
4647

collector/src/compile/execute/bencher.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use futures::{future, StreamExt};
1616
use std::collections::VecDeque;
1717
use std::future::Future;
1818
use std::io::Read;
19-
use std::path::{Path, PathBuf};
19+
use std::path::PathBuf;
2020
use std::pin::Pin;
2121
use std::process::Command;
2222
use std::{env, process};
@@ -214,7 +214,8 @@ impl<'a> Processor for BenchProcessor<'a> {
214214
}
215215
Err(
216216
e @ (DeserializeStatError::ParseError { .. }
217-
| DeserializeStatError::XperfError(..)),
217+
| DeserializeStatError::XperfError(..)
218+
| DeserializeStatError::IOError(..)),
218219
) => {
219220
panic!("process_perf_stat_output failed: {:?}", e);
220221
}

collector/src/compile/execute/mod.rs

Lines changed: 32 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ use crate::compile::benchmark::BenchmarkName;
88
use crate::toolchain::Toolchain;
99
use crate::utils::fs::EnsureImmutableFile;
1010
use crate::{async_command_output, command_output, utils};
11+
use analyzeme::ArtifactSize;
1112
use anyhow::Context;
1213
use bencher::Bencher;
13-
use database::QueryLabel;
1414
use std::collections::HashMap;
1515
use std::env;
1616
use std::fs;
1717
use std::future::Future;
18+
use std::io::ErrorKind;
1819
use std::path::{Path, PathBuf};
1920
use std::pin::Pin;
2021
use std::process::{self, Command};
@@ -467,7 +468,7 @@ fn store_artifact_sizes_into_stats(stats: &mut Stats, profile: &SelfProfile) {
467468
for artifact in profile.artifact_sizes.iter() {
468469
stats
469470
.stats
470-
.insert(format!("size:{}", artifact.label), artifact.size as f64);
471+
.insert(format!("size:{}", artifact.label), artifact.value as f64);
471472
}
472473
}
473474

@@ -479,6 +480,8 @@ enum DeserializeStatError {
479480
ParseError(String, #[source] ::std::num::ParseFloatError),
480481
#[error("could not process xperf data")]
481482
XperfError(#[from] anyhow::Error),
483+
#[error("io error")]
484+
IOError(#[from] std::io::Error),
482485
}
483486

484487
enum SelfProfileFiles {
@@ -574,7 +577,7 @@ fn process_stat_output(
574577
return Err(DeserializeStatError::NoOutput(output));
575578
}
576579
let (profile, files) = match (self_profile_dir, self_profile_crate) {
577-
(Some(dir), Some(krate)) => parse_self_profile(dir, krate),
580+
(Some(dir), Some(krate)) => parse_self_profile(dir, krate)?,
578581
_ => (None, None),
579582
};
580583
Ok((stats, profile, files))
@@ -616,115 +619,41 @@ pub struct SelfProfile {
616619
pub artifact_sizes: Vec<ArtifactSize>,
617620
}
618621

619-
#[derive(serde::Deserialize, Clone)]
620-
pub struct ArtifactSize {
621-
pub label: QueryLabel,
622-
#[serde(rename = "value")]
623-
pub size: u64,
624-
}
625-
626622
fn parse_self_profile(
627623
dir: PathBuf,
628624
crate_name: String,
629-
) -> (Option<SelfProfile>, Option<SelfProfileFiles>) {
630-
// First, find the mm_profdata file prefix, or a single file containing the self-profile
631-
// results.
632-
let mut prefix = None;
625+
) -> std::io::Result<(Option<SelfProfile>, Option<SelfProfileFiles>)> {
626+
// First, find the `.mm_profdata` file with the self-profile data.
633627
let mut full_path = None;
634628
// We don't know the pid of rustc, and can't easily get it -- we only know the
635629
// `perf` pid. So just blindly look in the directory to hopefully find it.
636-
for entry in fs::read_dir(&dir).unwrap() {
637-
let entry = entry.unwrap();
638-
if entry
639-
.file_name()
640-
.to_str()
641-
.map_or(false, |s| s.starts_with(&crate_name))
642-
{
643-
if entry.file_name().to_str().unwrap().ends_with("mm_profdata") {
644-
full_path = Some(entry.path());
645-
break;
646-
}
647-
let file = entry.file_name().to_str().unwrap().to_owned();
648-
let new_prefix = Some(file[..file.find('.').unwrap()].to_owned());
649-
assert!(
650-
prefix.is_none() || prefix == new_prefix,
651-
"prefix={:?}, new_prefix={:?}",
652-
prefix,
653-
new_prefix
654-
);
655-
prefix = new_prefix;
630+
for entry in fs::read_dir(dir)? {
631+
let entry = entry?;
632+
if entry.file_name().to_str().map_or(false, |s| {
633+
s.starts_with(&crate_name) && s.ends_with("mm_profdata")
634+
}) {
635+
full_path = Some(entry.path());
636+
break;
656637
}
657638
}
658639
let (profile, files) = if let Some(profile_path) = full_path {
659-
// measureme 0.8 has a single file
660-
let filename = profile_path.file_name().unwrap().to_str().unwrap();
661-
let json = run_summarize("summarize", &dir, filename)
662-
.unwrap_or_else(|e1| match run_summarize("summarize-9.0", &dir, filename) {
663-
Ok(s) => s,
664-
Err(e2) => {
665-
panic!("failed to run summarize and summarize-9.0. Errors:\nsummarize: {:?}\nsummarize-9.0: {:?}", e1, e2);
666-
}
667-
});
668-
let profile: SelfProfile = serde_json::from_str(&json).unwrap();
669-
(profile, SelfProfileFiles::Eight { file: profile_path })
670-
} else {
671-
let Some(prefix) = prefix else {
672-
return (None, None);
640+
// measureme 0.8+ uses a single file
641+
let data = fs::read(&profile_path)?;
642+
let results = analyzeme::ProfilingData::from_paged_buffer(data, None)
643+
.map_err(|error| {
644+
eprintln!("Cannot read self-profile data: {error:?}");
645+
std::io::Error::new(ErrorKind::InvalidData, error)
646+
})?
647+
.perform_analysis();
648+
let profile = SelfProfile {
649+
artifact_sizes: results.artifact_sizes,
673650
};
674-
675-
let mut string_index = PathBuf::new();
676-
let mut string_data = PathBuf::new();
677-
let mut events = PathBuf::new();
678-
for entry in fs::read_dir(&dir).unwrap() {
679-
let filename = entry.unwrap().file_name();
680-
let filename_str = filename.to_str().unwrap();
681-
let path = dir.join(filename_str);
682-
if filename_str.ends_with(".events") {
683-
assert!(filename_str.contains(&prefix), "{:?}", path);
684-
events = path;
685-
} else if filename_str.ends_with(".string_data") {
686-
assert!(filename_str.contains(&prefix), "{:?}", path);
687-
string_data = path;
688-
} else if filename_str.ends_with(".string_index") {
689-
assert!(filename_str.contains(&prefix), "{:?}", path);
690-
string_index = path;
691-
}
692-
}
693-
694-
let files = SelfProfileFiles::Seven {
695-
string_index,
696-
string_data,
697-
events,
698-
};
699-
700-
let json = run_summarize("summarize", &dir, &prefix)
701-
.or_else(|_| run_summarize("summarize-0.7", &dir, &prefix))
702-
.expect("able to run summarize or summarize-0.7");
703-
let profile: SelfProfile = serde_json::from_str(&json).unwrap();
704-
(profile, files)
651+
let files = SelfProfileFiles::Eight { file: profile_path };
652+
(Some(profile), Some(files))
653+
} else {
654+
// The old "3 files format" is not supported by analyzeme anymore, so we don't handle it
655+
// here.
656+
(None, None)
705657
};
706-
(Some(profile), Some(files))
707-
}
708-
709-
fn run_summarize(name: &str, prof_out_dir: &Path, prefix: &str) -> anyhow::Result<String> {
710-
let mut cmd = Command::new(name);
711-
cmd.current_dir(prof_out_dir);
712-
cmd.arg("summarize").arg("--json");
713-
cmd.arg(prefix);
714-
let status = cmd
715-
.status()
716-
.with_context(|| format!("Command::new({}).status() failed", name))?;
717-
if !status.success() {
718-
anyhow::bail!(
719-
"failed to run {} in {:?} with prefix {:?}",
720-
name,
721-
prof_out_dir,
722-
prefix
723-
)
724-
}
725-
let json = prof_out_dir.join(format!(
726-
"{}.json",
727-
prefix.strip_suffix(".mm_profdata").unwrap_or(prefix)
728-
));
729-
fs::read_to_string(&json).with_context(|| format!("failed to read {:?}", json))
658+
Ok((profile, files))
730659
}

0 commit comments

Comments
 (0)