summaryrefslogtreecommitdiffstats
path: root/servo/components/style/gecko/profiler.rs
blob: db269b497d1b3474947fbec31b2000d69315c982 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

//! Gecko profiler support.
//!
//! Use the `profiler_label!` macro from macros.rs.

use crate::gecko_bindings::structs;

/// A label describing a category of work that style threads can perform.
pub enum ProfilerLabel {
    /// Style computation.
    Style,
    /// Style sheet parsing.
    Parse,
}

/// RAII object that constructs and destroys a C++ AutoProfilerLabel object
/// pointed to be the specified reference.
#[cfg(feature = "gecko_profiler")]
pub struct AutoProfilerLabel<'a>(&'a mut structs::AutoProfilerLabel);

#[cfg(feature = "gecko_profiler")]
impl<'a> AutoProfilerLabel<'a> {
    /// Creates a new AutoProfilerLabel with the specified label type.
    ///
    /// unsafe since the caller must ensure that `label` is allocated on the
    /// stack.
    #[inline]
    pub unsafe fn new(
        label: &mut std::mem::MaybeUninit<structs::AutoProfilerLabel>,
        label_type: ProfilerLabel,
    ) -> AutoProfilerLabel {
        let category_pair = match label_type {
            ProfilerLabel::Style => structs::JS::ProfilingCategoryPair_LAYOUT_StyleComputation,
            ProfilerLabel::Parse => structs::JS::ProfilingCategoryPair_LAYOUT_CSSParsing,
        };
        structs::Gecko_Construct_AutoProfilerLabel(label.as_mut_ptr(), category_pair);
        AutoProfilerLabel(&mut *label.as_mut_ptr())
    }
}

#[cfg(feature = "gecko_profiler")]
impl<'a> Drop for AutoProfilerLabel<'a> {
    #[inline]
    fn drop(&mut self) {
        unsafe {
            structs::Gecko_Destroy_AutoProfilerLabel(self.0);
        }
    }
}

/// Whether the Gecko profiler is currently active.
///
/// This implementation must be kept in sync with
/// `mozilla::profiler::detail::RacyFeatures::IsActive`.
#[cfg(feature = "gecko_profiler")]
#[inline]
pub fn profiler_is_active() -> bool {
    use self::structs::profiler::detail;
    use std::mem;
    use std::sync::atomic::{AtomicU32, Ordering};

    let active_and_features: &AtomicU32 =
        unsafe { mem::transmute(&detail::RacyFeatures_sActiveAndFeatures) };
    (active_and_features.load(Ordering::Relaxed) & detail::RacyFeatures_Active) != 0
}

/// Always false when the Gecko profiler is disabled.
#[cfg(not(feature = "gecko_profiler"))]
#[inline]
pub fn profiler_is_active() -> bool {
    false
}