From: Brendan Hansen Date: Sun, 20 Dec 2020 00:18:54 +0000 (-0600) Subject: added arena allocator; bug fixes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=40eba3e5cdb17f683056d6056ef742d9e45c7204;p=onyx.git added arena allocator; bug fixes --- diff --git a/core/alloc/arena.onyx b/core/alloc/arena.onyx index 94180199..fba72bea 100644 --- a/core/alloc/arena.onyx +++ b/core/alloc/arena.onyx @@ -1,3 +1,55 @@ package core.alloc.arena -// TODO: Implement the arena allocator \ No newline at end of file +// This allocator is great for when you need to do bunch of +// allocations is a small amount of time. Much like the Ring +// allocator, it simply bumps up a pointer as you allocate +// memory. Unlike the Ring allocator, it does not wrap around, +// meaning you can run of out of memory, so make sure the buffer +// provided has enough space for what you are going to do. + +ArenaState :: struct { + base_ptr : rawptr; + size : u32; + curr_ptr : rawptr; +} + +#private_file +arena_alloc_proc :: proc (data: rawptr, aa: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr { + ss := cast(^ArenaState) data; + + if aa == AllocationAction.Alloc { + retval := null; + rem := ss.size - cast(u32) ss.curr_ptr + cast(u32) ss.base_ptr; + + if size <= rem { + retval = ss.curr_ptr; + ss.curr_ptr = cast(rawptr) (cast(u32) ss.curr_ptr + size); + } else { + // Not enough space for the allocation + retval = null; + } + + return retval; + } + + return null; +} + +make :: proc (buffer: rawptr, length: u32) -> ArenaState { + return ArenaState.{ + base_ptr = buffer, + curr_ptr = buffer, + size = length, + }; +} + +make_allocator :: proc (rs: ^ArenaState) -> Allocator { + return Allocator.{ + func = ring_alloc_proc, + data = rs, + }; +} + +reset :: proc (arena: ^ArenaState) { + arena.curr_ptr = arena.base_ptr; +} \ No newline at end of file diff --git a/docs/todo b/docs/todo index f761d865..492dbe52 100644 --- a/docs/todo +++ b/docs/todo @@ -75,10 +75,14 @@ Language Cohesion: WASM code; i.e. foo().bar; This should at least produce an error until the underlying issue is fixed. - [ ] Every type should have a unique id assigned to it. This would make it + [X] Every type should have a unique id assigned to it. This would make it easier to talk about types in a concrete way (for polymorphism and such), and would prepare the compiler to output type information into data section. + This has been implemented for structs and enums, since those are the two + types that you can control the name and inadvertently give the same name + to two different structs / enums. + [ ] Switches should have range based statements, i.e. switch expr { case 10 .. 14 do ... diff --git a/include/bh.h b/include/bh.h index c179531b..1e39372e 100644 --- a/include/bh.h +++ b/include/bh.h @@ -1625,6 +1625,7 @@ isize bh__printi64(char* str, isize n, bh__print_format format, i64 value) { return bh__print_string(str, n, walker); } +// TODO: This implementation is VERY VERY BAD AND WRONG. Fix it. isize bh__printf64(char* str, isize n, f64 value) { fori (i, 0, 6) value *= 10.0; i64 v = (i64) value; @@ -2274,8 +2275,6 @@ void bh_imap_clear(bh_imap* imap) { - - u64 bh_time_curr() { struct timespec spec; clock_gettime(CLOCK_MONOTONIC, &spec); diff --git a/onyx b/onyx index c4997874..7d215a93 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyx.c b/src/onyx.c index a0c1603f..b4df7f0a 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -531,16 +531,12 @@ static i32 onyx_compile(CompilerState* compiler_state) { u64 duration = bh_time_duration(start_time); if (compiler_state->options->verbose_output) { - bh_printf("\nStatistics:\n"); - bh_printf(" Time taken: %l.%l seconds\n", - duration / 1000, duration % 1000); - bh_printf(" Processed %l lines (%f lines/second).\n", - lexer_lines_processed, - ((f32) 1000 * lexer_lines_processed) / (duration)); - bh_printf(" Processed %l tokens (%f tokens/second).\n", - lexer_tokens_processed, - ((f32) 1000 * lexer_tokens_processed) / (duration)); - bh_printf("\n"); + // TODO: Replace these with bh_printf when padded formatting is added. + printf("\nStatistics:\n"); + printf(" Time taken: %lf seconds\n", (double) duration / 1000); + printf(" Processed %ld lines (%f lines/second).\n", lexer_lines_processed, ((f32) 1000 * lexer_lines_processed) / (duration)); + printf(" Processed %ld tokens (%f tokens/second).\n", lexer_tokens_processed, ((f32) 1000 * lexer_tokens_processed) / (duration)); + printf("\n"); } return ONYX_COMPILER_PROGRESS_SUCCESS;