From e0544300fb7da9a660a55eaf25f1996af573cd43 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 24 Feb 2019 20:01:58 +0100 Subject: Separate buffers from general allocation, but still have them in scoped allocator --- src/ast.c | 2 +- src/buffer.c | 42 ++++++++++++++++++++++++++++-------------- src/parser.c | 2 +- src/scoped_allocator.c | 19 +++++++++++++++++-- 4 files changed, 47 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/ast.c b/src/ast.c index 2802c3b..3ea4fe1 100644 --- a/src/ast.c +++ b/src/ast.c @@ -9,7 +9,7 @@ Ast ast_none() { int funcdecl_init(FunctionDecl *self, ScopedAllocator *allocator) { self->name = create_buffer_view_null(); - return buffer_init(&self->body, allocator, sizeof(Ast) * 4); + return buffer_init(&self->body, allocator); } int funcdecl_add_to_body(FunctionDecl *self, Ast ast) { diff --git a/src/buffer.c b/src/buffer.c index ad50771..349c186 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,41 +1,55 @@ #include "../include/buffer.h" #include "../include/alloc.h" #include "../include/mem.h" +#include "../include/scoped_allocator.h" #include -int buffer_init(Buffer *self, ScopedAllocator *allocator, usize initial_capacity) { +int buffer_init(Buffer *self, ScopedAllocator *allocator) { + self->data = NULL; + self->size = 0; + self->capacity = 0; self->allocator = allocator; + if(self->allocator) + return scoped_allocator_add_buffer(self->allocator, self); + return 0; +} + +void buffer_deinit(Buffer *self) { + am_free(self->data); + self->data = NULL; self->size = 0; - self->capacity = initial_capacity; - return scoped_allocator_alloc(self->allocator, initial_capacity, (void**)&self->data); + self->capacity = 0; } -static CHECK_RESULT int buffer_ensure_capacity_for(Buffer *self, usize size) { +static CHECK_RESULT int buffer_ensure_capacity(Buffer *self, usize new_capacity) { + usize capacity; void *new_mem; int alloc_result; - usize new_capacity; - new_capacity = self->size + size; if(self->capacity >= new_capacity) return BUFFER_OK; - /* - We are using alloc here instead of realloc because we are using scoped allocator - which doesn't reallocate. TODO: Verify if scoped allocator node size is enough to hold buffers... - */ - alloc_result = scoped_allocator_alloc(self->allocator, new_capacity, &new_mem); + capacity = self->capacity; + if(capacity == 0) { + capacity = new_capacity; + } else { + while(capacity < new_capacity) { + capacity *= 1.5; + } + } + + alloc_result = am_realloc(self->data, capacity, &new_mem); if(alloc_result != ALLOC_OK) return BUFFER_ALLOC_FAIL; self->data = new_mem; - self->capacity = new_capacity; + self->capacity = capacity; return BUFFER_OK; } int buffer_append(Buffer *self, void *data, usize size) { - return_if_error(buffer_ensure_capacity_for(self, size)); + return_if_error(buffer_ensure_capacity(self, self->size + size)); am_memcpy(self->data + self->size, data, size); - self->size += size; return BUFFER_OK; } diff --git a/src/parser.c b/src/parser.c index 6a1c796..78b0018 100644 --- a/src/parser.c +++ b/src/parser.c @@ -8,7 +8,7 @@ static CHECK_RESULT int parser_parse_body(Parser *self, Ast *ast); int parser_init(Parser *self) { return_if_error(scoped_allocator_init(&self->allocator)); - return_if_error(buffer_init(&self->ast_objects, &self->allocator, sizeof(Ast) * 8)); + return_if_error(buffer_init(&self->ast_objects, &self->allocator)); return PARSER_OK; } diff --git a/src/scoped_allocator.c b/src/scoped_allocator.c index cbf1aad..7e2cb0d 100644 --- a/src/scoped_allocator.c +++ b/src/scoped_allocator.c @@ -2,7 +2,7 @@ #include "../include/alloc.h" #include -#define ALLOC_NODE_SIZE 65536 +#define ALLOC_NODE_SIZE 4096 int scoped_allocator_node_init(ScopedAllocatorNode *self) { self->data = NULL; @@ -25,11 +25,22 @@ void scoped_allocator_node_deinit(ScopedAllocatorNode *self) { int scoped_allocator_init(ScopedAllocator *self) { return_if_error(scoped_allocator_node_init(&self->head)); self->current = &self->head; - return 0; + return buffer_init(&self->buffers, NULL); } + void scoped_allocator_deinit(ScopedAllocator *self) { + Buffer *buffer; + Buffer *buffer_end; + scoped_allocator_node_deinit(&self->head); self->current = NULL; + buffer = (Buffer*)&self->buffers.data[0]; + buffer_end = buffer + self->buffers.size / sizeof(Buffer); + while(buffer != buffer_end) { + buffer_deinit(buffer); + ++buffer; + } + buffer_deinit(&self->buffers); } static CHECK_RESULT int scoped_allocator_ensure_capacity_for(ScopedAllocator *self, usize size) { @@ -57,4 +68,8 @@ int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) { *mem = &self->current->data[self->current->size]; self->current->size += size; return 0; +} + +int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer) { + return buffer_append(&self->buffers, buffer, sizeof(buffer)); } \ No newline at end of file -- cgit v1.2.3