#heap #vm #garbage-collection #automatic #gc

managed-heap

An implementation of a virtual heap, inspired by VMs like the JVM. Currently supports automatic garbage collection, but no defragmentation

6 releases

0.1.5 Dec 29, 2018
0.1.4 Dec 23, 2018

#667 in Memory management

26 downloads per month

MIT license

43KB
1K SLoC

Build Status

Managed Heap

An implementation of virtual heap, inspired by VMs like the JVM. Currently supports automatic garbage collection, but no defragmentation.

Usage

Since the crate is still WIP, there is no documentation. You can look into the tests mod in src/managed.rs for examples though.


lib.rs:

An implementation of virtual heap, inspired by VMs like the JVM. It can be used while creating your own virtual machine in Rust.

To use it, you have to implement the traits in the trace module.

Example

extern crate managed_heap;

use managed_heap::managed::*;
use managed_heap::trace::*;
use managed_heap::address::*;

struct MockGcRoot {
    used_elems: Vec<IntegerObject>,
}

impl MockGcRoot {
    pub fn new(used_elems: Vec<IntegerObject>) -> Self {
        MockGcRoot { used_elems }
    }

    pub fn clear(&mut self) {
        self.used_elems.clear();
    }
}

unsafe impl GcRoot<IntegerObject> for MockGcRoot {
    fn children<'a>(&'a mut self) -> Box<Iterator<Item = &'a mut IntegerObject> + 'a> {
        Box::new(self.used_elems.iter_mut())
    }
}

#[derive(Debug)]
struct IntegerObject(Address);

impl IntegerObject {
    pub fn new(heap: &mut ManagedHeap, value: isize) -> Self {
        // reserve one usize for mark byte
        let mut address = heap.alloc(2).unwrap();

        address.write(false as usize);
        (address + 1).write(value as usize);

        IntegerObject(address)
    }

    pub fn get(&self) -> isize {
        *(self.0 + 1) as isize
    }
}

impl From<Address> for IntegerObject {
    fn from(address: Address) -> Self {
        IntegerObject(address)
    }
}

impl Into<Address> for IntegerObject {
    fn into(self) -> Address {
        self.0
    }
}

unsafe impl Traceable for IntegerObject {
    fn mark(&mut self) {
        self.0.write(true as usize);
    }

    fn unmark(&mut self) {
        self.0.write(false as usize);
    }

    fn is_marked(&self) -> bool {
        (*self.0) != 0
    }
}

let mut heap = ManagedHeap::new(100);
let mut i = IntegerObject::new(&mut heap, -42);

assert_eq!(-42, i.get());
assert_eq!(false, i.is_marked());

i.mark();
assert_eq!(true, i.is_marked());

No runtime deps