Skip to content

Commit efd2b3f

Browse files
committed
Add $vm_shrink_heap() host function to stress test the GC.
1 parent 566baa6 commit efd2b3f

File tree

8 files changed

+49
-6
lines changed

8 files changed

+49
-6
lines changed

src/alloc.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,28 @@ impl Alloc
4040
self.mem_size
4141
}
4242

43+
pub fn bytes_used(&self) -> usize
44+
{
45+
self.next_idx
46+
}
47+
4348
pub fn bytes_free(&self) -> usize
4449
{
4550
assert!(self.next_idx <= self.mem_size);
4651
self.mem_size - self.next_idx
4752
}
4853

49-
// Allocate a block of a given size
54+
/// Shrink the available memory to a smaller size
55+
/// This is primarily used to test the GC
56+
pub fn shrink_to(&mut self, new_size: usize)
57+
{
58+
assert!(self.next_idx <= new_size);
59+
self.mem_size = new_size;
60+
61+
// TODO: try to realloc to a smaller size?
62+
}
63+
64+
/// Allocate a block of a given size
5065
fn alloc_bytes(&mut self, size_bytes: usize) -> Result<*mut u8, ()>
5166
{
5267
let align_bytes = 8;
@@ -64,7 +79,7 @@ impl Alloc
6479
Ok(unsafe { self.mem_block.add(obj_pos) })
6580
}
6681

67-
// Allocate a variable-sized table of elements of a given type
82+
/// Allocate a variable-sized table of elements of a given type
6883
pub fn alloc_table<T>(&mut self, num_elems: usize) -> Result<*mut [T], ()>
6984
{
7085
let num_bytes = num_elems * std::mem::size_of::<T>();
@@ -74,7 +89,7 @@ impl Alloc
7489
Ok(std::ptr::slice_from_raw_parts_mut(p, num_elems))
7590
}
7691

77-
// Allocate a new object of a given type
92+
/// Allocate a new object of a given type
7893
pub fn alloc<T>(&mut self, obj: T) -> Result<*mut T, ()>
7994
{
8095
let num_bytes = std::mem::size_of::<T>();
@@ -88,7 +103,7 @@ impl Alloc
88103
Ok(p)
89104
}
90105

91-
// Allocate a new object with a given number of slots
106+
/// Allocate a new object with a given number of slots
92107
pub fn new_object(&mut self, class_id: ClassId, num_slots: usize) -> Result<Value, ()>
93108
{
94109
// Allocate the slots for the object

src/host.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub fn get_host_const(name: &str, fun: &Function, prog: &Program) -> Expr
7878
static READ_FILE: HostFn = HostFn { name: "read_file", f: Fn1(read_file) };
7979
static READ_FILE_UTF8: HostFn = HostFn { name: "read_file", f: Fn1(read_file_utf8) };
8080
static WRITE_FILE: HostFn = HostFn { name: "write_file", f: Fn2(write_file) };
81+
static VM_SHRINK_HEAP: HostFn = HostFn { name: "vm_shrink_heap", f: Fn1(vm_shrink_heap) };
8182
static ACTOR_ID: HostFn = HostFn { name: "actor_id", f: Fn0(actor_id) };
8283
static ACTOR_PARENT: HostFn = HostFn { name: "actor_parent", f: Fn0(actor_parent) };
8384
static ACTOR_SLEEP: HostFn = HostFn { name: "actor_sleep", f: Fn1(actor_sleep) };
@@ -109,6 +110,7 @@ pub fn get_host_const(name: &str, fun: &Function, prog: &Program) -> Expr
109110
"read_file_utf8" => &READ_FILE_UTF8,
110111
"write_file" => &WRITE_FILE,
111112

113+
"vm_shrink_heap" => &VM_SHRINK_HEAP,
112114
"actor_id" => &ACTOR_ID,
113115
"actor_parent" => &ACTOR_PARENT,
114116
"actor_sleep" => &ACTOR_SLEEP,
@@ -419,6 +421,20 @@ fn write_file(actor: &mut Actor, file_path: Value, mut bytes: Value) -> Result<V
419421
}
420422
}
421423

424+
/// Shrink the heap to a smaller size
425+
fn vm_shrink_heap(actor: &mut Actor, new_size: Value) -> Result<Value, String>
426+
{
427+
let new_size = unwrap_usize!(new_size);
428+
429+
if actor.alloc.bytes_used() > new_size {
430+
return Err("requested heap size is smaller than bytes currently allocated".into());
431+
}
432+
433+
actor.alloc.shrink_to(new_size);
434+
435+
Ok(Value::Nil)
436+
}
437+
422438
/// Get the id of the current actor
423439
fn actor_id(actor: &mut Actor) -> Result<Value, String>
424440
{

tests/gc_alloc_arrays.psh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
for (let var i = 0; i < 1_000_000; ++i)
1+
$vm_shrink_heap(256_000);
2+
3+
for (let var i = 0; i < 200_000; ++i)
24
{
35
let a = [0, 1, 2, 3, 4];
46
assert(a.len == 5);

tests/gc_alloc_random.psh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class Foo
2121
}
2222
}
2323

24-
for (let var i = 0; i < 6_000_000; ++i)
24+
$vm_shrink_heap(256_000);
25+
26+
for (let var i = 0; i < 4_000_000; ++i)
2527
{
2628
let r = rand_int(1, 5);
2729

tests/gc_grow_array.psh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
$vm_shrink_heap(256_000);
2+
13
let a = [];
24

35
for (let var i = 0; i < 3_000_000; ++i)

tests/gc_linked_list.psh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ class Node
77
}
88
}
99

10+
$vm_shrink_heap(256_000);
11+
1012
let var list = nil;
1113

1214
for (let var n = 0; n < 1_000; ++n)

tests/gc_list_extend.psh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ class Node
77
}
88
}
99

10+
$vm_shrink_heap(256_000);
11+
1012
let var list = nil;
1113
let num_nodes = 1_000_000;
1214

tests/gc_str_concat.psh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
$vm_shrink_heap(256_000);
2+
13
let var str = nil;
24

35
for (let var n = 0; n < 500; ++n)

0 commit comments

Comments
 (0)