Skip to content

Commit 6741b04

Browse files
committed
refactor(timings): store UnitData in RenderContext instead
This makes RenderContext more self-contained, so it no longer relies on full `Unit` info and can potentially be replayed from a log file.
1 parent d44468d commit 6741b04

File tree

2 files changed

+26
-39
lines changed

2 files changed

+26
-39
lines changed

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,16 @@ struct Concurrency {
125125
/// This is used by the HTML report's JavaScript to render the pipeline graph.
126126
#[derive(serde::Serialize)]
127127
struct UnitData {
128-
i: usize,
128+
i: u64,
129129
name: String,
130130
version: String,
131131
mode: String,
132132
target: String,
133+
features: Vec<String>,
133134
start: f64,
134135
duration: f64,
135-
unblocked_units: Vec<usize>,
136-
unblocked_rmeta_units: Vec<usize>,
136+
unblocked_units: Vec<u64>,
137+
unblocked_rmeta_units: Vec<u64>,
137138
sections: Option<Vec<(report::SectionName, report::SectionData)>>,
138139
}
139140

@@ -471,14 +472,16 @@ impl<'gctx> Timings<'gctx> {
471472
.map(|kind| build_runner.bcx.target_data.short_name(kind))
472473
.collect::<Vec<_>>();
473474

475+
let unit_data = report::to_unit_data(&self.unit_times, &self.unit_to_index);
476+
474477
let ctx = report::RenderContext {
475478
start: self.start,
476479
start_str: &self.start_str,
477480
root_units: &self.root_targets,
478481
profile: &self.profile,
479482
total_fresh: self.total_fresh,
480483
total_dirty: self.total_dirty,
481-
unit_times: &self.unit_times,
484+
unit_data,
482485
concurrency: &self.concurrency,
483486
cpu_usage: &self.cpu_usage,
484487
rustc_version,
@@ -503,10 +506,6 @@ impl<'gctx> Timings<'gctx> {
503506
}
504507

505508
impl UnitTime {
506-
fn name_ver(&self) -> String {
507-
format!("{} v{}", self.unit.pkg.name(), self.unit.pkg.version())
508-
}
509-
510509
fn start_section(&mut self, name: &str, now: f64) {
511510
if self
512511
.sections

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

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub struct RenderContext<'a> {
9797
/// Total number of dirty units.
9898
pub total_dirty: u32,
9999
/// Time tracking for each individual unit.
100-
pub unit_times: &'a [UnitTime],
100+
pub unit_data: Vec<UnitData>,
101101
/// Concurrency-tracking information. This is periodically updated while
102102
/// compilation progresses.
103103
pub concurrency: &'a [Concurrency],
@@ -236,12 +236,10 @@ fn write_summary_table(
236236
/// Write timing data in JavaScript. Primarily for `timings.js` to put data
237237
/// in a `<script>` HTML element to draw graphs.
238238
fn write_js_data(ctx: &RenderContext<'_>, f: &mut impl Write) -> CargoResult<()> {
239-
let unit_data = to_unit_data(&ctx.unit_times);
240-
241239
writeln!(
242240
f,
243241
"const UNIT_DATA = {};",
244-
serde_json::to_string_pretty(&unit_data)?
242+
serde_json::to_string_pretty(&ctx.unit_data)?
245243
)?;
246244
writeln!(
247245
f,
@@ -258,17 +256,14 @@ fn write_js_data(ctx: &RenderContext<'_>, f: &mut impl Write) -> CargoResult<()>
258256

259257
/// Render the table of all units.
260258
fn write_unit_table(ctx: &RenderContext<'_>, f: &mut impl Write) -> CargoResult<()> {
261-
let mut units: Vec<&UnitTime> = ctx.unit_times.iter().collect();
259+
let mut units: Vec<_> = ctx.unit_data.iter().collect();
262260
units.sort_unstable_by(|a, b| b.duration.partial_cmp(&a.duration).unwrap());
263261

264-
let aggregated: Vec<AggregatedSections> = units.iter().map(|u| aggregate_sections(u)).collect();
262+
let aggregated: Vec<Option<_>> = units.iter().map(|u| u.sections.as_ref()).collect();
265263

266264
let headers: Vec<_> = aggregated
267265
.iter()
268-
.find_map(|s| match s {
269-
AggregatedSections::Sections(sections) => Some(sections),
270-
_ => None,
271-
})
266+
.find_map(|s| s.as_ref())
272267
.map(|sections| {
273268
sections
274269
.iter()
@@ -315,22 +310,17 @@ fn write_unit_table(ctx: &RenderContext<'_>, f: &mut impl Write) -> CargoResult<
315310
// arbitrary set of headers, and an arbitrary set of sections per unit, so we always
316311
// initiate the cells to be empty, and then try to find a corresponding column for which
317312
// we might have data.
318-
let mut cells = HashMap::new();
313+
let mut cells: HashMap<_, _> = aggregated_sections
314+
.iter()
315+
.flat_map(|sections| sections.into_iter().map(|s| (&s.0, &s.1)))
316+
.collect();
319317

320-
match &aggregated_sections {
321-
AggregatedSections::Sections(sections) => {
322-
for (name, data) in sections {
323-
cells.insert(name, data);
324-
}
325-
}
326-
AggregatedSections::OnlyTotalDuration => {}
327-
};
328318
let cells = headers
329319
.iter()
330320
.map(|header| format!("<td>{}</td>", format_duration(cells.remove(header))))
331321
.join("\n");
332322

333-
let features = unit.unit.features.join(", ");
323+
let features = unit.features.join(", ");
334324
write!(
335325
f,
336326
r#"
@@ -343,7 +333,7 @@ fn write_unit_table(ctx: &RenderContext<'_>, f: &mut impl Write) -> CargoResult<
343333
</tr>
344334
"#,
345335
i + 1,
346-
unit.name_ver(),
336+
format_args!("{} v{}", unit.name, unit.version),
347337
unit.target,
348338
unit.duration,
349339
)?;
@@ -352,17 +342,14 @@ fn write_unit_table(ctx: &RenderContext<'_>, f: &mut impl Write) -> CargoResult<
352342
Ok(())
353343
}
354344

355-
fn to_unit_data(unit_times: &[UnitTime]) -> Vec<UnitData> {
356-
// Create a map to link indices of unlocked units.
357-
let unit_map: HashMap<Unit, usize> = unit_times
358-
.iter()
359-
.enumerate()
360-
.map(|(i, ut)| (ut.unit.clone(), i))
361-
.collect();
345+
pub(super) fn to_unit_data(
346+
unit_times: &[UnitTime],
347+
unit_map: &HashMap<Unit, u64>,
348+
) -> Vec<UnitData> {
362349
let round = |x: f64| (x * 100.0).round() / 100.0;
363350
unit_times
364351
.iter()
365-
.enumerate()
352+
.map(|ut| (unit_map[&ut.unit], ut))
366353
.map(|(i, ut)| {
367354
let mode = if ut.unit.mode.is_run_custom_build() {
368355
"run-custom-build"
@@ -373,12 +360,12 @@ fn to_unit_data(unit_times: &[UnitTime]) -> Vec<UnitData> {
373360
// These filter on the unlocked units because not all unlocked
374361
// units are actually "built". For example, Doctest mode units
375362
// don't actually generate artifacts.
376-
let unblocked_units: Vec<usize> = ut
363+
let unblocked_units = ut
377364
.unblocked_units
378365
.iter()
379366
.filter_map(|unit| unit_map.get(unit).copied())
380367
.collect();
381-
let unblocked_rmeta_units: Vec<usize> = ut
368+
let unblocked_rmeta_units = ut
382369
.unblocked_rmeta_units
383370
.iter()
384371
.filter_map(|unit| unit_map.get(unit).copied())
@@ -394,6 +381,7 @@ fn to_unit_data(unit_times: &[UnitTime]) -> Vec<UnitData> {
394381
version: ut.unit.pkg.version().to_string(),
395382
mode,
396383
target: ut.target.clone(),
384+
features: ut.unit.features.iter().map(|f| f.to_string()).collect(),
397385
start: round(ut.start),
398386
duration: round(ut.duration),
399387
unblocked_units,

0 commit comments

Comments
 (0)