mozjs/gc/
trace.rs

1use crate::jsapi::{Heap, JSObject, JSTracer};
2use crate::rust::{Runtime, Stencil};
3use mozjs_sys::trace::Traceable;
4use std::cell::RefCell;
5use std::ffi::c_void;
6
7use crate::typedarray::{TypedArray, TypedArrayElement};
8
9unsafe impl<T: TypedArrayElement> Traceable for TypedArray<T, Box<Heap<*mut JSObject>>> {
10    unsafe fn trace(&self, trc: *mut JSTracer) {
11        self.underlying_object().trace(trc);
12    }
13}
14
15unsafe impl Traceable for Runtime {
16    #[inline]
17    unsafe fn trace(&self, _: *mut JSTracer) {}
18}
19
20unsafe impl Traceable for Stencil {
21    #[inline]
22    unsafe fn trace(&self, _: *mut JSTracer) {}
23}
24
25/// Holds a set of JSTraceables that need to be rooted
26pub struct RootedTraceableSet {
27    set: Vec<*const dyn Traceable>,
28}
29
30thread_local!(
31    static ROOTED_TRACEABLES: RefCell<RootedTraceableSet>  = RefCell::new(RootedTraceableSet::new())
32);
33
34impl RootedTraceableSet {
35    fn new() -> RootedTraceableSet {
36        RootedTraceableSet { set: Vec::new() }
37    }
38
39    pub unsafe fn add(traceable: *const dyn Traceable) {
40        ROOTED_TRACEABLES.with(|traceables| {
41            traceables.borrow_mut().set.push(traceable);
42        });
43    }
44
45    pub unsafe fn remove(traceable: *const dyn Traceable) {
46        ROOTED_TRACEABLES.with(|traceables| {
47            let mut traceables = traceables.borrow_mut();
48            let idx = match traceables
49                .set
50                .iter()
51                .rposition(|x| *x as *const () == traceable as *const ())
52            {
53                Some(idx) => idx,
54                None => return,
55            };
56            traceables.set.remove(idx);
57        });
58    }
59
60    pub(crate) unsafe fn trace(&self, trc: *mut JSTracer) {
61        for traceable in &self.set {
62            (**traceable).trace(trc);
63        }
64    }
65}
66
67pub unsafe extern "C" fn trace_traceables(trc: *mut JSTracer, _: *mut c_void) {
68    ROOTED_TRACEABLES.with(|traceables| {
69        traceables.borrow().trace(trc);
70    });
71}