From a58e8670d173ba67551fd4efd24d9bbb2100483f Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sat, 19 May 2018 15:01:11 -0400 Subject: [PATCH] removed gc stuff. opting for a lack of memory management in general --- example.src | 3 + source/gc.c | 310 ------------------------------------------------- source/main.c | 2 +- source/sclpl.h | 42 +++++-- 4 files changed, 34 insertions(+), 323 deletions(-) create mode 100644 example.src delete mode 100644 source/gc.c diff --git a/example.src b/example.src new file mode 100644 index 0000000..690c1b1 --- /dev/null +++ b/example.src @@ -0,0 +1,3 @@ +def main(args string[]) int + 0 +end diff --git a/source/gc.c b/source/gc.c deleted file mode 100644 index a0d79ef..0000000 --- a/source/gc.c +++ /dev/null @@ -1,310 +0,0 @@ -#include - -typedef struct obj_t { - uintptr_t refs; - destructor_t destructor; -} obj_t; - -typedef struct hash_entry_t { - obj_t* object; - unsigned int hash; - struct hash_entry_t* next; -} hash_entry_t; - -typedef struct { - size_t size; - size_t bkt_count; - hash_entry_t** buckets; -} hash_t; - -static void hash_set(hash_t* hash, hash_entry_t* entry); - -/*****************************************************************************/ - -#define NUM_PRIMES (sizeof(Primes)/sizeof(unsigned int)) - -static unsigned int Primes[] = { - 5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, - 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469, - 12582917, 25165843, 50331653, 100663319, 201326611, 402653189, - 805306457, 1610612741 -}; - -static unsigned int num_buckets(unsigned int idx) { - assert(idx < NUM_PRIMES); - return Primes[idx]; -} - -static void hash_init(hash_t* hash) -{ - hash->size = 0; - hash->bkt_count = 0; - hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash->bkt_count)); -} - -static void find_entry(hash_entry_t** parent, hash_entry_t** current, hash_entry_t* entry) -{ - while(*current != NULL) { - if (((*current)->hash == entry->hash) && - ((*current)->object == entry->object)) - break; - *parent = *current; - *current = (*current)->next; - } -} - -static void rehash(hash_t* hash) -{ - unsigned int oldcount, i; - hash_entry_t** oldbuckets; - hash_entry_t *node, *entry; - if ((hash->bkt_count+1) < NUM_PRIMES) { - oldcount = hash->bkt_count++; - oldbuckets = hash->buckets; - hash->buckets = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash->bkt_count)); - hash->size = 0; - /* Iterate over all of the old buckets */ - for (i = 0; i < num_buckets(oldcount); i++) { - node = oldbuckets[i]; - /* re-insert all entries in the bucket into the new bucket table */ - while (node != NULL) { - entry = node; - node = entry->next; - hash_set(hash, entry); - } - } - /* Free the old bucket table */ - free(oldbuckets); - } -} - -static uint64_t hash64(uint64_t key) -{ - key = (~key) + (key << 21); - key = key ^ (key >> 24); - key = (key + (key << 3)) + (key << 8); - key = key ^ (key >> 14); - key = (key + (key << 2)) + (key << 4); - key = key ^ (key >> 28); - key = key + (key << 31); - return key; -} - -static size_t hash_size(hash_t* hash) -{ - return hash->size; -} - -static void hash_set(hash_t* hash, hash_entry_t* entry) -{ - unsigned int index; - hash_entry_t *parent, *node, *deadite; - if (hash->size >= num_buckets(hash->bkt_count)) - rehash(hash); - entry->hash = hash64((uint64_t)(entry->object)); - index = (entry->hash % num_buckets(hash->bkt_count)); - parent = NULL; - node = hash->buckets[index]; - deadite = NULL; - find_entry(&parent, &node, entry); - if ((parent == NULL) && (node == NULL)) { - hash->buckets[index] = entry; - entry->next = NULL; - hash->size++; - } else if (node == NULL) { - parent->next = entry; - entry->next = NULL; - hash->size++; - } else if (parent == NULL) { - deadite = node; - entry->next = deadite->next; - hash->buckets[index] = entry; - } else { - deadite = node; - entry->next = deadite->next; - parent->next = entry; - } - if (deadite != NULL) - free(deadite); -} - -static hash_entry_t* hash_del(hash_t* hash, hash_entry_t* entry) -{ - unsigned int index; - hash_entry_t *parent, *node, *ret = NULL; - entry->hash = hash64((uint64_t)(entry->object)); - index = (entry->hash % num_buckets(hash->bkt_count)); - parent = NULL; - node = hash->buckets[index]; - find_entry(&parent, &node, entry); - if (node != NULL) { - ret = node; - node = node->next; - if (parent != NULL) - parent->next = node; - else - hash->buckets[index] = node; - hash->size--; - } - return ret; -} - -/*****************************************************************************/ - -static bool Shutdown; -static void** Stack_Bottom; -static hash_t Zero_Count_Table; -static hash_t Multi_Ref_Table; -static hash_t Working_Table; - -static void gc_mark_region(void** start, void** end) { - hash_entry_t lookup = {0, 0, 0}; - hash_entry_t* entry; - for (; start <= end; start++) { - lookup.object = *start; - entry = hash_del(&Working_Table, &lookup); - if (entry != NULL) { - hash_set(&Zero_Count_Table, entry); - } - } -} - -static void gc_mark_stack(void) { - void* stack_top = NULL; - /* Determine which way the stack grows and scan it for pointers */ - if (&stack_top < Stack_Bottom) { - gc_mark_region(&stack_top, Stack_Bottom); - } else { - gc_mark_region(Stack_Bottom, &stack_top); - } -} - -static void gc_mark(void) { - jmp_buf env; - volatile int noinline = 1; - /* Flush Registers to Stack */ - if (noinline) { - memset(&env, 0x55, sizeof(jmp_buf)); - (void)setjmp(env); - } - /* Avoid Inlining function call so that we scan the registers along with - * the stack */ - (noinline ? gc_mark_stack : NULL)(); -} - -static void gc_sweep_table(hash_t* table) { - unsigned int i; - /* Delete all the entries in the hash */ - for (i = 0; i < num_buckets(table->bkt_count); i++) { - hash_entry_t* node = table->buckets[i]; - table->buckets[i] = NULL; - while (node != NULL) { - hash_entry_t* deadite = node; - node = node->next; - obj_t* obj = ((obj_t*)(deadite->object)-1); - if (obj->destructor != NULL) - obj->destructor(deadite->object); - free(deadite); - } - } - free(table->buckets); -} - -void gc_init(void** stack_bottom) -{ - Stack_Bottom = stack_bottom; - hash_init(&Zero_Count_Table); - hash_init(&Multi_Ref_Table); - atexit(gc_deinit); - Shutdown = false; -} - -void gc_deinit(void) -{ - Shutdown = true; - gc_sweep_table(&Zero_Count_Table); - gc_sweep_table(&Multi_Ref_Table); -} - -void gc_collect(void) { -#ifdef GC_DEBUG_MSGS - printf("BEFORE - ZCT: %ld MRT: %ld TOT: %ld\n", - hash_size(&Zero_Count_Table), - hash_size(&Multi_Ref_Table), - hash_size(&Zero_Count_Table) + hash_size(&Multi_Ref_Table)); -#endif - Working_Table = Zero_Count_Table; - hash_init(&Zero_Count_Table); - gc_mark(); - gc_sweep_table(&Working_Table); -#ifdef GC_DEBUG_MSGS - printf("AFTER - ZCT: %ld MRT: %ld TOT: %ld\n\n", - hash_size(&Zero_Count_Table), - hash_size(&Multi_Ref_Table), - hash_size(&Zero_Count_Table) + hash_size(&Multi_Ref_Table)); -#endif -} - -void* gc_alloc(size_t size, destructor_t destructor) -{ - hash_entry_t* entry = (hash_entry_t*)malloc(sizeof(hash_entry_t) + sizeof(obj_t) + size); - obj_t* p_obj = (obj_t*)(entry+1); - void* p_data = (void*)(p_obj+1); - entry->object = p_data; - p_obj->refs = 0; - p_obj->destructor = destructor; - hash_set(&Zero_Count_Table, entry); - if (hash_size(&Zero_Count_Table) >= 500) - gc_collect(); - return p_data; -} - -void* gc_addref(void* ptr) -{ - hash_entry_t lookup = {0, 0, 0}; - hash_entry_t* entry; - obj_t* obj = ((obj_t*)ptr-1); - if ((ptr != NULL) && !Shutdown) { - obj->refs++; - if (obj->refs == 1) { - lookup.object = ptr; - entry = hash_del(&Zero_Count_Table, &lookup); - assert(entry != NULL); - hash_set(&Multi_Ref_Table, entry); - } - } - return ptr; -} - -void gc_delref(void* ptr) -{ - hash_entry_t lookup = {0, 0, 0}; - hash_entry_t* entry; - obj_t* obj = ((obj_t*)ptr-1); - if ((ptr != NULL) && !Shutdown) { - obj->refs--; - if (obj->refs == 0) { - lookup.object = ptr; - entry = hash_del(&Multi_Ref_Table, &lookup); - assert(entry != NULL); - hash_set(&Zero_Count_Table, entry); - } - } -} - -void gc_swapref(void** dest, void* newref) -{ - void* oldref = *dest; - *dest = gc_addref(newref); - gc_delref(oldref); -} - -/*****************************************************************************/ - -int main(int argc, char** argv) -{ - void* stack_bottom = NULL; - gc_init(&stack_bottom); - return user_main(argc, argv); -} - diff --git a/source/main.c b/source/main.c index 7717fd1..0a22d40 100644 --- a/source/main.c +++ b/source/main.c @@ -36,7 +36,7 @@ void usage(void) { exit(1); } -int user_main(int argc, char **argv) { +int main(int argc, char **argv) { /* Option parsing */ OPTBEGIN { case 'A': Artifact = EOPTARG(usage()); break; diff --git a/source/sclpl.h b/source/sclpl.h index 346f3f5..a2b20cc 100644 --- a/source/sclpl.h +++ b/source/sclpl.h @@ -9,20 +9,39 @@ #include #include -/* Garbage Collection - *****************************************************************************/ typedef void (*destructor_t)(void*); -void gc_init(void** stack_bottom); -void gc_deinit(void); -void gc_collect(void); -void* gc_alloc(size_t size, destructor_t destructor); -void* gc_addref(void* ptr); -void gc_delref(void* ptr); -void gc_swapref(void** dest, void* newref); +static void fatal(char* estr) { + perror(estr); + exit(1); +} + +static void* gc_alloc(size_t size, destructor_t destructor) +{ + void* ptr = malloc(size); + //fprintf(stderr, "%d\n", size); + if (!ptr) fatal("malloc()"); + return ptr; +} + +static void* gc_addref(void* ptr) +{ + return ptr; +} -// Redefine main -extern int user_main(int argc, char** argv); +static void gc_delref(void* ptr) +{ +} + +static void gc_swapref(void** dest, void* newref) +{ + void* oldref = *dest; + *dest = gc_addref(newref); + gc_delref(oldref); +} + +/* Garbage Collection + *****************************************************************************/ /* Vector Implementation *****************************************************************************/ @@ -193,7 +212,6 @@ typedef struct SymTable { } SymTable; SymTable* symbol_new(void); -//void symbol_free(SymTable* sym); SymTable* symbol_push(SymTable* top, SymTable* newtop); SymTable* symbol_pop(SymTable* top); SymTable* symbol_get(const char* name); -- 2.54.0