aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-02-24 20:01:58 +0100
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commite0544300fb7da9a660a55eaf25f1996af573cd43 (patch)
treed6e375f78f10a0c9ad16d984aa218234a5d078e1 /src
parent204a1cc2b01ed3f18cb3e33bd6aa756d1f99dda8 (diff)
Separate buffers from general allocation, but still have them in scoped allocator
Diffstat (limited to 'src')
-rw-r--r--src/ast.c2
-rw-r--r--src/buffer.c42
-rw-r--r--src/parser.c2
-rw-r--r--src/scoped_allocator.c19
4 files changed, 47 insertions, 18 deletions
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 <assert.h>
-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 <assert.h>
-#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