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}