Skip to content

Commit c2b4c2d

Browse files
committed
Auto merge of rust-lang#95739 - lqd:proc-macro-expansions, r=wesleywiser
self-profiler: record spans for proc-macro expansions This PR is a follow-up to rust-lang#95473, using the arg recorder feature from rust-lang#95689: - it adds support code to easily record spans in the event's arguments, when using `generic_activity_with_arg_recorder`. - uses that to record the spans where proc-macro expansions happen in addition to their name. As for the other 2 PRs, the goal here is to provide visibility into proc-macro expansion performance, so that users can diagnose which uses of proc-macros in their code could be causing compile time issues. Some areas where I'd love feedback: - [x] the API and names: the `SpannedEventArgRecorder` trait and its method, much like rust-lang#95689 had the same question about the `EventArgRecorder` naming - [x] we don't currently have a way to record the names of the event arguments, so should `record_arg_spanned` record the span as "location: {}" or similar ?
2 parents f4ec0e7 + c525396 commit c2b4c2d

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

compiler/rustc_expand/src/proc_macro.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_data_structures::sync::Lrc;
99
use rustc_errors::ErrorGuaranteed;
1010
use rustc_parse::nt_to_tokenstream;
1111
use rustc_parse::parser::ForceCollect;
12+
use rustc_span::profiling::SpannedEventArgRecorder;
1213
use rustc_span::{Span, DUMMY_SP};
1314

1415
const EXEC_STRATEGY: pm::bridge::server::SameThread = pm::bridge::server::SameThread;
@@ -25,7 +26,10 @@ impl base::ProcMacro for BangProcMacro {
2526
input: TokenStream,
2627
) -> Result<TokenStream, ErrorGuaranteed> {
2728
let _timer =
28-
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
29+
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
30+
recorder.record_arg_with_span(ecx.expansion_descr(), span);
31+
});
32+
2933
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
3034
let server = proc_macro_server::Rustc::new(ecx);
3135
self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace).map_err(|e| {
@@ -51,7 +55,10 @@ impl base::AttrProcMacro for AttrProcMacro {
5155
annotated: TokenStream,
5256
) -> Result<TokenStream, ErrorGuaranteed> {
5357
let _timer =
54-
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
58+
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
59+
recorder.record_arg_with_span(ecx.expansion_descr(), span);
60+
});
61+
5562
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
5663
let server = proc_macro_server::Rustc::new(ecx);
5764
self.client
@@ -103,7 +110,9 @@ impl MultiItemModifier for ProcMacroDerive {
103110

104111
let stream = {
105112
let _timer =
106-
ecx.sess.prof.generic_activity_with_arg("expand_proc_macro", ecx.expansion_descr());
113+
ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| {
114+
recorder.record_arg_with_span(ecx.expansion_descr(), span);
115+
});
107116
let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace;
108117
let server = proc_macro_server::Rustc::new(ecx);
109118
match self.client.run(&EXEC_STRATEGY, server, input, proc_macro_backtrace) {

compiler/rustc_span/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ pub use symbol::{sym, Symbol};
5959
mod analyze_source_file;
6060
pub mod fatal_error;
6161

62+
pub mod profiling;
63+
6264
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
6365
use rustc_data_structures::sync::{Lock, Lrc};
6466

compiler/rustc_span/src/profiling.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use std::borrow::Borrow;
2+
3+
use rustc_data_structures::profiling::EventArgRecorder;
4+
5+
/// Extension trait for self-profiling purposes: allows to record spans within a generic activity's
6+
/// event arguments.
7+
pub trait SpannedEventArgRecorder {
8+
/// Records the following event arguments within the current generic activity being profiled:
9+
/// - the provided `event_arg`
10+
/// - a string representation of the provided `span`
11+
///
12+
/// Note: when self-profiling with costly event arguments, at least one argument
13+
/// needs to be recorded. A panic will be triggered if that doesn't happen.
14+
fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span)
15+
where
16+
A: Borrow<str> + Into<String>;
17+
}
18+
19+
impl SpannedEventArgRecorder for EventArgRecorder<'_> {
20+
fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span)
21+
where
22+
A: Borrow<str> + Into<String>,
23+
{
24+
self.record_arg(event_arg);
25+
26+
let span_arg = crate::with_session_globals(|session_globals| {
27+
if let Some(source_map) = &*session_globals.source_map.borrow() {
28+
source_map.span_to_embeddable_string(span)
29+
} else {
30+
format!("{:?}", span)
31+
}
32+
});
33+
self.record_arg(span_arg);
34+
}
35+
}

0 commit comments

Comments
 (0)