profile_traits/
lib.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! This module contains APIs for the `profile` crate used generically in the
6//! rest of Servo. These APIs are here instead of in `profile` so that these
7//! modules won't have to depend on `profile`.
8
9#![deny(unsafe_code)]
10
11pub mod generic_callback;
12pub mod generic_channel;
13pub mod ipc;
14pub mod mem;
15pub mod time;
16
17/// Measure the given callback with the time profiler and (if enabled) tracing.
18///
19/// `$category` must be const, because we use it to derive the span name.
20#[macro_export]
21macro_rules! time_profile {
22    ($category:expr, $meta:expr, $profiler_chan:expr, $($callback:tt)+) => {{
23        let meta: Option<$crate::time::TimerMetadata> = $meta;
24        #[cfg(feature = "tracing")]
25        let span = $crate::servo_tracing::info_span!(
26            $category.variant_name(),
27            servo_profiling = true,
28            url = meta.as_ref().map(|m| m.url.clone()),
29        );
30        #[cfg(not(feature = "tracing"))]
31        let span = ();
32        $crate::time::profile($category, meta, $profiler_chan, span, $($callback)+)
33    }};
34}
35
36#[doc(hidden)]
37#[macro_export]
38macro_rules! __profiling_span {
39    ($backend_macro:ident, $span_name:literal $(, $($fields:tt)+)?) => {{
40        #[cfg(feature = "tracing")]
41        {
42            $crate::servo_tracing::$backend_macro!(
43                $span_name,
44                servo_profiling = true
45                $(, $($fields)+)?
46            )
47        }
48        #[cfg(not(feature = "tracing"))]
49        {
50            $crate::dummy_tracing::Span()
51        }
52    }};
53}
54
55#[doc(hidden)]
56#[macro_export]
57macro_rules! __profiling_event {
58    ($backend_macro:ident, $event_name:literal $(, $($fields:tt)+)?) => {{
59        #[cfg(feature = "tracing")]
60        $crate::servo_tracing::$backend_macro!(
61            name: $event_name,
62            servo_profiling = true
63            $(, $($fields)+)?
64        );
65    }};
66}
67
68/// Provides API compatible dummies for the tracing-rs APIs we use
69/// if tracing is disabled. Hence, nothing will be traced
70pub mod dummy_tracing {
71    use std::fmt::Display;
72    use std::marker::PhantomData;
73
74    pub struct Span();
75
76    pub struct EnteredSpan(Span);
77    pub struct Entered<'a>(PhantomData<&'a Span>);
78
79    impl Span {
80        pub fn enter(&self) -> Entered<'_> {
81            Entered(PhantomData)
82        }
83
84        pub fn entered(self) -> EnteredSpan {
85            EnteredSpan(self)
86        }
87
88        pub fn in_scope<F: FnOnce() -> T, T>(&self, f: F) -> T {
89            // We still need to execute the function, even if tracing is disabled.
90            f()
91        }
92    }
93
94    impl EnteredSpan {}
95
96    impl Entered<'_> {}
97
98    #[derive(Debug)]
99    struct Level();
100
101    #[expect(dead_code)]
102    impl Level {
103        /// The "error" level.
104        ///
105        /// Designates very serious errors.
106        pub const ERROR: Level = Level();
107        /// The "warn" level.
108        ///
109        /// Designates hazardous situations.
110        pub const WARN: Level = Level();
111        /// The "info" level.
112        ///
113        /// Designates useful information.
114        pub const INFO: Level = Level();
115        /// The "debug" level.
116        ///
117        /// Designates lower priority information.
118        pub const DEBUG: Level = Level();
119        /// The "trace" level.
120        ///
121        /// Designates very low priority, often extremely verbose, information.
122        pub const TRACE: Level = Level();
123        /// Returns the string representation of the `Level`.
124        ///
125        /// This returns the same string as the `fmt::Display` implementation.
126        pub fn as_str(&self) -> &'static str {
127            "disabled"
128        }
129    }
130    impl Display for Level {
131        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132            write!(f, "{}", self.as_str())
133        }
134    }
135}
136
137/// Constructs a span at the trace level
138///
139/// This macro creates a Span for the purpose of instrumenting code to measure
140/// the execution time of the span.
141/// If the `tracing` feature (of the crate using this macro) is disabled, then
142/// the Span implementation will be replaced with a dummy, that does not record
143/// anything.
144///
145/// Attention: This macro requires the user crate to have a `tracing` feature,
146/// which can be used to disable the effects of this macro.
147#[macro_export]
148macro_rules! trace_span {
149    ($span_name:literal $(, $($fields:tt)+)?) => {
150        $crate::__profiling_span!(trace_span, $span_name $(, $($fields)+)?)
151    };
152}
153
154/// Constructs a span at the debug level
155///
156/// This macro creates a Span for the purpose of instrumenting code to measure
157/// the execution time of the span.
158/// If the `tracing` feature (of the crate using this macro) is disabled, then
159/// the Span implementation will be replaced with a dummy, that does not record
160/// anything.
161///
162/// Attention: This macro requires the user crate to have a `tracing` feature,
163/// which can be used to disable the effects of this macro.
164#[macro_export]
165macro_rules! debug_span {
166    ($span_name:literal $(, $($fields:tt)+)?) => {
167        $crate::__profiling_span!(debug_span, $span_name $(, $($fields)+)?)
168    };
169}
170
171/// Constructs a span at the info level
172///
173/// This macro creates a Span for the purpose of instrumenting code to measure
174/// the execution time of the span.
175/// If the `tracing` feature (of the crate using this macro) is disabled, then
176/// the Span implementation will be replaced with a dummy, that does not record
177/// anything.
178///
179/// Attention: This macro requires the user crate to have a `tracing` feature,
180/// which can be used to disable the effects of this macro.
181#[macro_export]
182macro_rules! info_span {
183    ($span_name:literal $(, $($fields:tt)+)?) => {
184        $crate::__profiling_span!(info_span, $span_name $(, $($fields)+)?)
185    };
186}
187
188/// Emit an event at the trace level
189///
190/// This macro creates an Event for the purpose of instrumenting code to measure
191/// the execution time between events.
192///
193/// If the `tracing` feature (of the crate using this macro) is disabled, this
194/// macro expands to nothing.
195///
196/// Attention: This macro requires the user crate to have a `tracing` feature,
197/// which can be used to disable the effects of this macro.
198#[macro_export]
199macro_rules! trace_event {
200    ($event_name:literal $(, $($fields:tt)+)?) => {
201        $crate::__profiling_event!(trace, $event_name $(, $($fields)+)?)
202    };
203}
204
205/// Emit an event at the debug level
206///
207/// This macro creates an Event for the purpose of instrumenting code to measure
208/// the execution time between events.
209///
210/// If the `tracing` feature (of the crate using this macro) is disabled, this
211/// macro expands to nothing.
212///
213/// Attention: This macro requires the user crate to have a `tracing` feature,
214/// which can be used to disable the effects of this macro.
215#[macro_export]
216macro_rules! debug_event {
217    ($event_name:literal $(, $($fields:tt)+)?) => {
218        $crate::__profiling_event!(debug, $event_name $(, $($fields)+)?)
219    };
220}
221
222/// Emit an event at the info level
223///
224/// This macro creates an Event for the purpose of instrumenting code to measure
225/// the execution time between events.
226///
227/// If the `tracing` feature (of the crate using this macro) is disabled, this
228/// macro expands to nothing.
229///
230/// Attention: This macro requires the user crate to have a `tracing` feature,
231/// which can be used to disable the effects of this macro.
232#[macro_export]
233macro_rules! info_event {
234    ($event_name:literal $(, $($fields:tt)+)?) => {
235        $crate::__profiling_event!(info, $event_name $(, $($fields)+)?)
236    };
237}
238
239#[cfg(feature = "tracing")]
240pub use tracing as servo_tracing;