From: Brendan Hansen Date: Sun, 17 May 2020 17:58:51 +0000 (-0500) Subject: Implemented Allow Arena allocator to create more arenas #10 X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=132c0de79c2c247eb94d1b297a8face26be166a9;p=onyx.git Implemented Allow Arena allocator to create more arenas #10 --- diff --git a/bh.h b/bh.h index f4d89cfb..c9715ebf 100644 --- 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 d44a3a89..e08127de 100644 --- 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; } diff --git a/onyxlex.c b/onyxlex.c index 8447be00..0eef2e79 100644 --- 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); diff --git a/onyxlex.h b/onyxlex.h index 42dd767f..399ca1cb 100644 --- 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