summaryrefslogtreecommitdiffstats
path: root/bytecode/heap.c
diff options
context:
space:
mode:
Diffstat (limited to 'bytecode/heap.c')
-rw-r--r--bytecode/heap.c125
1 files changed, 0 insertions, 125 deletions
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 <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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;
-}