diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:29 +0000 |
commit | 631cd5845e8de329d0e227aaa707d7ea228b8f8f (patch) | |
tree | a1b87c8f8cad01cf18f7c5f57a08f102771ed303 /compiler/rustc_data_structures/src/profiling.rs | |
parent | Adding debian version 1.69.0+dfsg1-1. (diff) | |
download | rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.tar.xz rustc-631cd5845e8de329d0e227aaa707d7ea228b8f8f.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_data_structures/src/profiling.rs')
-rw-r--r-- | compiler/rustc_data_structures/src/profiling.rs | 105 |
1 files changed, 77 insertions, 28 deletions
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 443316836..1ed584eaf 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -97,6 +97,7 @@ use std::time::{Duration, Instant}; pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; use parking_lot::RwLock; +use serde_json::json; use smallvec::SmallVec; bitflags::bitflags! { @@ -145,6 +146,15 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ /// Something that uniquely identifies a query invocation. pub struct QueryInvocationId(pub u32); +/// Which format to use for `-Z time-passes` +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum TimePassesFormat { + /// Emit human readable text + Text, + /// Emit structured JSON + Json, +} + /// A reference to the SelfProfiler. It can be cloned and sent across thread /// boundaries at will. #[derive(Clone)] @@ -158,14 +168,14 @@ pub struct SelfProfilerRef { // actually enabled. event_filter_mask: EventFilter, - // Print verbose generic activities to stderr? - print_verbose_generic_activities: bool, + // Print verbose generic activities to stderr. + print_verbose_generic_activities: Option<TimePassesFormat>, } impl SelfProfilerRef { pub fn new( profiler: Option<Arc<SelfProfiler>>, - print_verbose_generic_activities: bool, + print_verbose_generic_activities: Option<TimePassesFormat>, ) -> SelfProfilerRef { // If there is no SelfProfiler then the filter mask is set to NONE, // ensuring that nothing ever tries to actually access it. @@ -207,9 +217,10 @@ impl SelfProfilerRef { /// a measureme event, "verbose" generic activities also print a timing entry to /// stderr if the compiler is invoked with -Ztime-passes. pub fn verbose_generic_activity(&self, event_label: &'static str) -> VerboseTimingGuard<'_> { - let message = self.print_verbose_generic_activities.then(|| event_label.to_owned()); + let message_and_format = + self.print_verbose_generic_activities.map(|format| (event_label.to_owned(), format)); - VerboseTimingGuard::start(message, self.generic_activity(event_label)) + VerboseTimingGuard::start(message_and_format, self.generic_activity(event_label)) } /// Like `verbose_generic_activity`, but with an extra arg. @@ -221,11 +232,14 @@ impl SelfProfilerRef { where A: Borrow<str> + Into<String>, { - let message = self + let message_and_format = self .print_verbose_generic_activities - .then(|| format!("{}({})", event_label, event_arg.borrow())); + .map(|format| (format!("{}({})", event_label, event_arg.borrow()), format)); - VerboseTimingGuard::start(message, self.generic_activity_with_arg(event_label, event_arg)) + VerboseTimingGuard::start( + message_and_format, + self.generic_activity_with_arg(event_label, event_arg), + ) } /// Start profiling a generic activity. Profiling continues until the @@ -703,17 +717,32 @@ impl<'a> TimingGuard<'a> { } } +struct VerboseInfo { + start_time: Instant, + start_rss: Option<usize>, + message: String, + format: TimePassesFormat, +} + #[must_use] pub struct VerboseTimingGuard<'a> { - start_and_message: Option<(Instant, Option<usize>, String)>, + info: Option<VerboseInfo>, _guard: TimingGuard<'a>, } impl<'a> VerboseTimingGuard<'a> { - pub fn start(message: Option<String>, _guard: TimingGuard<'a>) -> Self { + pub fn start( + message_and_format: Option<(String, TimePassesFormat)>, + _guard: TimingGuard<'a>, + ) -> Self { VerboseTimingGuard { _guard, - start_and_message: message.map(|msg| (Instant::now(), get_resident_set_size(), msg)), + info: message_and_format.map(|(message, format)| VerboseInfo { + start_time: Instant::now(), + start_rss: get_resident_set_size(), + message, + format, + }), } } @@ -726,10 +755,10 @@ impl<'a> VerboseTimingGuard<'a> { impl Drop for VerboseTimingGuard<'_> { fn drop(&mut self) { - if let Some((start_time, start_rss, ref message)) = self.start_and_message { + if let Some(info) = &self.info { let end_rss = get_resident_set_size(); - let dur = start_time.elapsed(); - print_time_passes_entry(message, dur, start_rss, end_rss); + let dur = info.start_time.elapsed(); + print_time_passes_entry(&info.message, dur, info.start_rss, end_rss, info.format); } } } @@ -739,7 +768,22 @@ pub fn print_time_passes_entry( dur: Duration, start_rss: Option<usize>, end_rss: Option<usize>, + format: TimePassesFormat, ) { + match format { + TimePassesFormat::Json => { + let json = json!({ + "pass": what, + "time": dur.as_secs_f64(), + "rss_start": start_rss, + "rss_end": end_rss, + }); + eprintln!("time: {json}"); + return; + } + TimePassesFormat::Text => (), + } + // Print the pass if its duration is greater than 5 ms, or it changed the // measured RSS. let is_notable = || { @@ -796,21 +840,26 @@ fn get_thread_id() -> u32 { cfg_if! { if #[cfg(windows)] { pub fn get_resident_set_size() -> Option<usize> { - use std::mem::{self, MaybeUninit}; - use winapi::shared::minwindef::DWORD; - use winapi::um::processthreadsapi::GetCurrentProcess; - use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}; - - let mut pmc = MaybeUninit::<PROCESS_MEMORY_COUNTERS>::uninit(); - match unsafe { - GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD) - } { - 0 => None, - _ => { - let pmc = unsafe { pmc.assume_init() }; - Some(pmc.WorkingSetSize as usize) - } + use std::mem; + + use windows::{ + Win32::System::ProcessStatus::{K32GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}, + Win32::System::Threading::GetCurrentProcess, + }; + + let mut pmc = PROCESS_MEMORY_COUNTERS::default(); + let pmc_size = mem::size_of_val(&pmc); + unsafe { + K32GetProcessMemoryInfo( + GetCurrentProcess(), + &mut pmc, + pmc_size as u32, + ) } + .ok() + .ok()?; + + Some(pmc.WorkingSetSize) } } else if #[cfg(target_os = "macos")] { pub fn get_resident_set_size() -> Option<usize> { |