Skip to main content

sim_lib_gc_tracing/
lib.rs

1#![forbid(unsafe_code)]
2#![deny(missing_docs)]
3//! Bounded stop-the-world tracing collection for managed arenas.
4
5use std::{error::Error, fmt};
6
7use sim_lib_mutation::{ArenaError, EdgeId, ManagedId};
8
9mod collector;
10mod correctness;
11mod finalization;
12
13pub use collector::{collect, collect_with_finalization};
14pub use correctness::CorrectnessDimension;
15pub use finalization::{FinalizationRecord, FinalizationRegistry};
16
17/// Independently enforced limits for one collection.
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct CollectionLimits {
20    /// Maximum arena objects admitted.
21    pub objects: usize,
22    /// Maximum enumerated edges admitted.
23    pub edges: usize,
24    /// Maximum pending iterative mark stack length.
25    pub stack: usize,
26    /// Maximum charged root, object, edge, ephemeron, and sweep operations.
27    pub work: usize,
28    /// Maximum weak and ephemeron entries cleared.
29    pub clears: usize,
30    /// Maximum finalization records produced and admitted.
31    pub finalizers: usize,
32}
33
34/// A resource class which refused collection.
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub enum LimitKind {
37    /// Arena objects.
38    Objects,
39    /// Enumerated edges.
40    Edges,
41    /// Pending mark entries.
42    Stack,
43    /// Total charged operations.
44    Work,
45    /// Weak and ephemeron clears.
46    Clears,
47    /// Finalization records.
48    Finalizers,
49}
50
51/// Inspectable evidence for a collection refused before mutation.
52#[derive(Clone, Debug, Eq, PartialEq)]
53pub struct FailureReceipt {
54    /// Snapshot mutation epoch.
55    pub mutation_epoch: u64,
56    /// Exhausted resource.
57    pub kind: LimitKind,
58    /// Configured maximum.
59    pub limit: usize,
60    /// Required amount at refusal.
61    pub required: usize,
62}
63
64/// Deterministic evidence for a completed collection.
65#[derive(Clone, Debug, Eq, PartialEq)]
66pub struct CollectionReceipt {
67    /// Snapshot mutation epoch used to plan the sweep.
68    pub mutation_epoch: u64,
69    /// Reachable objects in allocation order.
70    pub marked: Vec<ManagedId>,
71    /// Reclaimed objects in allocation order.
72    pub swept: Vec<ManagedId>,
73    /// Number of edges enumerated.
74    pub edges: usize,
75    /// Total charged operations.
76    pub work: usize,
77    /// Weak edges cleared as `(owner, edge)`.
78    pub cleared_weak: Vec<(ManagedId, EdgeId)>,
79    /// Ephemerons cleared as `(owner, edge)`.
80    pub cleared_ephemerons: Vec<(ManagedId, EdgeId)>,
81    /// Finalization records admitted after arena mutation completed.
82    pub finalization: Vec<FinalizationRecord>,
83}
84
85/// A fail-closed collection error.
86#[derive(Clone, Debug, Eq, PartialEq)]
87pub enum CollectionError {
88    /// A budget could not admit the complete read-only plan.
89    Limit(FailureReceipt),
90    /// The arena rejected a stale edge or atomic sweep.
91    Arena(ArenaError),
92}
93
94impl fmt::Display for CollectionError {
95    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96        match self {
97            Self::Limit(r) => write!(
98                f,
99                "collection {:?} limit {} requires {}",
100                r.kind, r.limit, r.required
101            ),
102            Self::Arena(error) => error.fmt(f),
103        }
104    }
105}
106impl Error for CollectionError {}
107impl From<ArenaError> for CollectionError {
108    fn from(value: ArenaError) -> Self {
109        Self::Arena(value)
110    }
111}
112
113#[cfg(test)]
114mod tests;