fxprof_processed_profile/
frame.rs

1use bitflags::bitflags;
2
3use crate::category::CategoryPairHandle;
4use crate::global_lib_table::LibraryHandle;
5use crate::profile::StringHandle;
6
7/// A part of the information about a single stack frame.
8#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
9pub enum Frame {
10    /// A code address taken from the instruction pointer.
11    ///
12    /// This code address will be resolved to a library-relative address using
13    /// the library mappings on the process which were specified using
14    /// [`Profile::add_lib_mapping`](crate::Profile::add_lib_mapping).
15    InstructionPointer(u64),
16    /// A code address taken from a return address
17    ///
18    /// This code address will be resolved to a library-relative address using
19    /// the library mappings on the process which were specified using
20    /// [`Profile::add_lib_mapping`](crate::Profile::add_lib_mapping).
21    ReturnAddress(u64),
22    /// A code address taken from a return address, but adjusted so that it
23    /// points into the previous instruction. Usually this is "return address
24    /// minus one byte", but some unwinders subtract 2 or 4 bytes if they know
25    /// more about the architecture-dependent instruction size.
26    ///
27    /// When you call a function with a call instruction, the return address
28    /// is set up in such a way that, once the called function returns, the CPU
29    /// continues executing after the call instruction. That means that the return
30    /// address points to the instruction *after* the call instruction. But for
31    /// stack unwinding, you're interested in **the call instruction itself**.
32    /// The call instruction and the instruction after often have very different
33    /// symbol information (different line numbers, or even different inline stacks).
34    ///
35    /// This code address will be resolved to a library-relative address using
36    /// the library mappings on the process which were specified using
37    /// [`Profile::add_lib_mapping`](crate::Profile::add_lib_mapping).
38    AdjustedReturnAddress(u64),
39    /// A relative address taken from the instruction pointer which
40    /// has already been resolved to a `LibraryHandle`.
41    RelativeAddressFromInstructionPointer(LibraryHandle, u32),
42    /// A relative address taken from a return address which
43    /// has already been resolved to a `LibraryHandle`.
44    RelativeAddressFromReturnAddress(LibraryHandle, u32),
45    /// A relative address taken from an adjusted return address which
46    /// has already been resolved to a `LibraryHandle`.
47    RelativeAddressFromAdjustedReturnAddress(LibraryHandle, u32),
48    /// A string, containing an index returned by
49    /// [`Profile::intern_string`](crate::Profile::intern_string).
50    Label(StringHandle),
51}
52
53/// All the information about a single stack frame.
54#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
55pub struct FrameInfo {
56    /// The absolute address or label of this frame.
57    pub frame: Frame,
58    /// The category pair of this frame.
59    pub category_pair: CategoryPairHandle,
60    /// The flags of this frame. Use `FrameFlags::empty()` if unsure.
61    pub flags: FrameFlags,
62}
63
64bitflags! {
65    /// Flags for a stack frame.
66    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
67    pub struct FrameFlags: u32 {
68        /// Set on frames which are JavaScript functions.
69        const IS_JS = 0b00000001;
70
71        /// Set on frames which are not strictly JavaScript functions but which
72        /// should be included in the JS-only call tree, such as DOM API calls.
73        const IS_RELEVANT_FOR_JS = 0b00000010;
74    }
75}