Implemented Allow Arena allocator to create more arenas #10
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 17 May 2020 17:58:51 +0000 (12:58 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 17 May 2020 17:58:51 +0000 (12:58 -0500)
bh.h
onyx.c
onyxlex.c
onyxlex.h

diff --git a/bh.h b/bh.h
index f4d89cfbc9fc6ac20d2671d4aa62854947742fb1..c9715ebf0829cffdfd17b635c120bfd3b4c6e638 100644 (file)
--- a/bh.h
+++ b/bh.h
@@ -176,12 +176,16 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc);
 // ARENA ALLOCATOR
 typedef struct bh_arena {
        bh_allocator backing;
-       ptr memory;
-       ptr next_allocation;
-       isize size, total_size; // in bytes
+       ptr first_arena, current_arena;
+       isize size, arena_size; // in bytes
 } bh_arena;
 
-void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize total_size);
+typedef struct bh__arena_internal {
+       ptr next_arena;
+       void* data; // Not actually a pointer, just used for the offset
+} bh__arena_internal;
+
+void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size);
 void bh_arena_free(bh_arena* alloc);
 bh_allocator bh_arena_allocator(bh_arena* alloc);
 BH_ALLOCATOR_PROC(bh_arena_allocator_proc);
@@ -375,16 +379,16 @@ typedef struct bh__arr {
 #define bh_arr_free(arr)                                       (bh__arr_free((void**) &(arr)))
 #define bh_arr_copy(allocator_, arr)           (bh__arr_copy((allocator_), (arr), sizeof(*(arr))))
 
-#define bh_arr_grow(arr, cap)          (bh__arr_grow((void **) &(arr), sizeof(*(arr)), cap))
+#define bh_arr_grow(arr, cap)          (bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), cap))
 #define bh_arr_shrink(arr, cap)                (bh__arr_shrink((void **) &(arr), sizeof(*(arr)), cap))
 #define bh_arr_set_length(arr, n)      ( \
-       bh__arr_grow((void **) &(arr), sizeof(*(arr)), n), \
+       bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), n), \
        bh__arrhead(arr)->length = n)
 
 #define bh_arr_insertn(arr, i, n)      (bh__arr_insertn((void **) &(arr), sizeof(*(arr)), i, n))
 
 #define bh_arr_insert_end(arr, n)      ( \
-       bh__arr_grow((void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \
+       bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \
        bh__arrhead(arr)->length += n)
 
 #define bh_arr_push(arr, value)        ( \
@@ -650,21 +654,30 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc) {
 
 
 // ARENA ALLOCATOR IMPLEMENTATION
-void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize total_size) {
-       ptr data = bh_alloc(backing, total_size);
+void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size) {
+       ptr data = bh_alloc(backing, arena_size);
 
        alloc->backing = backing;
-       alloc->total_size = total_size;
+       alloc->arena_size = arena_size;
        alloc->size = 0;
-       alloc->memory = data;
-       alloc->next_allocation = data;
+       alloc->first_arena = data;
+       alloc->current_arena = data;
+
+       ((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL;
 }
 
 void bh_arena_free(bh_arena* alloc) {
-       bh_free(alloc->backing, alloc->memory);
-       alloc->memory = NULL;
-       alloc->next_allocation = NULL;
-       alloc->total_size = 0;
+       bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena;
+       bh__arena_internal *trailer = walker;
+       while (walker != NULL) {
+               walker = walker->next_arena;
+               bh_free(alloc->backing, trailer);
+               trailer = walker;
+       }
+
+       alloc->first_arena = NULL;
+       alloc->current_arena = NULL;
+       alloc->arena_size = 0;
        alloc->size = 0;
 }
 
@@ -676,24 +689,35 @@ bh_allocator bh_arena_allocator(bh_arena* alloc) {
 }
 
 BH_ALLOCATOR_PROC(bh_arena_allocator_proc) {
-       bh_arena* alloc_nf = (bh_arena*) data;
+       bh_arena* alloc_arena = (bh_arena*) data;
 
        ptr retval = NULL;
 
        switch (action) {
        case bh_allocator_action_alloc: {
-               retval = alloc_nf->next_allocation;
 
-               size = bh__align(size, alignment);
-               alloc_nf->next_allocation = bh_pointer_add(alloc_nf->next_allocation, size);
-               
-               if (alloc_nf->size + size >= alloc_nf->total_size) {
-                       // Out of memory
-                       fprintf(stderr, "NoFree allocator out of memory\n");
+               // TODO: Do this better because right now bh__align is bad
+               // size = bh__align(size, alignment);
+               if (size > alloc_arena->arena_size) {
+                       // Size too large for the arena
                        return NULL;
                }
+               
+               if (alloc_arena->size + size >= alloc_arena->arena_size) {
+                       alloc_arena->size = sizeof(ptr);
+                       bh__arena_internal* new_arena = (bh__arena_internal *) bh_alloc(alloc_arena->backing, alloc_arena->arena_size);
+
+                       if (new_arena == NULL) {
+                               fprintf(stderr, "Arena Allocator: couldn't allocate new arena");
+                               return NULL;
+                       }
+
+                       ((bh__arena_internal *)alloc_arena->current_arena)->next_arena = new_arena;
+                       alloc_arena->current_arena = new_arena;
+               }
 
-               alloc_nf->size += size;
+               retval = alloc_arena->current_arena + alloc_arena->size;
+               alloc_arena->size += size;
        } break;
 
        case bh_allocator_action_resize: {
diff --git a/onyx.c b/onyx.c
index d44a3a897726d9b2cbc1c6e088e1dea902d9d4a7..e08127dec0e98f225b7ab2fb1952832812e60932 100644 (file)
--- a/onyx.c
+++ b/onyx.c
@@ -20,9 +20,7 @@ int main(int argc, char *argv[]) {
        bh_file_contents fc = bh_file_read_contents(alloc, &source_file);
        bh_file_close(&source_file);
 
-       bh_hash(u16) symbol_count;
-       bh_hash_init(alloc, symbol_count);
-       bh_arr(OnyxToken) token_arr = onyx_parse_tokens(alloc, &fc, symbol_count);
+       bh_arr(OnyxToken) token_arr = onyx_parse_tokens(alloc, &fc);
 
        printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr));
 
@@ -30,17 +28,8 @@ int main(int argc, char *argv[]) {
                printf("%s '%c' (Line %ld, Col %ld)\n", onyx_get_token_type_name(*it), *(char *)it->token, it->line_number, it->line_column);
        }
 
-       bh_hash_iterator it = bh_hash_iter_setup(u16, symbol_count);
-       while (bh_hash_iter_next(&it)) {
-               const char* sym = bh_hash_iter_key(it);
-               u16 count = bh_hash_iter_value(u16, it);
-
-               printf("%s was seen %d times.\n", sym, count);
-       }
-
        bh_file_contents_delete(&fc);
        bh_arr_free(token_arr);
-       bh_hash_free(symbol_count);
 
        return 0;
 }
index 8447be000e734ebe8b6e5081b2aca1ea5ceb4449..0eef2e79bd7035bd50fdf8d43504e309efaee393 100644 (file)
--- a/onyxlex.c
+++ b/onyxlex.c
@@ -236,14 +236,13 @@ token_parsed:
        return tk;
 }
 
-bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc, bh_hash(u16) symcount) {
+bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc) {
        OnyxTokenizer tknizer = {
                .start                  = fc->data,
                .curr                   = fc->data,
                .end                    = fc->data + fc->length,
                .line_number    = 1,
                .line_start     = fc->data,
-               .symbol_count   = symcount,
        };
 
        bh_arr(OnyxToken) token_arr = NULL;
@@ -252,22 +251,6 @@ bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc,
        OnyxToken tk;
        do {
                tk = onyx_get_token(&tknizer);
-
-               if (tk.type == TOKEN_TYPE_SYMBOL) {
-                       u16 val = 0;
-
-                       char tmp = tk.token[tk.length];
-                       tk.token[tk.length] = '\0';
-
-                       if (bh_hash_has(u16, tknizer.symbol_count, tk.token)) {
-                               val = bh_hash_get(u16, tknizer.symbol_count, tk.token);
-                       }
-
-                       bh_hash_put(u16, tknizer.symbol_count, tk.token, val + 1);
-
-                       tk.token[tk.length] = tmp;
-               }
-
                bh_arr_push(token_arr, tk);
        } while (tk.type != TOKEN_TYPE_END_STREAM);
 
index 42dd767fdafdac18e160757666036e9bf755802b..399ca1cbcf8b03de758e6c1ceca1749c3d9c5729 100644 (file)
--- a/onyxlex.h
+++ b/onyxlex.h
@@ -6,11 +6,8 @@
 typedef struct OnyxTokenizer {
        char *start, *curr, *end;
 
-       // TODO: Fix the line number and column count
        char* line_start;
        u64 line_number;
-
-       bh_hash(u16) symbol_count;
 } OnyxTokenizer;
 
 typedef enum OnyxTokenType {
@@ -75,6 +72,6 @@ typedef struct OnyxToken {
 
 const char* onyx_get_token_type_name(OnyxToken tkn);
 OnyxToken onyx_get_token(OnyxTokenizer* tokenizer);
-bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc, bh_hash(u16) symcount);
+bh_arr(OnyxToken) onyx_parse_tokens(bh_allocator tk_alloc, bh_file_contents *fc);
 
 #endif
\ No newline at end of file