From 5989629a7951e544ad4656672025a99ecd08c7c9 Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sat, 11 Feb 2023 21:31:04 -0800 Subject: Change how slices work. I'm switching to a more macro-heavy solution. Hopefully it proves robust. --- bytecode/heap.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'bytecode/heap.c') diff --git a/bytecode/heap.c b/bytecode/heap.c index 863bf0c..1ba5faf 100644 --- a/bytecode/heap.c +++ b/bytecode/heap.c @@ -6,8 +6,9 @@ #include "heap.h" #include "panic.h" #include "value.h" +#include "value_slice.h" -struct heap new_heap(struct val_slice gc_roots) +struct heap new_heap(value_slice gc_roots) { return (struct heap) { .buf = NULL, @@ -56,14 +57,16 @@ static value process_gc_value(struct heap *h, value val) // Allocate space in the new buffer. value *q = simple_alloc(h, size); + // Write forwarding pointer. + value first_value = p[0]; + p[0] = from_pointer(q); + // Copy values, recursively modifying pointers. - for (size_t i = 0; i < size; i++) { + q[0] = process_gc_value(h, first_value); + for (size_t i = 1; i < size; i++) { q[i] = process_gc_value(h, p[i]); } - // Write forwarding pointer. - p[0] = from_pointer(q); - return from_pointer(q); } @@ -74,7 +77,7 @@ static void collect_garbage(struct heap *h) } // Swap the heaps. - struct val_slice temp = h->active; + value_slice temp = h->active; h->active = h->standby; h->standby = temp; @@ -85,19 +88,25 @@ static void collect_garbage(struct heap *h) } } -static void more_space(struct heap *h, int64_t size_hint) +static value_slice xcalloc(size_t size) { - size_t new_size = h->active.size * 2 + size_hint; - value *new_buf = calloc(2 * new_size, sizeof(value)); - if (!new_buf) { + value *p = calloc(size, sizeof(value)); + if (!p) { panicf("Out of memory!\n"); } - memcpy(new_buf, h->active.buf, h->active.size * sizeof(value)); - free(h->buf); + return (value_slice) { .size = size, .buf = p }; +} + +static void more_space(struct heap *h, int64_t size_hint) +{ + size_t new_size = h->active.size * 2 + size_hint; + value_slice new_buf = xcalloc(2 * new_size); + memcpy(new_buf.buf, h->active.buf, h->active.size * sizeof(value)); - h->buf = new_buf; - h->active = (struct val_slice) { .size = new_size, .buf = new_buf }; - h->standby = (struct val_slice) { .size = new_size, .buf = new_buf + new_size }; + free(h->buf); + h->buf = new_buf.buf; + h->active = value_slice2(new_buf, 0, new_size); + h->standby = value_slice1(new_buf, new_size); } value *alloc(struct heap *h, int64_t size) @@ -110,5 +119,7 @@ value *alloc(struct heap *h, int64_t size) if (h->free_ptr + size >= h->active.size) { more_space(h, size); } - return simple_alloc(h, size); + value *p = simple_alloc(h, size); + memset(p, 0, size * sizeof(value)); + return p; } -- cgit v1.3.1