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