mmtk/util/
slot_logger.rs

1//! This is a simple module to log slogs and check for duplicate slots.
2//!
3//! It uses a hash-set to keep track of slots, and is so very expensive.
4//! We currently only use this as part of the `extreme_assertions` feature.
5//!
6
7use crate::plan::Plan;
8use crate::vm::slot::Slot;
9use crate::vm::VMBinding;
10use std::collections::HashSet;
11use std::sync::RwLock;
12
13pub struct SlotLogger<SL: Slot> {
14    // A private hash-set to keep track of slots.
15    slot_log: RwLock<HashSet<SL>>,
16}
17
18unsafe impl<SL: Slot> Sync for SlotLogger<SL> {}
19
20impl<SL: Slot> SlotLogger<SL> {
21    pub fn new() -> Self {
22        Self {
23            slot_log: Default::default(),
24        }
25    }
26
27    /// Logs a slot.
28    /// Panics if the slot was already logged.
29    ///
30    /// # Arguments
31    ///
32    /// * `slot` - The slot to log.
33    ///
34    pub fn log_slot(&self, slot: SL) {
35        trace!("log_slot({:?})", slot);
36        let mut slot_log = self.slot_log.write().unwrap();
37        assert!(
38            slot_log.insert(slot),
39            "duplicate slot ({:?}) detected",
40            slot
41        );
42    }
43
44    /// Reset the slot logger by clearing the hash-set of slots.
45    /// This function is called at the end of each GC iteration.
46    ///
47    pub fn reset(&self) {
48        let mut slot_log = self.slot_log.write().unwrap();
49        slot_log.clear();
50    }
51}
52
53/// Whether we should check duplicate slots. This depends on the actual plan.
54pub fn should_check_duplicate_slots<VM: VMBinding>(plan: &dyn Plan<VM = VM>) -> bool {
55    // If a plan allows tracing duplicate edges, we should not run this check.
56    !plan.constraints().may_trace_duplicate_edges
57}