From 17face3633686e374aa0859271ccf462a48e60aa Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Sun, 4 Feb 2024 16:46:20 -0800 Subject: Rewrite the bytecode interpreter in Rust. --- bytecode/heap.c | 125 -------------------------------------------------------- 1 file changed, 125 deletions(-) delete mode 100644 bytecode/heap.c (limited to 'bytecode/heap.c') diff --git a/bytecode/heap.c b/bytecode/heap.c deleted file mode 100644 index 1ba5faf..0000000 --- a/bytecode/heap.c +++ /dev/null @@ -1,125 +0,0 @@ -#include -#include -#include - -#include "encoding.h" -#include "heap.h" -#include "panic.h" -#include "value.h" -#include "value_slice.h" - -struct heap new_heap(value_slice gc_roots) -{ - return (struct heap) { - .buf = NULL, - .active = { .size = 0 }, - .standby = { .size = 0 }, - .free_ptr = 0, - .last_free = 0, - .gc_roots = gc_roots, - }; -} - -static bool forwarded(struct heap *h, value *p) -{ - if (!is_pointer(*p)) { - return false; - } - value *q = to_pointer(*p); - return h->active.buf <= q && q <= h->active.buf + h->active.size; -} - -static size_t alloc_size(value *p) -{ - return p[-1] >> 1; -} - -static value *simple_alloc(struct heap *h, int64_t size) -{ - h->active.buf[h->free_ptr] = size << 1; - value *p = h->active.buf + h->free_ptr + 1; - h->free_ptr += size; - return p; -} - -static value process_gc_value(struct heap *h, value val) -{ - if (!is_pointer(val)) { - return val; - } - value *p = to_pointer(val); - if (forwarded(h, p)) { - return *p; - } - - size_t size = alloc_size(p); - - // 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. - q[0] = process_gc_value(h, first_value); - for (size_t i = 1; i < size; i++) { - q[i] = process_gc_value(h, p[i]); - } - - return from_pointer(q); -} - -static void collect_garbage(struct heap *h) -{ - if (h->free_ptr < 2 * h->last_free) { - return; - } - - // Swap the heaps. - value_slice temp = h->active; - h->active = h->standby; - h->standby = temp; - - h->free_ptr = 0; - - for (size_t i = 0; i < h->gc_roots.size; i++ ) { - h->gc_roots.buf[i] = process_gc_value(h, h->gc_roots.buf[i]); - } -} - -static value_slice xcalloc(size_t size) -{ - value *p = calloc(size, sizeof(value)); - if (!p) { - panicf("Out of memory!\n"); - } - 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)); - - 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) -{ - if (size <= 0) { - panicf("Alloc of zero size!\n"); - } - collect_garbage(h); - - if (h->free_ptr + size >= h->active.size) { - more_space(h, size); - } - value *p = simple_alloc(h, size); - memset(p, 0, size * sizeof(value)); - return p; -} -- cgit v1.3.1