Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate measureme's hardware performance counter support. #78781

Merged
merged 9 commits into from
Jun 14, 2022
14 changes: 10 additions & 4 deletions compiler/rustc_data_structures/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,14 +550,20 @@ impl SelfProfiler {
pub fn new(
output_directory: &Path,
crate_name: Option<&str>,
event_filters: &Option<Vec<String>>,
event_filters: Option<&[String]>,
counter_name: &str,
) -> Result<SelfProfiler, Box<dyn Error + Send + Sync>> {
fs::create_dir_all(output_directory)?;

let crate_name = crate_name.unwrap_or("unknown-crate");
let filename = format!("{}-{}.rustc_profile", crate_name, process::id());
// HACK(eddyb) we need to pad the PID, strange as it may seem, as its
// length can behave as a source of entropy for heap addresses, when
// ASLR is disabled and the heap is otherwise determinic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*deterministic

let pid: u32 = process::id();
let filename = format!("{}-{:07}.rustc_profile", crate_name, pid);
let path = output_directory.join(&filename);
let profiler = Profiler::new(&path)?;
let profiler =
Profiler::with_counter(&path, measureme::counters::Counter::by_name(counter_name)?)?;

let query_event_kind = profiler.alloc_string("Query");
let generic_activity_event_kind = profiler.alloc_string("GenericActivity");
Expand All @@ -570,7 +576,7 @@ impl SelfProfiler {

let mut event_filter_mask = EventFilter::empty();

if let Some(ref event_filters) = *event_filters {
if let Some(event_filters) = event_filters {
let mut unknown_events = vec![];
for item in event_filters {
if let Some(&(_, mask)) =
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_query_impl/src/profiling_support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ fn alloc_self_profile_query_strings_for_query_cache<'tcx, C>(
let query_name = profiler.get_or_alloc_cached_string(query_name);
let event_id = event_id_builder.from_label(query_name).to_string_id();

// FIXME(eddyb) make this O(1) by using a pre-cached query name `EventId`,
// instead of passing the `DepNodeIndex` to `finish_with_query_invocation_id`,
// when recording the event in the first place.
let mut query_invocation_ids = Vec::new();
query_cache.iter(&mut |_, _, i| {
query_invocation_ids.push(i.into());
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,12 @@ options! {
for example: `-Z self-profile-events=default,query-keys`
all options: none, all, default, generic-activity, query-provider, query-cache-hit
query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"),
self_profile_counter: String = ("wall-time".to_string(), parse_string, [UNTRACKED],
"counter used by the self profiler (default: `wall-time`), one of:
`wall-time` (monotonic clock, i.e. `std::time::Instant`)
`instructions:u` (retired instructions, userspace-only)
`instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy)"
),
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
"make the current crate share its generic instantiations"),
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,8 @@ pub fn build_session(
let profiler = SelfProfiler::new(
directory,
sopts.crate_name.as_deref(),
&sopts.debugging_opts.self_profile_events,
sopts.debugging_opts.self_profile_events.as_ref().map(|xs| &xs[..]),
&sopts.debugging_opts.self_profile_counter,
);
match profiler {
Ok(profiler) => Some(Arc::new(profiler)),
Expand Down
22 changes: 19 additions & 3 deletions library/proc_macro/src/bridge/handle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Server-side handles and storage for per-handle data.

use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
use std::hash::{BuildHasher, Hash};
use std::num::NonZeroU32;
use std::ops::{Index, IndexMut};
use std::sync::atomic::{AtomicUsize, Ordering};
Expand Down Expand Up @@ -51,15 +51,31 @@ impl<T> IndexMut<Handle> for OwnedStore<T> {
}
}

// HACK(eddyb) deterministic `std::collections::hash_map::RandomState` replacement
// that doesn't require adding any dependencies to `proc_macro` (like `rustc-hash`).
#[derive(Clone)]
struct NonRandomState;

impl BuildHasher for NonRandomState {
type Hasher = std::collections::hash_map::DefaultHasher;
#[inline]
fn build_hasher(&self) -> Self::Hasher {
Self::Hasher::new()
}
}

/// Like `OwnedStore`, but avoids storing any value more than once.
pub(super) struct InternedStore<T: 'static> {
owned: OwnedStore<T>,
interner: HashMap<T, Handle>,
interner: HashMap<T, Handle, NonRandomState>,
}

impl<T: Copy + Eq + Hash> InternedStore<T> {
pub(super) fn new(counter: &'static AtomicUsize) -> Self {
InternedStore { owned: OwnedStore::new(counter), interner: HashMap::new() }
InternedStore {
owned: OwnedStore::new(counter),
interner: HashMap::with_hasher(NonRandomState),
}
}

pub(super) fn alloc(&mut self, x: T) -> Handle {
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3140,6 +3140,7 @@ impl DefaultHasher {
/// `DefaultHasher` instances, but is the same as all other `DefaultHasher`
/// instances created through `new` or `default`.
#[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
#[inline]
#[allow(deprecated)]
#[must_use]
pub fn new() -> DefaultHasher {
Expand All @@ -3153,6 +3154,7 @@ impl Default for DefaultHasher {
/// See its documentation for more.
///
/// [`new`]: DefaultHasher::new
#[inline]
fn default() -> DefaultHasher {
DefaultHasher::new()
}
Expand Down