sim_lib_mutation/managed/
arena_model.rs1pub trait EdgeVisitor {
3 fn strong(&mut self, edge: EdgeId, target: ManagedId);
5
6 fn weak(&mut self, edge: EdgeId, target: ManagedId);
8
9 fn ephemeron(&mut self, edge: EdgeId, key: ManagedId, value: ManagedId);
11}
12pub trait ManagedObject {
14 fn trace_edges(&self, visitor: &mut dyn EdgeVisitor);
16
17 fn clear_weak_edge(&mut self, edge: EdgeId, expected: ManagedId) -> bool;
23
24 fn clear_ephemeron_edge(
27 &mut self,
28 _edge: EdgeId,
29 _expected_key: ManagedId,
30 _expected_value: ManagedId,
31 ) -> bool {
32 false
33 }
34}
35
36#[derive(Clone, Copy, Debug, Eq, PartialEq)]
39pub struct HardCappedRetainPolicy {
40 max_objects: usize,
41}
42
43impl HardCappedRetainPolicy {
44 pub fn new(max_objects: usize) -> Result<Self, ArenaError> {
46 if max_objects == 0 {
47 return Err(ArenaError::InvalidCap);
48 }
49 Ok(Self { max_objects })
50 }
51
52 pub const fn max_objects(self) -> usize {
54 self.max_objects
55 }
56}
57
58#[derive(Clone, Copy, Debug, Eq, PartialEq)]
60pub enum ArenaError {
61 InvalidCap,
63 CapacityExceeded {
65 cap: usize,
67 },
68 IdentityExhausted,
70 StaleHandle(ManagedId),
72 StaleRoot(RootId),
74 ObjectRooted(ManagedId),
76 MutationEpochChanged {
78 expected: u64,
80 actual: u64,
82 },
83}
84
85impl fmt::Display for ArenaError {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 match self {
88 Self::InvalidCap => f.write_str("managed arena cap must be non-zero"),
89 Self::CapacityExceeded { cap } => write!(f, "managed arena hard cap {cap} reached"),
90 Self::IdentityExhausted => f.write_str("managed arena identity space exhausted"),
91 Self::StaleHandle(id) => write!(f, "stale managed handle {}", id.0),
92 Self::StaleRoot(id) => write!(f, "stale managed root {}", id.0),
93 Self::ObjectRooted(id) => write!(f, "managed object {} is rooted", id.0),
94 Self::MutationEpochChanged { expected, actual } => write!(
95 f,
96 "managed arena mutation epoch changed from {expected} to {actual}"
97 ),
98 }
99 }
100}
101
102impl Error for ArenaError {}
103
104pub struct TraceSnapshot<'a, T> {
106 roots: Vec<ManagedId>,
107 kept_alive: Vec<ManagedId>,
108 objects: &'a BTreeMap<ManagedId, T>,
109 mutation_epoch: u64,
110}
111
112impl<T: ManagedObject> TraceSnapshot<'_, T> {
113 pub const fn mutation_epoch(&self) -> u64 {
115 self.mutation_epoch
116 }
117 pub fn roots(&self) -> impl ExactSizeIterator<Item = ManagedId> + '_ {
119 self.roots.iter().copied()
120 }
121
122 pub fn kept_alive(&self) -> impl ExactSizeIterator<Item = ManagedId> + '_ {
124 self.kept_alive.iter().copied()
125 }
126
127 pub fn objects(&self) -> impl ExactSizeIterator<Item = ManagedId> + '_ {
129 self.objects.keys().copied()
130 }
131
132 pub fn visit_edges(
134 &self,
135 owner: ManagedId,
136 visitor: &mut dyn EdgeVisitor,
137 ) -> Result<(), ArenaError> {
138 self.objects
139 .get(&owner)
140 .ok_or(ArenaError::StaleHandle(owner))?
141 .trace_edges(visitor);
142 Ok(())
143 }
144}
145
146#[derive(Clone, Debug, Eq, PartialEq)]
148pub struct SafepointReceipt {
149 pub sequence: u64,
151 pub roots: Vec<ManagedId>,
153 pub objects: Vec<ManagedId>,
155}
156
157#[derive(Clone, Debug, Eq, PartialEq)]
163pub struct RoleProjectionReceipt<L> {
164 pub safepoint: SafepointReceipt,
166 pub mutation_epoch: u64,
168 pub roles: Vec<(ManagedId, L)>,
170}
171
172#[derive(Clone, Debug, Eq, PartialEq)]
174pub enum RoleProjectionError {
175 Limit {
177 limit: usize,
179 required: usize,
181 },
182 Arena(ArenaError),
184}
185
186impl fmt::Display for RoleProjectionError {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 match self {
189 Self::Limit { limit, required } => {
190 write!(f, "role projection limit {limit} requires {required}")
191 }
192 Self::Arena(error) => error.fmt(f),
193 }
194 }
195}
196
197impl Error for RoleProjectionError {}
198
199impl From<ArenaError> for RoleProjectionError {
200 fn from(error: ArenaError) -> Self {
201 Self::Arena(error)
202 }
203}
204
205#[derive(Clone, Debug, Eq, PartialEq)]
207pub struct TeardownReceipt {
208 pub objects: Vec<ManagedId>,
210 pub roots: Vec<RootId>,
212}
213
214pub struct CollectionMutationReceipt {
216 pub cleared_weak: Vec<(ManagedId, EdgeId)>,
218 pub cleared_ephemerons: Vec<(ManagedId, EdgeId)>,
220 pub swept: Vec<ManagedId>,
222}