1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
use super::*; pub trait Trace<T: Trace<T>> { fn trace(&self, tracer: &mut Tracer<T>); } pub struct Tracer<'a, T: Trace<T>> { pub(crate) new_sweep: usize, pub(crate) object_sweeps: &'a mut HashMap<Handle<T>, usize>, pub(crate) objects: &'a HashSet<Handle<T>>, } impl<'a, T: Trace<T>> Tracer<'a, T> { pub(crate) fn mark(&mut self, handle: Handle<T>) { let sweep = self.object_sweeps .entry(handle) .or_insert(self.new_sweep - 1); if *sweep != self.new_sweep && self.objects.contains(&handle) { *sweep = self.new_sweep; unsafe { (&*handle.ptr).trace(self); } } } } impl<O: Trace<O>> Trace<O> for Handle<O> { fn trace(&self, tracer: &mut Tracer<O>) { tracer.mark(*self); } } impl<O: Trace<O>> Trace<O> for Rooted<O> { fn trace(&self, tracer: &mut Tracer<O>) { self.handle().trace(tracer); } } use std::collections::{ HashMap as StdHashMap, VecDeque, LinkedList, }; impl<O: Trace<O>, T: Trace<O>> Trace<O> for [T] { fn trace(&self, tracer: &mut Tracer<O>) { self.iter().for_each(|object| object.trace(tracer)); } } impl<O: Trace<O>, T: Trace<O>> Trace<O> for VecDeque<T> { fn trace(&self, tracer: &mut Tracer<O>) { self.iter().for_each(|object| object.trace(tracer)); } } impl<O: Trace<O>, T: Trace<O>> Trace<O> for LinkedList<T> { fn trace(&self, tracer: &mut Tracer<O>) { self.iter().for_each(|object| object.trace(tracer)); } } impl<O: Trace<O>, K, V: Trace<O>> Trace<O> for StdHashMap<K, V> { fn trace(&self, tracer: &mut Tracer<O>) { self.values().for_each(|object| object.trace(tracer)); } } impl<O: Trace<O>, T: Trace<O>> Trace<O> for HashSet<T> { fn trace(&self, tracer: &mut Tracer<O>) { self.iter().for_each(|object| object.trace(tracer)); } }