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