|
| 1 | +use std::time::Instant; |
| 2 | + |
| 3 | +use crate::DiagCtxtHandle; |
| 4 | + |
| 5 | +/// A high-level section of the compilation process. |
| 6 | +#[derive(Copy, Clone, Debug)] |
| 7 | +pub enum TimingSection { |
| 8 | + /// Time spent linking. |
| 9 | + Linking, |
| 10 | +} |
| 11 | + |
| 12 | +/// Section with attached timestamp |
| 13 | +#[derive(Copy, Clone, Debug)] |
| 14 | +pub struct TimingRecord { |
| 15 | + pub section: TimingSection, |
| 16 | + /// Microseconds elapsed since some predetermined point in time (~start of the rustc process). |
| 17 | + pub timestamp: u128, |
| 18 | +} |
| 19 | + |
| 20 | +impl TimingRecord { |
| 21 | + fn from_origin(origin: Instant, section: TimingSection) -> Self { |
| 22 | + Self { section, timestamp: Instant::now().duration_since(origin).as_micros() } |
| 23 | + } |
| 24 | + |
| 25 | + pub fn section(&self) -> TimingSection { |
| 26 | + self.section |
| 27 | + } |
| 28 | + |
| 29 | + pub fn timestamp(&self) -> u128 { |
| 30 | + self.timestamp |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +/// Manages emission of start/end section timings, enabled through `--json=timings`. |
| 35 | +pub struct TimingSectionHandler { |
| 36 | + /// Time when the compilation session started. |
| 37 | + /// If `None`, timing is disabled. |
| 38 | + origin: Option<Instant>, |
| 39 | +} |
| 40 | + |
| 41 | +impl TimingSectionHandler { |
| 42 | + pub fn new(enabled: bool) -> Self { |
| 43 | + let origin = if enabled { Some(Instant::now()) } else { None }; |
| 44 | + Self { origin } |
| 45 | + } |
| 46 | + |
| 47 | + /// Returns a RAII guard that will immediately emit a start the provided section, and then emit |
| 48 | + /// its end when it is dropped. |
| 49 | + pub fn start_section<'a>( |
| 50 | + &self, |
| 51 | + diag_ctxt: DiagCtxtHandle<'a>, |
| 52 | + section: TimingSection, |
| 53 | + ) -> TimingSectionGuard<'a> { |
| 54 | + TimingSectionGuard::create(diag_ctxt, section, self.origin) |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +/// RAII wrapper for starting and ending section timings. |
| 59 | +pub struct TimingSectionGuard<'a> { |
| 60 | + dcx: DiagCtxtHandle<'a>, |
| 61 | + section: TimingSection, |
| 62 | + origin: Option<Instant>, |
| 63 | +} |
| 64 | + |
| 65 | +impl<'a> TimingSectionGuard<'a> { |
| 66 | + fn create(dcx: DiagCtxtHandle<'a>, section: TimingSection, origin: Option<Instant>) -> Self { |
| 67 | + if let Some(origin) = origin { |
| 68 | + dcx.emit_timing_section_start(TimingRecord::from_origin(origin, section)); |
| 69 | + } |
| 70 | + Self { dcx, section, origin } |
| 71 | + } |
| 72 | +} |
| 73 | + |
| 74 | +impl<'a> Drop for TimingSectionGuard<'a> { |
| 75 | + fn drop(&mut self) { |
| 76 | + if let Some(origin) = self.origin { |
| 77 | + self.dcx.emit_timing_section_end(TimingRecord::from_origin(origin, self.section)); |
| 78 | + } |
| 79 | + } |
| 80 | +} |
0 commit comments