From fa49500139f365b9f620695af0ef59cd36b57ad7 Mon Sep 17 00:00:00 2001 From: Jur van den Berg Date: Mon, 3 Jun 2019 10:12:49 +0200 Subject: [PATCH] Switch the global list to Weak based pointers, allowing us to actually use rust lifetimes for heaps --- src/heap.rs | 46 +++++++++++++++++++++++----------------------- src/ops.rs | 22 ++++++++-------------- 2 files changed, 31 insertions(+), 37 deletions(-) diff --git a/src/heap.rs b/src/heap.rs index 26785f0..77cba42 100644 --- a/src/heap.rs +++ b/src/heap.rs @@ -1,12 +1,14 @@ use value::Value; -use std::rc::Rc; +use std::rc::{Rc, Weak}; use std::cell::RefCell; -pub type Heap = Rc>>; +pub type HeapInner = RefCell>; +pub type Heap = Rc; +pub type WeakHeap = Weak; #[derive(Debug,Default)] pub struct Heaps { - pub heaps: Vec + pub heaps: Vec } impl Heaps { @@ -20,13 +22,24 @@ impl Heaps { self.heaps.len() } - pub fn get(&mut self, i: usize) -> Heap { - self.heaps[i].clone() + pub fn get(&mut self, i: usize) -> Option { + if i >= self.len() { + return None + } + + let weak_ref = self.heaps[i].clone(); + let possibly_strong = weak_ref.upgrade(); + + if possibly_strong.is_none() { + self.heaps.remove(i); + } + + possibly_strong } pub fn alloc(&mut self, size: usize) -> Heap { let heap = Rc::new(RefCell::new(vec![Value::Int(0); size])); - self.heaps.push(heap.clone()); + self.heaps.push(Rc::downgrade(&heap)); heap } @@ -35,23 +48,10 @@ impl Heaps { } pub fn gc(&mut self) { - let pre_size = self.len(); - - if cfg!(feature = "debug:gc") { - for (i, heap) in self.heaps.iter().enumerate() { - eprintln!("GC heap {} ref = {}", i, Rc::strong_count(heap)); - } - } - - self.heaps = self.heaps.iter() - .filter(|e| Rc::strong_count(e) > 1) - .map(|e| Rc::clone(e)) - .collect(); - - let post_size = self.len(); - - if cfg!(feature = "debug:gc") { - eprintln!("GC reaped {} heaps", pre_size - post_size); + println!("GC PRE : {} weaks", self.len()); + for i in 0..self.len() { + println!("\theap: {} = {:?}", i, self.get(i)); } + println!("GC POST: {} weaks", self.len()); } } diff --git a/src/ops.rs b/src/ops.rs index 4755621..0f36606 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -267,20 +267,14 @@ fn invokevirtual(machine: &mut Machine) -> Result<()> { } fn ireturn(machine: &mut Machine) -> Result<()> { - // Lifetime for prev frame, allows gc to reap into the frame - { - let mut prev_frame: Frame = match machine.frame.pop() { - Some(a) => a, - None => return Err("Got no frame... somehow..."), - }; - let result = prev_frame.stack.pop()?; - let return_addr: i32 = prev_frame.get(0)?.try_into()?; - machine.cur_stack().push(result); - machine.block.seek(return_addr as usize)?; - } - - machine.heap.gc(); - Ok(()) + let mut prev_frame: Frame = match machine.frame.pop() { + Some(a) => a, + None => return Err("Got no frame... somehow..."), + }; + let result = prev_frame.stack.pop()?; + let return_addr: i32 = prev_frame.get(0)?.try_into()?; + machine.cur_stack().push(result); + machine.block.seek(return_addr as usize) } #[cfg(feature = "extra:sleep")]