Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
notJoon committed Nov 24, 2023
1 parent eab3cd2 commit 5165d9e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 34 deletions.
10 changes: 6 additions & 4 deletions src/gc.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use std::fmt;

use crate::{controller::PIController, vm::VM};
use crate::{controller::PIController, vm::VirtualMachine};

pub trait GarbageCollector {
fn collect(&self, vm: &mut VM);
fn collect(&self, vm: &mut VirtualMachine);
fn ty(&self) -> GCType;
fn new_instance(&self) -> Box<dyn GarbageCollector>;
fn adjust_confidence(&mut self, vm: &mut VirtualMachine);
fn trigger_gc(&mut self, vm: &mut VirtualMachine);
}

pub struct TriColorGC {
Expand Down Expand Up @@ -40,6 +42,6 @@ pub struct MarkAndSweep {

// impl GarbageCollector for MarkAndSweep {
// fn collect(&self, vm: &mut VM) {

// }
// }
// }
6 changes: 6 additions & 0 deletions src/heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use std::collections::BTreeSet;

// #[derive(Debug, PartialEq, Clone, Default)]
// pub struct Heap {
// pub roots: BTreeSet<>
// }
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod mem;
pub mod object;
pub mod vm;
pub mod gc;
pub mod heap;
20 changes: 5 additions & 15 deletions src/object.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use core::fmt;
use std::cell::RefCell;
use std::default;
use std::rc::Rc;

use crate::gc::TriColor;

Expand All @@ -22,14 +20,14 @@ impl fmt::Display for TypeValue {
pub struct Object {
pub ident: String,
pub value: Option<TypeValue>,
pub reference: Vec<Rc<RefCell<Object>>>,
pub reference: Vec<Object>,
pub marked: TriColor,
}

pub trait ObjectTrait {
fn new(ident: String, value: TypeValue) -> Self;
fn add_reference(&mut self, object: Object) -> usize;
fn delete_reference(&mut self, object: Rc<RefCell<Object>>) -> usize;
fn delete_reference(&mut self, object: Object) -> usize;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn to_string(&self) -> String;
Expand All @@ -47,12 +45,12 @@ impl ObjectTrait for Object {
}

fn add_reference(&mut self, object: Object) -> usize {
self.reference.push(Rc::new(RefCell::new(object)));
self.reference.push(object);
self.reference.len()
}

fn delete_reference(&mut self, object: Rc<RefCell<Object>>) -> usize {
self.reference.retain(|x| !Rc::ptr_eq(x, &object));
fn delete_reference(&mut self, object: Object) -> usize {
self.reference.retain(|x| x != &object);
self.reference.len()
}

Expand Down Expand Up @@ -87,11 +85,3 @@ impl default::Default for Object {
}
}
}

// pub trait ObjectMarker {
// fn mark_from_root(&self, vm: &mut VM) {
// for obj in &vm.stack {
// obj.co
// }
// }
// }
Empty file added src/stack.rs
Empty file.
56 changes: 50 additions & 6 deletions src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use core::fmt;

use crate::object::{Object, TypeValue};
use crate::{
gc::TriColor,
object::{Object, TypeValue},
};

#[derive(Debug, PartialEq, Default)]
#[derive(Debug, PartialEq, Default, Clone)]
pub enum GCStatus {
#[default]
Idle,
Expand All @@ -23,10 +26,12 @@ pub enum OpCode {
Halt,
Pop,
Push(TypeValue),
Mark,
Sweep,
}

#[derive(Debug, PartialEq, Default)]
pub struct VM {
#[derive(Debug, PartialEq, Default, Clone)]
pub struct VirtualMachine {
pub stack: Vec<Object>,
pub op_codes: Vec<OpCode>,
pub max_stack_size: usize,
Expand All @@ -49,9 +54,11 @@ pub trait VMTrait {
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn to_string(&self) -> String;

fn mark(&mut self);
}

impl VMTrait for VM {
impl VMTrait for VirtualMachine {
fn new(max_stack_size: usize, threshold: f64) -> Result<Self, VMError> {
if threshold <= 0.0 || threshold >= 100.0 {
return Err(VMError::InvalidRangeOfThreshold);
Expand Down Expand Up @@ -110,6 +117,41 @@ impl VMTrait for VM {
self.gc_status
)
}

fn mark(&mut self) {
self.op_codes.push(OpCode::Mark);
let mut mark_stack = Vec::new();

while let Some(mut obj) = self.stack.pop() {
if obj.marked == TriColor::White {
obj.marked = TriColor::Gray;
mark_stack.push(obj.clone());
}

if obj.reference.len() > 0 {
let mut ref_obj = obj.reference.pop().unwrap();
if ref_obj.marked == TriColor::White {
ref_obj.marked = TriColor::Gray;
mark_stack.push(ref_obj.clone());
}
obj.reference.push(ref_obj);
}
}

while let Some(mut obj) = mark_stack.pop() {
if obj.marked == TriColor::Gray {
obj.marked = TriColor::Black;
}

if obj.reference.len() > 0 {
let mut ref_obj = obj.reference.pop().unwrap();
if ref_obj.marked == TriColor::Gray {
ref_obj.marked = TriColor::Black;
}
obj.reference.push(ref_obj);
}
}
}
}

impl fmt::Display for VMError {
Expand Down Expand Up @@ -141,6 +183,8 @@ impl fmt::Display for OpCode {
OpCode::Push(ref i) => write!(f, "Push: {}", i),
OpCode::Pop => write!(f, "Pop"),
OpCode::Halt => write!(f, "Halt"),
OpCode::Mark => write!(f, "Mark"),
OpCode::Sweep => write!(f, "Sweep"),
}
}
}
}
18 changes: 9 additions & 9 deletions tests/vm_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
mod vm_tests {
use gc_simulator::{
object::{TypeValue, Object, ObjectTrait},
vm::{VMError, VMTrait, VM, OpCode},
vm::{VMError, VMTrait, VirtualMachine, OpCode},
};

static THRESHOLD: f64 = 0.75;

#[test]
fn test_new_vm() {
let max_stack_size = 10;
let vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

assert_eq!(vm.max_stack_size, max_stack_size);
assert_eq!(vm.stack, vec![]);
Expand All @@ -21,7 +21,7 @@ mod vm_tests {
#[test]
fn test_max_stack_size_exceed_max_int() {
let max_stack_size = usize::MAX;
let vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

assert_eq!(vm.max_stack_size, max_stack_size);
assert_eq!(vm.stack, vec![]);
Expand All @@ -32,7 +32,7 @@ mod vm_tests {
#[test]
fn test_push_objects_to_vm() {
let max_stack_size = 10;
let mut vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let mut vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

for i in 0..max_stack_size-1 {
let value = Object::new(
Expand All @@ -48,7 +48,7 @@ mod vm_tests {
#[test]
fn test_stack_overflow() {
let max_stack_size = 10;
let mut vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let mut vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

for i in 0..max_stack_size {
let value = Object::new(
Expand All @@ -69,7 +69,7 @@ mod vm_tests {
#[test]
fn test_pop() {
let max_stack_size = 10;
let mut vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let mut vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

for i in 0..max_stack_size {
let value = Object::new(
Expand All @@ -95,7 +95,7 @@ mod vm_tests {
#[test]
fn stack_underflow() {
let max_stack_size = 10;
let mut vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let mut vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

assert_eq!(
vm.pop().unwrap_err(),
Expand All @@ -106,7 +106,7 @@ mod vm_tests {
#[test]
fn test_op_code() {
let max_stack_size = 10;
let mut vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let mut vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

let value = Object::new(
String::from("test"),
Expand All @@ -123,7 +123,7 @@ mod vm_tests {
#[test]
fn test_vm_debug_string() {
let max_stack_size = 10;
let mut vm = VM::new(max_stack_size, THRESHOLD).unwrap();
let mut vm = VirtualMachine::new(max_stack_size, THRESHOLD).unwrap();

let value = Object::new(
String::from("test"),
Expand Down

0 comments on commit 5165d9e

Please sign in to comment.