1use core::fmt;
2
3#[cfg(feature = "mem_dbg")]
4use mem_dbg::{MemDbg, MemSize};
5
6#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
7#[cfg_attr(feature = "mem_dbg", copy_type)]
8#[derive(Debug, Clone, Copy)]
9pub struct StackFrame {
10 pub from_cdcl: bool,
13 pub active: TimeRange,
14}
15
16impl StackFrame {
17 pub fn new(start: u32, from_cdcl: bool) -> Self {
18 Self {
19 from_cdcl,
20 active: TimeRange {
21 start,
22 end: u32::MAX,
23 leaked: false,
24 },
25 }
26 }
27}
28
29#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
30#[cfg_attr(feature = "mem_dbg", copy_type)]
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
32pub struct TimeRange {
33 start: u32,
34 end: u32,
35 leaked: bool,
36}
37
38impl TimeRange {
39 pub fn sorted_overlap(&self, greater: &Self) -> bool {
40 debug_assert!(self.start <= greater.start);
41 debug_assert!(greater.end <= self.end || self.end < greater.start);
42 greater.end <= self.end
43 }
44
45 pub fn status(&self) -> TimeRangeStatus {
46 match (self.start, self.end, self.leaked) {
47 (0, end, leaked) => {
48 debug_assert!(end == u32::MAX && !leaked);
49 TimeRangeStatus::Global
50 }
51 (_, u32::MAX, leaked) => {
52 debug_assert!(!leaked);
53 TimeRangeStatus::Active
54 }
55 (_, _, true) => TimeRangeStatus::Leaked,
56 (_, _, false) => TimeRangeStatus::Ended,
57 }
58 }
59
60 pub fn end(&mut self, end: u32, leaked: bool) {
61 debug_assert!(self.status().is_active());
62 self.end = end;
63 self.leaked = leaked;
64 }
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum TimeRangeStatus {
69 Global,
70 Active,
71 Leaked,
72 Ended,
73}
74
75impl TimeRangeStatus {
76 pub fn is_global(self) -> bool {
77 matches!(self, Self::Global)
78 }
79 pub fn is_active(self) -> bool {
80 matches!(self, Self::Active)
81 }
82 pub fn is_leaked(self) -> bool {
83 matches!(self, Self::Leaked)
84 }
85 pub fn is_ended(self) -> bool {
86 matches!(self, Self::Ended)
87 }
88
89 pub fn is_alive(self) -> bool {
90 !self.is_ended()
91 }
92}
93
94impl fmt::Display for TimeRange {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 match self.status() {
97 TimeRangeStatus::Global => write!(f, "∞"),
98 TimeRangeStatus::Active => write!(f, "t{}→", self.start),
99 TimeRangeStatus::Leaked => write!(f, "t{}→t{}?", self.start, self.end),
100 TimeRangeStatus::Ended => write!(f, "t{}→t{}", self.start, self.end),
101 }
102 }
103}