Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
notJoon committed Nov 27, 2023
1 parent dbf84ce commit 520923a
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 111 deletions.
6 changes: 0 additions & 6 deletions src/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,3 @@ impl fmt::Display for TriColor {
pub struct MarkAndSweep {
pub pi: PIController,
}

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

// }
// }
6 changes: 2 additions & 4 deletions src/heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
use crate::{
free_list::FreeList,
mem::{self, Memory},
object::{Object, ObjectAddress, ObjectTrait, Field, Address},
object::{Address, Field, Object, ObjectAddress, ObjectTrait},
};

#[derive(Debug, PartialEq, Clone)]
Expand Down Expand Up @@ -119,9 +119,7 @@ impl Heap {

/// Returns the address of the object that is next to the given address.
pub fn next_object(&self, addr: usize) -> Option<&Object> {
self.objects
.values()
.find(|obj| obj.get_address() > addr)
self.objects.values().find(|obj| obj.get_address() > addr)
}

pub fn prev_object(&self, addr: usize) -> Option<&Object> {
Expand Down
5 changes: 4 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use gc_simulator::vm::VirtualMachine;

fn main() {
println!("Hello, world!");
let vm = VirtualMachine::new(1025, 10.5);
println!("{:?}", vm);
}
9 changes: 9 additions & 0 deletions src/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@ impl Memory {
status: Status::Free,
}
}

pub fn inspector(&self) -> String {
match self.status {
Status::Free => String::from("Free"),
Status::Allocated => String::from("Allocated"),
Status::Marked => String::from("Marked"),
Status::Used => String::from("Used"),
}
}
}
10 changes: 8 additions & 2 deletions src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::gc::TriColor;

pub type ObjectAddress = usize;

// Global counter for generating sequential UUIDs
static COUNTER: AtomicUsize = AtomicUsize::new(0);

#[derive(Debug, PartialEq, Clone)]
Expand Down Expand Up @@ -189,11 +190,16 @@ impl default::Default for Object {

#[allow(non_snake_case)]
/// Generates a sequential UUID for simulating memory addresses.
///
///
/// It is also possible to customize the address by using the `inject_address` method.
fn generate_sequential_UUID() -> usize {
let counter = COUNTER.fetch_add(1, Ordering::SeqCst);
let uuid = Uuid::from_fields(0, 0, 0, &[1, 2, 3, 4, 5, 6, 7, 8]);
let uuid = Uuid::from_fields(
0xa1a2a3a4,
0xb1b2,
0xc1b2,
&[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x42],
);
uuid.as_u128() as usize + counter + 3
}

Expand Down
121 changes: 43 additions & 78 deletions src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use core::fmt;

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

#[derive(Debug, PartialEq, Default, Clone)]
pub enum GCStatus {
Expand Down Expand Up @@ -32,10 +29,6 @@ pub enum OpCode {

#[derive(Debug, PartialEq, Default, Clone)]
pub struct VirtualMachine {
/// heap manages the runtime, which is a collection of memory regions.
///
/// The runtime uses this memory to hold heap blocks that it fills up with values
/// in response to allocation requests
pub heap: Vec<Object>,
pub stack: Vec<Object>,
pub op_codes: Vec<OpCode>,
Expand All @@ -50,21 +43,8 @@ pub struct VirtualMachine {
pub gc_status: GCStatus,
}

pub trait VMTrait {
fn new(max_stack_size: usize, threshold: f64) -> Result<Self, VMError>
where
Self: Sized;
fn push(&mut self, obj: Object) -> Result<usize, VMError>;
fn pop(&mut self) -> Result<Object, VMError>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn to_string(&self) -> String;

// fn mark(&mut self);
}

impl VMTrait for VirtualMachine {
fn new(max_stack_size: usize, threshold: f64) -> Result<Self, VMError> {
impl VirtualMachine {
pub fn new(max_stack_size: usize, threshold: f64) -> Result<Self, VMError> {
if threshold <= 0.0 || threshold >= 100.0 {
return Err(VMError::InvalidRangeOfThreshold);
}
Expand All @@ -76,89 +56,56 @@ impl VMTrait for VirtualMachine {
})
}

fn push(&mut self, obj: Object) -> Result<usize, VMError> {
pub fn push(&mut self, obj: Object) -> Result<usize, VMError> {
if self.len() >= self.max_stack_size {
self.op_codes.push(OpCode::Halt);
return Err(VMError::StackOverflow);
}

self.stack.push(obj.to_owned());
self.op_codes.push(OpCode::Push(obj.value.unwrap()));
self.first_object = Some(self.stack[0].to_owned());
self.update_first_object();
self.update_num_object();

Ok(self.len())
}

fn pop(&mut self) -> Result<Object, VMError> {
pub fn pop(&mut self) -> Result<usize, VMError> {
if self.is_empty() {
self.op_codes.push(OpCode::Halt);
return Err(VMError::StackUnderflow);
}

let obj = self.stack.pop().unwrap();
let _obj = self.stack.pop().unwrap();
self.op_codes.push(OpCode::Pop);
self.num_objects -= 1;
self.update_first_object();
self.update_num_object();

Ok(obj)
Ok(self.len())
}

fn len(&self) -> usize {
pub fn len(&self) -> usize {
if self.is_empty() {
return 0;
}

self.stack.len()
}

fn is_empty(&self) -> bool {
pub fn is_empty(&self) -> bool {
self.stack.is_empty()
}

fn to_string(&self) -> String {
format!(
"VM: {{\nstack: {:?},\nop_codes: {:?},\nmax_stack_size: {},\nthreshold: {},\nnum_objects: {},\nfirst_object: {:?},\ngc_confidence: {},\ntrigger_gc: {},\ngc_status: {}\n}}",
self.stack,
self.op_codes,
self.max_stack_size,
self.threshold,
self.num_objects,
self.first_object,
self.gc_confidence,
self.trigger_gc,
self.gc_status
)
fn update_num_object(&mut self) -> usize {
self.num_objects = self.heap.len();
self.num_objects
}

// 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);
// }
// }
// }
fn update_first_object(&mut self) -> bool {
self.first_object = self.stack.first().map(|obj| obj.to_owned());

self.first_object.is_some()
}
}

impl fmt::Display for VMError {
Expand All @@ -174,6 +121,24 @@ impl fmt::Display for VMError {
}
}

impl fmt::Display for VirtualMachine {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"VM: {{\nstack: {:?},\nop_codes: {:?},\nmax_stack_size: {},\nthreshold: {},\nnum_objects: {},\nfirst_object: {:?},\ngc_confidence: {},\ntrigger_gc: {},\ngc_status: {}\n}}",
self.stack,
self.op_codes,
self.max_stack_size,
self.threshold,
self.num_objects,
self.first_object,
self.gc_confidence,
self.trigger_gc,
self.gc_status
)
}
}

impl fmt::Display for GCStatus {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expand Down
14 changes: 6 additions & 8 deletions tests/heap_test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#[cfg(test)]
mod heap_tests {
use gc_simulator::{heap::Heap, object::{Object, ObjectTrait}};
use gc_simulator::{
heap::Heap,
object::{Address, Field, Object, ObjectTrait},
};

#[test]
fn test_create_new_heap() {
Expand All @@ -10,12 +13,6 @@ mod heap_tests {
assert_eq!(heap.objects.is_empty(), true);
}

#[test]
#[ignore]
fn test_lookup() {
assert!(true);
}

#[test]
fn test_next_object_address() {
let mut heap = Heap::new(100, 0);
Expand Down Expand Up @@ -64,6 +61,7 @@ mod heap_tests {
h.objects.insert(o2.get_address(), o2.to_owned());
h.objects.insert(o3.get_address(), o3.to_owned());

// println!("heap: {:?}", h);
assert_eq!(h.next_object(o1.get_address()), Some(&o2));
assert_eq!(h.next_object(o2.get_address()), Some(&o3));
assert_eq!(h.next_object(o3.get_address()), None);
Expand Down Expand Up @@ -112,4 +110,4 @@ mod heap_tests {
assert_eq!(h.aligned_position(i), i);
}
}
}
}
38 changes: 26 additions & 12 deletions tests/vm_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
mod vm_tests {
use gc_simulator::{
object::{Object, ObjectTrait, TypeValue},
vm::{OpCode, VMError, VMTrait, VirtualMachine},
vm::{OpCode, VMError, VirtualMachine},
};

static THRESHOLD: f64 = 0.75;
Expand Down Expand Up @@ -82,17 +82,31 @@ mod vm_tests {
assert_eq!(vm.pop().unwrap_err(), VMError::StackUnderflow);
}

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

// let value = Object::new(String::from("test"), TypeValue::Int(1));
// vm.push(value).unwrap();
// vm.pop().unwrap();
let value = Object::new(String::from("test"), TypeValue::Int(1));
vm.push(value).unwrap();
vm.pop().unwrap();

// assert_eq!(vm.op_codes.len(), 2);
// assert_eq!(vm.op_codes[0], OpCode::Push(TypeValue::Int(1)));
// assert_eq!(vm.op_codes[1], OpCode::Pop);
// }
assert_eq!(vm.op_codes.len(), 2);
assert_eq!(vm.op_codes[0], OpCode::Push(TypeValue::Int(1)));
assert_eq!(vm.op_codes[1], OpCode::Pop);
}

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

let value = Object::new(String::from("test"), TypeValue::Int(1));
vm.push(value.clone()).unwrap();

assert_eq!(vm.first_object, Some(value));

vm.pop().unwrap();
assert_eq!(vm.first_object, None);
}
}

0 comments on commit 520923a

Please sign in to comment.