diff options
Diffstat (limited to 'bytecode/src/heap.rs')
| -rw-r--r-- | bytecode/src/heap.rs | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/bytecode/src/heap.rs b/bytecode/src/heap.rs index f1b9d81..45ce283 100644 --- a/bytecode/src/heap.rs +++ b/bytecode/src/heap.rs @@ -3,8 +3,10 @@ use std::error::Error; pub const NUM_LOCALS: usize = 8; +#[derive(Debug)] pub struct Heap { pub buf: Vec<u64>, + first_active: bool, free_ptr: usize, last_live: usize, pub locals: [Value; NUM_LOCALS], @@ -14,6 +16,7 @@ impl Heap { pub fn new() -> Heap { Heap { buf: Vec::new(), + first_active: true, free_ptr: 0, last_live: 0, locals: [Value(0); NUM_LOCALS], @@ -24,7 +27,7 @@ impl Heap { let Some(q) = Value(self.buf[p]).to_pointer() else { return false; }; - return (self.free_ptr < self.buf.len() / 2) == (q < self.buf.len() / 2); + return self.first_active == (q < self.buf.len() / 2); } fn alloc_size(&self, p: usize) -> usize { @@ -64,50 +67,45 @@ impl Heap { Value::from_pointer(q) } + fn size(&self) -> usize { + if self.first_active { + self.free_ptr + } else { + self.free_ptr - self.buf.len() / 2 + } + } + fn collect_garbage(&mut self) { - if self.free_ptr < 2 * self.last_live { + if self.size() < 2 * self.last_live { return; } // Swap the heaps. - if self.free_ptr < self.buf.len() / 2 { + if self.first_active { + self.first_active = false; self.free_ptr = self.buf.len() / 2; } else { + self.first_active = true; self.free_ptr = 0; } for i in 0..self.locals.len() { self.locals[i] = self.process_gc_value(self.locals[i]); } - if self.free_ptr < self.buf.len() / 2 { - self.last_live = self.free_ptr; - } else { - self.last_live = self.free_ptr - self.buf.len() / 2; - } + self.last_live = self.size(); } fn more_space(&mut self, size_hint: usize) { - let current_size = self.buf.len() / 2; - let mut new_size = current_size * 2; + let mut new_size = self.buf.len() / 2; if new_size == 0 { new_size = 1; } - while new_size <= current_size + size_hint { + while new_size < self.free_ptr + size_hint { new_size *= 2; } - let active; - if self.free_ptr < current_size { - active = &self.buf[..current_size]; - } else { - active = &self.buf[current_size..]; - self.free_ptr -= current_size; - } - - let mut new_buf = Vec::with_capacity(new_size * 2); - new_buf.extend_from_slice(active); - new_buf.resize(new_size * 2, 0); - self.buf = new_buf; + self.first_active = true; + self.buf.resize(new_size * 2, 0); } pub fn alloc(&mut self, size: i64) -> Result<usize, Box<dyn Error>> { @@ -116,8 +114,8 @@ impl Heap { } let usize = usize::try_from(size).expect("32 bits in 2024 LULW"); self.collect_garbage(); - if self.free_ptr + usize + 1 >= self.buf.len() / 2 { - self.more_space(usize); + if self.size() + usize + 1 > self.buf.len() / 2 { + self.more_space(usize + 1); } let p = self.simple_alloc(usize::try_from(size).expect("using 32 bits in 2024 LULW")); |
