From 943a6597b2bcd1b3ed208458a5cba61ad5b4051c Mon Sep 17 00:00:00 2001 From: Nathan Ringo Date: Mon, 18 Nov 2024 00:34:23 -0600 Subject: ... --- src/gc/gc.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 23 deletions(-) (limited to 'src/gc/gc.c') diff --git a/src/gc/gc.c b/src/gc/gc.c index f53fd79..1c0daec 100644 --- a/src/gc/gc.c +++ b/src/gc/gc.c @@ -1,17 +1,11 @@ +#include "../gc.h" +#include "../platform.h" #include "../util.h" #include #include -#include +#include #include -/** - * These cache-size details are from - * https://www.copetti.org/writings/consoles/nintendo-3ds/. We call the second - * level of cache (only available on N3DS) L3, since this GC design only cares - * about L1D and L3. - */ -static const size_t L1D_SIZE = 16 * 1024, L3_SIZE = 2 * 1024 * 1024; - /** * Constants that should probably be learned. */ @@ -42,6 +36,12 @@ enum object_kind { */ OBJECT_UNTRACED, + /** + * A wrapper for a pointer to a code address. When this object gets collected, + * calls `free_code` on its first untraced slot. + */ + OBJECT_COMPILED_FUNCTION, + /** * A hashtable keyed by the addresses. This behaves like a normal object, but * the first untraced slot gets set to the `uintptr_t` 1 whenever a collection @@ -49,13 +49,7 @@ enum object_kind { * * The hashtable uses this information to rehash after each collection. */ - OBJECT_EQ_HASHTABLE, - - /** - * A wrapper for a pointer to a code address. When this object gets collected, - * calls `free_code` on its first untraced slot. - */ - OBJECT_COMPILED_FUNCTION, + OBJECT_HASHTABLE_EQ, }; /** @@ -72,11 +66,11 @@ struct object_size { /** * Returns the number of slots for values the object has. */ -static size_t object_value_slots(struct object_size size) { +static size_t object_size_value_slots(struct object_size size) { switch (size.kind) { case OBJECT_NORMAL: - case OBJECT_EQ_HASHTABLE: case OBJECT_COMPILED_FUNCTION: + case OBJECT_HASHTABLE_EQ: return size.bits >> ((4 * sizeof(size_t)) - 3); case OBJECT_UNTRACED: return 0; @@ -86,11 +80,11 @@ static size_t object_value_slots(struct object_size size) { /** * Returns the number of untraced slots the object has. */ -static size_t object_untraced_slots(struct object_size size) { +static size_t object_size_untraced_slots(struct object_size size) { switch (size.kind) { case OBJECT_NORMAL: - case OBJECT_EQ_HASHTABLE: case OBJECT_COMPILED_FUNCTION: + case OBJECT_HASHTABLE_EQ: return size.bits & ((1 << ((4 * sizeof(size_t)) - 3)) - 1); case OBJECT_UNTRACED: return size.bits; @@ -105,6 +99,20 @@ struct object { uintptr_t tl[]; }; +/** + * Returns the number of slots for values the object has. + */ +static size_t object_value_slots(const struct object *obj) { + return object_size_value_slots(((struct object_size *)obj)[-1]); +} + +/** + * Returns the number of untraced slots the object has. + */ +static size_t object_untraced_slots(const struct object *obj) { + return object_size_untraced_slots(((struct object_size *)obj)[-1]); +} + /** * This is the layout of an object in the nursery. */ @@ -120,8 +128,8 @@ struct nursery_object { * with one. */ struct young_heap_object { - struct object_size size; size_t fwd; + struct object_size size; uintptr_t slots[]; }; @@ -199,10 +207,10 @@ static struct old_heap_block old_heap_sentinels[SIZE_CLASS_COUNT]; void gc_init(void) { // Allocate the nursery and young-heap. nursery_bottom = nursery_next = - (uintptr_t)malloc(L1D_SIZE * NURSERY_L1D_SIZE_FACTOR); + (uintptr_t)malloc(get_l1d_size() * NURSERY_L1D_SIZE_FACTOR); assume(nursery_bottom); young_heap_bottom = young_heap_next = - (uintptr_t)malloc(L3_SIZE * YOUNG_HEAP_L3_SIZE_FACTOR); + (uintptr_t)malloc(get_l3_size() * YOUNG_HEAP_L3_SIZE_FACTOR); assume(young_heap_bottom); // Self-link the old-heap. @@ -211,3 +219,48 @@ void gc_init(void) { &old_heap_sentinels[i]; } } + +struct object *gc_alloc(size_t value_slot_count, size_t untraced_slot_count) { + todo("gc_alloc"); +} + +struct object *gc_alloc_compiled_function(size_t value_slot_count, + size_t untraced_slot_count) { + todo("gc_alloc_compiled_function"); +} + +struct object *gc_alloc_hashtable_eq(size_t value_slot_count, + size_t untraced_slot_count) { + todo("gc_alloc_hashtable_eq"); +} + +struct value gc_read_value_slot(const struct object *obj, size_t slot_index) { + assume(slot_index < object_value_slots(obj)); + todo("gc_read_value_slot"); +} + +uintptr_t gc_read_untraced_slot(const struct object *obj, size_t slot_index) { + assume(slot_index < object_untraced_slots(obj)); + todo("gc_read_untraced_slot"); +} + +uint8_t gc_read_untraced_byte(const struct object *obj, size_t byte_index) { + todo("gc_read_untraced_byte"); +} + +void gc_write_value_slot(struct object *obj, size_t slot_index, + struct value value) { + assume(slot_index < object_value_slots(obj)); + todo("gc_write_value_slot"); +} + +void gc_write_untraced_slot(struct object *obj, size_t slot_index, + uintptr_t value) { + assume(slot_index < object_untraced_slots(obj)); + todo("gc_write_untraced_slot"); +} + +void gc_write_untraced_byte(struct object *obj, size_t byte_index, + uint8_t byte) { + todo("gc_write_untraced_byte"); +} -- cgit v1.2.3