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/// Provides API compatible dummies for the tracing-rs APIs we use
37/// if tracing is disabled. Hence, nothing will be traced
38pub mod dummy_tracing {
39    use std::fmt::Display;
40    use std::marker::PhantomData;
41
42    pub struct Span();
43
44    pub struct EnteredSpan(Span);
45    pub struct Entered<'a>(PhantomData<&'a Span>);
46
47    impl Span {
48        pub fn enter(&self) -> Entered<'_> {
49            Entered(PhantomData)
50        }
51
52        pub fn entered(self) -> EnteredSpan {
53            EnteredSpan(self)
54        }
55
56        pub fn in_scope<F: FnOnce() -> T, T>(&self, f: F) -> T {
57            // We still need to execute the function, even if tracing is disabled.
58            f()
59        }
60    }
61
62    impl EnteredSpan {}
63
64    impl Entered<'_> {}
65
66    #[derive(Debug)]
67    struct Level();
68
69    #[expect(dead_code)]
70    impl Level {
71        /// The "error" level.
72        ///
73        /// Designates very serious errors.
74        pub const ERROR: Level = Level();
75        /// The "warn" level.
76        ///
77        /// Designates hazardous situations.
78        pub const WARN: Level = Level();
79        /// The "info" level.
80        ///
81        /// Designates useful information.
82        pub const INFO: Level = Level();
83        /// The "debug" level.
84        ///
85        /// Designates lower priority information.
86        pub const DEBUG: Level = Level();
87        /// The "trace" level.
88        ///
89        /// Designates very low priority, often extremely verbose, information.
90        pub const TRACE: Level = Level();
91        /// Returns the string representation of the `Level`.
92        ///
93        /// This returns the same string as the `fmt::Display` implementation.
94        pub fn as_str(&self) -> &'static str {
95            "disabled"
96        }
97    }
98    impl Display for Level {
99        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100            write!(f, "{}", self.as_str())
101        }
102    }
103}
104
105/// Constructs a span at the trace level
106///
107/// This macro creates a Span for the purpose of instrumenting code to measure
108/// the execution time of the span.
109/// If the `tracing` feature (of the crate using this macro) is disabled, then
110/// the Span implementation will be replaced with a dummy, that does not record
111/// anything.
112///
113/// Attention: This macro requires the user crate to have a `tracing` feature,
114/// which can be used to disable the effects of this macro.
115#[macro_export]
116macro_rules! trace_span {
117    ($span_name:literal, $($field:tt)*) => {
118        {
119        #[cfg(feature = "tracing")]
120        {
121            $crate::servo_tracing::trace_span!(
122                $span_name,
123                servo_profiling = true,
124                $($field)*
125            )
126        }
127        #[cfg(not(feature = "tracing"))]
128        { $crate::dummy_tracing::Span() }
129        }
130    };
131    ($span_name:literal) => {
132        {
133         #[cfg(feature = "tracing")]
134         {
135             $crate::servo_tracing::trace_span!(
136                $span_name,
137                servo_profiling = true,
138             )
139         }
140        #[cfg(not(feature = "tracing"))]
141        { $crate::dummy_tracing::Span() }
142        }
143    };
144}
145
146/// Constructs a span at the info level
147///
148/// This macro creates a Span for the purpose of instrumenting code to measure
149/// the execution time of the span.
150/// If the `tracing` feature (of the crate using this macro) is disabled, then
151/// the Span implementation will be replaced with a dummy, that does not record
152/// anything.
153///
154/// Attention: This macro requires the user crate to have a `tracing` feature,
155/// which can be used to disable the effects of this macro.
156#[macro_export]
157macro_rules! info_span {
158    ($span_name:literal, $($field:tt)*) => {
159        {
160        #[cfg(feature = "tracing")]
161        {
162            $crate::servo_tracing::info_span!(
163                $span_name,
164                servo_profiling = true,
165                $($field)*
166            )
167        }
168        #[cfg(not(feature = "tracing"))]
169        { $crate::dummy_tracing::Span() }
170        }
171    };
172    ($span_name:literal) => {
173        {
174         #[cfg(feature = "tracing")]
175         {
176             $crate::servo_tracing::info_span!(
177                $span_name,
178                servo_profiling = true,
179             )
180         }
181        #[cfg(not(feature = "tracing"))]
182        { $crate::dummy_tracing::Span() }
183        }
184    };
185}
186
187#[cfg(feature = "tracing")]
188pub use tracing as servo_tracing;