Skip to content

Commit 9e94ced

Browse files
authored
Merge pull request #1657 from Kobzol/artifact-size
Store artifact sizes into the DB
2 parents 229bc65 + 134d317 commit 9e94ced

File tree

9 files changed

+206
-48
lines changed

9 files changed

+206
-48
lines changed

collector/src/bin/collector.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use collector::compile::benchmark::{
1111
compile_benchmark_dir, get_compile_benchmarks, Benchmark, BenchmarkName,
1212
};
1313
use collector::{runtime, utils, CollectorCtx, CollectorStepBuilder};
14-
use database::{ArtifactId, Commit, CommitType, Connection, Pool};
14+
use database::{ArtifactId, ArtifactIdNumber, Commit, CommitType, Connection, Pool};
1515
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
1616
use std::cmp::Ordering;
1717
use std::ffi::OsStr;
@@ -921,8 +921,8 @@ fn main_result() -> anyhow::Result<i32> {
921921
sysroot.preserve(); // don't delete it
922922

923923
// Print the directory containing the toolchain.
924-
sysroot.rustc.pop();
925-
let s = format!("{:?}", sysroot.rustc);
924+
sysroot.components.rustc.pop();
925+
let s = format!("{:?}", sysroot.components.rustc);
926926
println!("{}", &s[1..s.len() - 1]);
927927

928928
Ok(0)
@@ -978,6 +978,12 @@ fn run_benchmarks(
978978
compile: Option<CompileBenchmarkConfig>,
979979
runtime: Option<RuntimeBenchmarkConfig>,
980980
) -> anyhow::Result<()> {
981+
rt.block_on(record_toolchain_sizes(
982+
connection.as_mut(),
983+
&shared.artifact_id,
984+
&shared.toolchain,
985+
));
986+
981987
let collector = rt.block_on(init_collection(
982988
connection.as_mut(),
983989
&shared,
@@ -1190,6 +1196,38 @@ fn bench_compile(
11901196
errors
11911197
}
11921198

1199+
/// Records the sizes of individual components (rustc, libLLVM, etc.) for the given toolchain
1200+
/// and artifact id into the database.
1201+
async fn record_toolchain_sizes(
1202+
conn: &mut dyn Connection,
1203+
artifact_id: &ArtifactId,
1204+
toolchain: &Toolchain,
1205+
) {
1206+
let aid = conn.artifact_id(artifact_id).await;
1207+
1208+
async fn record(
1209+
conn: &mut dyn Connection,
1210+
aid: ArtifactIdNumber,
1211+
component: &str,
1212+
path: Option<&Path>,
1213+
) {
1214+
if let Some(path) = path {
1215+
if let Ok(size) = fs::metadata(path).map(|m| m.len()) {
1216+
conn.record_artifact_size(aid, component, size).await;
1217+
}
1218+
}
1219+
}
1220+
1221+
let paths = &toolchain.components;
1222+
record(conn, aid, "rustc", Some(&paths.rustc)).await;
1223+
record(conn, aid, "rustdoc", paths.rustdoc.as_deref()).await;
1224+
record(conn, aid, "cargo", Some(&paths.cargo)).await;
1225+
record(conn, aid, "librustc_driver", paths.lib_rustc.as_deref()).await;
1226+
record(conn, aid, "libstd", paths.lib_std.as_deref()).await;
1227+
record(conn, aid, "libtest", paths.lib_test.as_deref()).await;
1228+
record(conn, aid, "libLLVM", paths.lib_llvm.as_deref()).await;
1229+
}
1230+
11931231
fn add_perf_config(directory: &Path, category: Category) {
11941232
let data = serde_json::json!({
11951233
"category": category.to_string()

collector/src/compile/execute/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ impl<'a> CargoProcess<'a> {
144144
}
145145

146146
fn base_command(&self, cwd: &Path, subcommand: &str) -> Command {
147-
let mut cmd = Command::new(Path::new(&self.toolchain.cargo));
147+
let mut cmd = Command::new(Path::new(&self.toolchain.components.cargo));
148148
cmd
149149
// Not all cargo invocations (e.g. `cargo clean`) need all of these
150150
// env vars set, but it doesn't hurt to have them.
151151
.env("RUSTC", &*FAKE_RUSTC)
152-
.env("RUSTC_REAL", &self.toolchain.rustc)
152+
.env("RUSTC_REAL", &self.toolchain.components.rustc)
153153
// We separately pass -Cincremental to the leaf crate --
154154
// CARGO_INCREMENTAL is cached separately for both the leaf crate
155155
// and any in-tree dependencies, and we don't want that; it wastes
@@ -164,7 +164,7 @@ impl<'a> CargoProcess<'a> {
164164
.arg("--manifest-path")
165165
.arg(&self.manifest_path);
166166

167-
if let Some(r) = &self.toolchain.rustdoc {
167+
if let Some(r) = &self.toolchain.components.rustdoc {
168168
cmd.env("RUSTDOC", &*FAKE_RUSTDOC).env("RUSTDOC_REAL", r);
169169
}
170170
cmd

collector/src/compile/execute/rustc.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ fn record(
9595
.arg("rust.deny-warnings=false")
9696
.arg("--set")
9797
.arg(&format!("build.rustc={}", fake_rustc.to_str().unwrap()))
98-
.env("RUSTC_PERF_REAL_RUSTC", &toolchain.rustc)
98+
.env("RUSTC_PERF_REAL_RUSTC", &toolchain.components.rustc)
9999
.arg("--set")
100100
.arg(&format!(
101101
"build.cargo={}",
102-
toolchain.cargo.to_str().unwrap()
102+
toolchain.components.cargo.to_str().unwrap()
103103
))
104104
.status()
105105
.context("configuring")?;
@@ -114,7 +114,7 @@ fn record(
114114
.context("x.py script canonicalize")?,
115115
)
116116
.current_dir(checkout)
117-
.env("RUSTC_PERF_REAL_RUSTC", &toolchain.rustc)
117+
.env("RUSTC_PERF_REAL_RUSTC", &toolchain.components.rustc)
118118
.arg("build")
119119
.arg("--stage")
120120
.arg("0")

collector/src/runtime/benchmark.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@ fn start_cargo_build(
240240
benchmark_dir: &Path,
241241
target_dir: Option<&Path>,
242242
) -> anyhow::Result<Child> {
243-
let mut command = Command::new(&toolchain.cargo);
243+
let mut command = Command::new(&toolchain.components.cargo);
244244
command
245-
.env("RUSTC", &toolchain.rustc)
245+
.env("RUSTC", &toolchain.components.rustc)
246246
.arg("build")
247247
.arg("--release")
248248
.arg("--message-format")

collector/src/toolchain.rs

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::compile::benchmark::profile::Profile;
22
use anyhow::{anyhow, Context};
33
use log::debug;
4+
use std::ffi::OsStr;
45
use std::fs::{self, File};
56
use std::io::{BufReader, Read};
67
use std::path::{Path, PathBuf};
@@ -12,9 +13,7 @@ use xz2::bufread::XzDecoder;
1213
/// Sysroot downloaded from CI.
1314
pub struct Sysroot {
1415
pub sha: String,
15-
pub rustc: PathBuf,
16-
pub rustdoc: PathBuf,
17-
pub cargo: PathBuf,
16+
pub components: ToolchainComponents,
1817
pub triple: String,
1918
pub preserve: bool,
2019
}
@@ -121,10 +120,15 @@ impl SysrootDownload {
121120
})
122121
};
123122

123+
let components = ToolchainComponents::from_binaries_and_libdir(
124+
sysroot_bin("rustc")?,
125+
Some(sysroot_bin("rustdoc")?),
126+
sysroot_bin("cargo")?,
127+
&self.directory.join(&self.rust_sha).join("lib"),
128+
)?;
129+
124130
Ok(Sysroot {
125-
rustc: sysroot_bin("rustc")?,
126-
rustdoc: sysroot_bin("rustdoc")?,
127-
cargo: sysroot_bin("cargo")?,
131+
components,
128132
sha: self.rust_sha,
129133
triple: self.triple,
130134
preserve: false,
@@ -218,25 +222,72 @@ impl SysrootDownload {
218222
/// Representation of a toolchain that can be used to compile Rust programs.
219223
#[derive(Debug, Clone)]
220224
pub struct Toolchain {
221-
pub rustc: PathBuf,
222-
pub rustdoc: Option<PathBuf>,
223-
pub cargo: PathBuf,
225+
pub components: ToolchainComponents,
224226
pub id: String,
225227
pub triple: String,
226228
}
227229

228230
impl Toolchain {
229231
pub fn from_sysroot(sysroot: &Sysroot, id: String) -> Self {
230232
Self {
231-
rustc: sysroot.rustc.clone(),
232-
rustdoc: Some(sysroot.rustdoc.clone()),
233-
cargo: sysroot.cargo.clone(),
233+
components: sysroot.components.clone(),
234234
id,
235235
triple: sysroot.triple.clone(),
236236
}
237237
}
238238
}
239239

240+
#[derive(Debug, Clone, Default)]
241+
pub struct ToolchainComponents {
242+
pub rustc: PathBuf,
243+
pub rustdoc: Option<PathBuf>,
244+
pub cargo: PathBuf,
245+
pub lib_rustc: Option<PathBuf>,
246+
pub lib_std: Option<PathBuf>,
247+
pub lib_test: Option<PathBuf>,
248+
pub lib_llvm: Option<PathBuf>,
249+
}
250+
251+
impl ToolchainComponents {
252+
fn from_binaries_and_libdir(
253+
rustc: PathBuf,
254+
rustdoc: Option<PathBuf>,
255+
cargo: PathBuf,
256+
libdir: &Path,
257+
) -> anyhow::Result<Self> {
258+
let mut component = ToolchainComponents {
259+
rustc,
260+
rustdoc,
261+
cargo,
262+
..Default::default()
263+
};
264+
component.fill_libraries(libdir)?;
265+
Ok(component)
266+
}
267+
268+
/// Finds known library components in the given `dir` and stores them in `self`.
269+
fn fill_libraries(&mut self, dir: &Path) -> anyhow::Result<()> {
270+
for entry in fs::read_dir(dir).context("Cannot read lib dir to find components")? {
271+
let entry = entry?;
272+
let path = entry.path();
273+
if path.is_file() && path.extension() == Some(OsStr::new("so")) {
274+
if let Some(filename) = path.file_name().and_then(|s| s.to_str()) {
275+
if filename.starts_with("libLLVM") {
276+
self.lib_llvm = Some(path);
277+
} else if filename.starts_with("librustc_driver") {
278+
self.lib_rustc = Some(path);
279+
} else if filename.starts_with("libstd") {
280+
self.lib_std = Some(path);
281+
} else if filename.starts_with("libtest") {
282+
self.lib_test = Some(path);
283+
}
284+
}
285+
}
286+
}
287+
Ok(())
288+
}
289+
}
290+
240291
/// Get a toolchain from the input.
241292
/// - `rustc`: check if the given one is acceptable.
242293
/// - `rustdoc`: if one is given, check if it is acceptable. Otherwise, if
@@ -374,10 +425,10 @@ pub fn get_local_toolchain(
374425
cargo
375426
};
376427

428+
let lib_dir = get_lib_dir_from_rustc(&rustc).context("Cannot find libdir for rustc")?;
429+
377430
Ok(Toolchain {
378-
rustc,
379-
rustdoc,
380-
cargo,
431+
components: ToolchainComponents::from_binaries_and_libdir(rustc, rustdoc, cargo, &lib_dir)?,
381432
id,
382433
triple: target_triple,
383434
})
@@ -420,11 +471,25 @@ pub fn create_toolchain_from_published_version(
420471
debug!("Found rustdoc: {}", rustdoc.display());
421472
debug!("Found cargo: {}", cargo.display());
422473

474+
let lib_dir = get_lib_dir_from_rustc(&rustc)?;
475+
476+
let components =
477+
ToolchainComponents::from_binaries_and_libdir(rustc, Some(rustdoc), cargo, &lib_dir)?;
478+
423479
Ok(Toolchain {
424-
rustc,
425-
rustdoc: Some(rustdoc),
426-
cargo,
480+
components,
427481
id: toolchain.to_string(),
428482
triple: target_triple.to_string(),
429483
})
430484
}
485+
486+
fn get_lib_dir_from_rustc(rustc: &Path) -> anyhow::Result<PathBuf> {
487+
let sysroot = Command::new(rustc)
488+
.arg("--print")
489+
.arg("sysroot")
490+
.output()?
491+
.stdout;
492+
let sysroot_path = String::from_utf8_lossy(&sysroot);
493+
494+
Ok(Path::new(sysroot_path.as_ref().trim()).join("lib"))
495+
}

database/schema.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,22 @@ id name date type
6161
1 LOCAL_TEST release
6262
```
6363

64+
### artifact size
65+
66+
Records the size of individual components (like `librustc_driver.so` or `libLLVM.so`) of a single
67+
artifact.
68+
69+
This description includes:
70+
* component: normalized name of the component (hashes are removed)
71+
* size: size of the component in bytes
72+
73+
```
74+
sqlite> select * from artifact_size limit 1;
75+
aid component size
76+
---------- ---------- ----------
77+
1 libLLVM.so 177892352
78+
```
79+
6480
### collection
6581

6682
A "collection" of benchmarks tied only differing by the statistic collected.
@@ -267,26 +283,13 @@ bors_sha pr parent_sha complete requested include exclude runs commi
267283
1w0p83... 42 fq24xq... true <timestamp> 3 <timestamp>
268284
```
269285

270-
### error_series
271-
272-
Records a compile-time benchmark that caused an error.
273-
274-
This table exists to avoid duplicating benchmarks many times in the `error` table.
275-
276-
```
277-
sqlite> select * from error_series limit 1;
278-
id crate
279-
---------- -----------
280-
1 hello-world
281-
```
282-
283286
### error
284287

285-
Records a compilation error for an artifact and an entry in `error_series`.
288+
Records a compilation or runtime error for an artifact and a benchmark.
286289

287290
```
288291
sqlite> select * from error limit 1;
289-
series aid error
290-
---------- --- -----
291-
1 42 Failed to compile...
292+
aid benchmark error
293+
---------- --- -----
294+
1 syn-1.0.89 Failed to compile...
292295
```

database/src/pool.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ pub trait Connection: Send + Sync {
8686
krate: &str,
8787
value: Duration,
8888
);
89+
90+
/// Records the size of an artifact component (like `librustc_driver.so` or `libLLVM.so`) in
91+
/// bytes.
92+
async fn record_artifact_size(&self, artifact: ArtifactIdNumber, component: &str, size: u64);
93+
8994
/// Returns vector of bootstrap build times for the given artifacts. The kth
9095
/// element is the minimum build time for the kth artifact in `aids`, across
9196
/// all collections for the artifact, or none if there is no bootstrap data

0 commit comments

Comments
 (0)