Skip to content

Commit a7cdba1

Browse files
authored
feat(log): add more log events (#16390)
### What does this PR try to resolve? * `resolution-started` * `resolution-finished` * `unit-graph-started` * `unit-graph-finished` * `unit-registered` The first four events are simple log events with elapsed time. The `unit-registered` event contains unit metadata and the index, so that `unit-started` doesn't need to have those. As a result, the timing replay now requires `unit-registered` events to derive those data. The log and HTML snapshot also changed to `rustfix`, which is a bit smaller in size. Part of <#15844> ### How to test and review this PR?
2 parents 963b490 + 9a238b9 commit a7cdba1

File tree

8 files changed

+1237
-3758
lines changed

8 files changed

+1237
-3758
lines changed

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ pub struct BuildContext<'a, 'gctx> {
7878
/// The dependency graph of units to compile.
7979
pub unit_graph: UnitGraph,
8080

81+
/// A map from unit to index.
82+
pub unit_to_index: HashMap<Unit, u64>,
83+
8184
/// Reverse-dependencies of documented units, used by the `rustdoc --scrape-examples` flag.
8285
pub scrape_units: Vec<Unit>,
8386

@@ -96,6 +99,7 @@ impl<'a, 'gctx> BuildContext<'a, 'gctx> {
9699
target_data: RustcTargetData<'gctx>,
97100
roots: Vec<Unit>,
98101
unit_graph: UnitGraph,
102+
unit_to_index: HashMap<Unit, u64>,
99103
scrape_units: Vec<Unit>,
100104
) -> CargoResult<BuildContext<'a, 'gctx>> {
101105
let all_kinds = unit_graph
@@ -116,6 +120,7 @@ impl<'a, 'gctx> BuildContext<'a, 'gctx> {
116120
target_data,
117121
roots,
118122
unit_graph,
123+
unit_to_index,
119124
scrape_units,
120125
all_kinds,
121126
})

src/cargo/core/compiler/timings/mod.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use crate::util::{CargoResult, GlobalContext};
1717

1818
use cargo_util::paths;
1919
use indexmap::IndexMap;
20-
use itertools::Itertools as _;
2120
use std::collections::HashMap;
2221
use std::io::BufWriter;
2322
use std::time::{Duration, Instant};
@@ -53,9 +52,6 @@ pub struct Timings<'gctx> {
5352
/// Total number of dirty units.
5453
total_dirty: u32,
5554
/// A map from unit to index.
56-
///
57-
/// This for saving log size.
58-
/// Only the unit-started event needs to hold the entire unit information.
5955
unit_to_index: HashMap<Unit, u64>,
6056
/// Time tracking for each individual unit.
6157
unit_times: Vec<UnitTime>,
@@ -174,13 +170,6 @@ impl<'gctx> Timings<'gctx> {
174170
None
175171
}
176172
};
177-
let unit_to_index = bcx
178-
.unit_graph
179-
.keys()
180-
.sorted()
181-
.enumerate()
182-
.map(|(i, unit)| (unit.clone(), i as u64))
183-
.collect();
184173

185174
Timings {
186175
gctx: bcx.gctx,
@@ -193,7 +182,7 @@ impl<'gctx> Timings<'gctx> {
193182
profile,
194183
total_fresh: 0,
195184
total_dirty: 0,
196-
unit_to_index,
185+
unit_to_index: bcx.unit_to_index.clone(),
197186
unit_times: Vec::new(),
198187
active: HashMap::new(),
199188
last_cpu_state,
@@ -237,9 +226,6 @@ impl<'gctx> Timings<'gctx> {
237226
};
238227
if let Some(logger) = build_runner.bcx.logger {
239228
logger.log(LogMessage::UnitStarted {
240-
package_id: unit_time.unit.pkg.package_id().to_spec(),
241-
target: (&unit_time.unit.target).into(),
242-
mode: unit_time.unit.mode,
243229
index: self.unit_to_index[&unit_time.unit],
244230
elapsed: start,
245231
});

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ use annotate_snippets::{Group, Level, Origin};
6464
pub use compile_filter::{CompileFilter, FilterRule, LibRule};
6565

6666
pub(super) mod unit_generator;
67+
use itertools::Itertools as _;
6768
use unit_generator::UnitGenerator;
6869

6970
mod packages;
@@ -304,6 +305,11 @@ pub fn create_bcx<'a, 'gctx>(
304305
}
305306
};
306307
let dry_run = false;
308+
309+
if let Some(logger) = logger {
310+
let elapsed = ws.gctx().creation_time().elapsed().as_secs_f64();
311+
logger.log(LogMessage::ResolutionStarted { elapsed });
312+
}
307313
let resolve = ops::resolve_ws_with_opts(
308314
ws,
309315
&mut target_data,
@@ -321,6 +327,11 @@ pub fn create_bcx<'a, 'gctx>(
321327
specs_and_features,
322328
} = resolve;
323329

330+
if let Some(logger) = logger {
331+
let elapsed = ws.gctx().creation_time().elapsed().as_secs_f64();
332+
logger.log(LogMessage::ResolutionFinished { elapsed });
333+
}
334+
324335
let std_resolve_features = if let Some(crates) = &gctx.cli_unstable().build_std {
325336
let (std_package_set, std_resolve, std_features) = standard_lib::resolve_std(
326337
ws,
@@ -397,10 +408,15 @@ pub fn create_bcx<'a, 'gctx>(
397408
})
398409
.collect();
399410

400-
let mut units = Vec::new();
411+
let mut root_units = Vec::new();
401412
let mut unit_graph = HashMap::new();
402413
let mut scrape_units = Vec::new();
403414

415+
if let Some(logger) = logger {
416+
let elapsed = ws.gctx().creation_time().elapsed().as_secs_f64();
417+
logger.log(LogMessage::UnitGraphStarted { elapsed });
418+
}
419+
404420
for SpecsAndResolvedFeatures {
405421
specs,
406422
resolved_features,
@@ -479,14 +495,14 @@ pub fn create_bcx<'a, 'gctx>(
479495
&profiles,
480496
interner,
481497
)?);
482-
units.extend(targeted_root_units);
498+
root_units.extend(targeted_root_units);
483499
scrape_units.extend(targeted_scrape_units);
484500
}
485501

486502
// TODO: In theory, Cargo should also dedupe the roots, but I'm uncertain
487503
// what heuristics to use in that case.
488504
if build_config.intent.wants_deps_docs() {
489-
remove_duplicate_doc(build_config, &units, &mut unit_graph);
505+
remove_duplicate_doc(build_config, &root_units, &mut unit_graph);
490506
}
491507

492508
let host_kind_requested = build_config
@@ -496,29 +512,50 @@ pub fn create_bcx<'a, 'gctx>(
496512
// Rebuild the unit graph, replacing the explicit host targets with
497513
// CompileKind::Host, removing `artifact_target_for_features` and merging any dependencies
498514
// shared with build and artifact dependencies.
499-
(units, scrape_units, unit_graph) = rebuild_unit_graph_shared(
515+
(root_units, scrape_units, unit_graph) = rebuild_unit_graph_shared(
500516
interner,
501517
unit_graph,
502-
&units,
518+
&root_units,
503519
&scrape_units,
504520
host_kind_requested.then_some(explicit_host_kind),
505521
build_config.compile_time_deps_only,
506522
);
507523

524+
// unit_graph must be immutable after this point.
525+
let unit_graph = unit_graph;
526+
let units: Vec<_> = unit_graph.keys().sorted().collect();
527+
let unit_to_index: HashMap<_, _> = units
528+
.iter()
529+
.enumerate()
530+
.map(|(i, &unit)| (unit.clone(), i as u64))
531+
.collect();
532+
if let Some(logger) = logger {
533+
for (i, unit) in units.into_iter().enumerate() {
534+
logger.log(LogMessage::UnitRegistered {
535+
package_id: unit.pkg.package_id().to_spec(),
536+
target: (&unit.target).into(),
537+
mode: unit.mode,
538+
index: i as u64,
539+
});
540+
}
541+
let elapsed = ws.gctx().creation_time().elapsed().as_secs_f64();
542+
logger.log(LogMessage::UnitGraphFinished { elapsed });
543+
}
544+
508545
let mut extra_compiler_args = HashMap::new();
509546
if let Some(args) = extra_args {
510-
if units.len() != 1 {
547+
if root_units.len() != 1 {
511548
anyhow::bail!(
512549
"extra arguments to `{}` can only be passed to one \
513550
target, consider filtering\nthe package by passing, \
514551
e.g., `--lib` or `--bin NAME` to specify a single target",
515552
extra_args_name
516553
);
517554
}
518-
extra_compiler_args.insert(units[0].clone(), args);
555+
extra_compiler_args.insert(root_units[0].clone(), args);
519556
}
520557

521-
for unit in units
558+
for unit in root_units
522559
.iter()
523560
.filter(|unit| unit.mode.is_doc() || unit.mode.is_doc_test())
524561
.filter(|unit| rustdoc_document_private_items || unit.target.is_bin())
@@ -541,7 +578,7 @@ pub fn create_bcx<'a, 'gctx>(
541578

542579
// Validate target src path for each root unit
543580
let mut error_count: usize = 0;
544-
for unit in &units {
581+
for unit in &root_units {
545582
if let Some(target_src_path) = unit.target.src_path().path() {
546583
validate_target_path_as_source_file(
547584
gctx,
@@ -619,8 +656,9 @@ where `<compatible-ver>` is the latest version supporting rustc {rustc_version}"
619656
profiles,
620657
extra_compiler_args,
621658
target_data,
622-
units,
659+
root_units,
623660
unit_graph,
661+
unit_to_index,
624662
scrape_units,
625663
)?;
626664

src/cargo/ops/cargo_report/timings.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! The `cargo report timings` command.
22
3+
use std::collections::HashMap;
34
use std::ffi::OsStr;
45
use std::fs::File;
56
use std::io::BufReader;
@@ -178,6 +179,8 @@ fn prepare_context(log: &Path, run_id: &RunId) -> CargoResult<RenderContext<'sta
178179
};
179180
let mut units: IndexMap<_, UnitEntry> = IndexMap::new();
180181

182+
let mut unit_by_index: HashMap<u64, _> = HashMap::new();
183+
181184
for (log_index, result) in serde_json::Deserializer::from_reader(reader)
182185
.into_iter::<LogMessage>()
183186
.enumerate()
@@ -208,13 +211,17 @@ fn prepare_context(log: &Path, run_id: &RunId) -> CargoResult<RenderContext<'sta
208211
ctx.profile = profile;
209212
ctx.rustc_version = rustc_version;
210213
}
211-
LogMessage::UnitStarted {
214+
LogMessage::UnitRegistered {
212215
package_id,
213216
target,
214217
mode,
215218
index,
216-
elapsed,
217219
} => {
220+
unit_by_index.insert(index, (package_id, target, mode));
221+
}
222+
LogMessage::UnitStarted { index, elapsed } => {
223+
let (package_id, target, mode) = unit_by_index.get(&index).unwrap();
224+
218225
let version = package_id
219226
.version()
220227
.map(|v| v.to_string())
@@ -223,7 +230,7 @@ fn prepare_context(log: &Path, run_id: &RunId) -> CargoResult<RenderContext<'sta
223230
// This is pretty similar to how the current `core::compiler::timings`
224231
// renders `core::manifest::Target`. However, our target is
225232
// a simplified type so we cannot reuse the same logic here.
226-
let mut target_str = if target.kind == "lib" && mode == CompileMode::Build {
233+
let mut target_str = if target.kind == "lib" && mode == &CompileMode::Build {
227234
// Special case for brevity, since most dependencies hit this path.
228235
"".to_string()
229236
} else if target.kind == "build-script" {

src/cargo/util/log_message.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,30 @@ pub enum LogMessage {
3939
/// Workspace root directory.
4040
workspace_root: PathBuf,
4141
},
42-
/// Emitted when a compilation unit starts.
43-
UnitStarted {
42+
/// Emitted when resolving dependencies starts.
43+
ResolutionStarted {
44+
/// Seconds elapsed from build start.
45+
elapsed: f64,
46+
},
47+
/// Emitted when resolving dependencies finishes.
48+
ResolutionFinished {
49+
/// Seconds elapsed from build start.
50+
elapsed: f64,
51+
},
52+
/// Emitted when unit graph generation starts.
53+
UnitGraphStarted {
54+
/// Seconds elapsed from build start.
55+
elapsed: f64,
56+
},
57+
/// Emitted when unit graph generation finishes.
58+
UnitGraphFinished {
59+
/// Seconds elapsed from build start.
60+
elapsed: f64,
61+
},
62+
/// Emitted when a compilation unit is registered in the unit graph,
63+
/// right before [`LogMessage::UnitGraphFinished`] that Cargo finalizes
64+
/// the unit graph.
65+
UnitRegistered {
4466
/// Package ID specification.
4567
package_id: PackageIdSpec,
4668
/// Cargo target (lib, bin, example, etc.).
@@ -49,12 +71,17 @@ pub enum LogMessage {
4971
mode: CompileMode,
5072
/// Unit index for compact reference in subsequent events.
5173
index: u64,
74+
},
75+
/// Emitted when a compilation unit starts.
76+
UnitStarted {
77+
/// Unit index from the associated unit-registered event.
78+
index: u64,
5279
/// Seconds elapsed from build start.
5380
elapsed: f64,
5481
},
5582
/// Emitted when a section (e.g., rmeta, link) of the compilation unit finishes.
5683
UnitRmetaFinished {
57-
/// Unit index from the associated unit-started event.
84+
/// Unit index from the associated unit-registered event.
5885
index: u64,
5986
/// Seconds elapsed from build start.
6087
elapsed: f64,
@@ -66,7 +93,7 @@ pub enum LogMessage {
6693
///
6794
/// Requires `-Zsection-timings` to be enabled.
6895
UnitSectionStarted {
69-
/// Unit index from the associated unit-started event.
96+
/// Unit index from the associated unit-registered event.
7097
index: u64,
7198
/// Seconds elapsed from build start.
7299
elapsed: f64,
@@ -77,7 +104,7 @@ pub enum LogMessage {
77104
///
78105
/// Requires `-Zsection-timings` to be enabled.
79106
UnitSectionFinished {
80-
/// Unit index from the associated unit-started event.
107+
/// Unit index from the associated unit-registered event.
81108
index: u64,
82109
/// Seconds elapsed from build start.
83110
elapsed: f64,
@@ -86,7 +113,7 @@ pub enum LogMessage {
86113
},
87114
/// Emitted when a compilation unit finishes.
88115
UnitFinished {
89-
/// Unit index from the associated unit-started event.
116+
/// Unit index from the associated unit-registered event.
90117
index: u64,
91118
/// Seconds elapsed from build start.
92119
elapsed: f64,

0 commit comments

Comments
 (0)