Skip to main content

gc/
malloc.rs

1/// Default GC trigger threshold, matching QuickJS `JS_NewRuntime2`.
2pub const DEFAULT_GC_THRESHOLD: usize = 256 * 1024;
3
4/// Per-allocation accounting overhead, matching QuickJS `MALLOC_OVERHEAD` on non-Apple platforms.
5pub const MALLOC_OVERHEAD: usize = 8;
6
7/// Tracked heap usage, matching QuickJS `JSMallocState`.
8#[derive(Debug, Clone)]
9pub struct MallocState {
10    pub malloc_count: usize,
11    pub malloc_size: usize,
12    pub malloc_limit: usize,
13}
14
15impl Default for MallocState {
16    fn default() -> Self {
17        MallocState {
18            malloc_count: 0,
19            malloc_size: 0,
20            malloc_limit: 0,
21        }
22    }
23}
24
25impl MallocState {
26    pub fn new() -> Self {
27        Self::default()
28    }
29
30    pub fn set_limit(&mut self, limit: usize) {
31        self.malloc_limit = limit;
32    }
33
34    pub fn would_exceed(&self, size: usize) -> bool {
35        if self.malloc_limit == 0 {
36            return false;
37        }
38        self.malloc_size.saturating_add(size) > self.malloc_limit.saturating_sub(1)
39    }
40
41    pub fn record_alloc(&mut self, usable_size: usize) {
42        self.malloc_count += 1;
43        self.malloc_size += usable_size + MALLOC_OVERHEAD;
44    }
45
46    pub fn record_free(&mut self, usable_size: usize) {
47        self.malloc_count = self.malloc_count.saturating_sub(1);
48        self.malloc_size = self
49            .malloc_size
50            .saturating_sub(usable_size + MALLOC_OVERHEAD);
51    }
52}