Skip to main content

gc/
heap.rs

1use crate::header::{GcId, GcObjectType, GcPhase};
2use crate::malloc::MallocState;
3use crate::runtime::{GcObject, GcRuntime, MarkFunc};
4
5/// Opaque handle to a GC-managed object.
6#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
7pub struct GcRef(pub GcId);
8
9/// High-level heap API wrapping QuickJS-style `GcRuntime`.
10pub struct GcHeap {
11    rt: GcRuntime,
12}
13
14impl GcHeap {
15    pub fn new() -> Self {
16        GcHeap {
17            rt: GcRuntime::new(),
18        }
19    }
20
21    pub fn malloc_state(&self) -> &MallocState {
22        self.rt.malloc_state()
23    }
24
25    pub fn malloc_state_mut(&mut self) -> &mut MallocState {
26        self.rt.malloc_state_mut()
27    }
28
29    pub fn gc_threshold(&self) -> usize {
30        self.rt.gc_threshold()
31    }
32
33    pub fn set_gc_threshold(&mut self, threshold: usize) {
34        self.rt.set_gc_threshold(threshold);
35    }
36
37    pub fn gc_phase(&self) -> GcPhase {
38        self.rt.gc_phase()
39    }
40
41    pub fn alloc<O: GcObject>(&mut self, object: O, ty: GcObjectType) -> GcRef {
42        self.trigger_gc(std::mem::size_of::<O>());
43        GcRef(self.rt.add_gc_object(Box::new(object), ty))
44    }
45
46    pub fn dup(&mut self, reference: GcRef) -> GcRef {
47        GcRef(self.rt.dup_gc(reference.0))
48    }
49
50    pub fn free(&mut self, reference: GcRef) {
51        self.rt.free_gc(reference.0);
52    }
53
54    pub fn run_gc(&mut self) {
55        self.rt.run_gc();
56    }
57
58    pub fn trigger_gc(&mut self, alloc_size: usize) {
59        self.rt.trigger_gc(alloc_size);
60    }
61
62    pub fn is_live(&self, reference: GcRef) -> bool {
63        self.rt.is_live_object(reference.0)
64    }
65
66    pub fn exists(&self, reference: GcRef) -> bool {
67        self.rt.object_exists(reference.0)
68    }
69
70    pub fn ref_count(&self, reference: GcRef) -> i32 {
71        self.rt.ref_count(reference.0)
72    }
73
74    pub fn mark_children(&mut self, reference: GcRef, mark_func: MarkFunc) {
75        self.rt.mark_children(reference.0, mark_func);
76    }
77
78    pub(crate) fn header_mut(&mut self, reference: GcRef) -> &mut crate::header::GcObjectHeader {
79        self.rt.header_mut(reference.0)
80    }
81
82    pub fn runtime(&self) -> &GcRuntime {
83        &self.rt
84    }
85
86    pub fn runtime_mut(&mut self) -> &mut GcRuntime {
87        &mut self.rt
88    }
89}
90
91impl Default for GcHeap {
92    fn default() -> Self {
93        Self::new()
94    }
95}