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