From d77ca22f5f846d2db5e3d75067e924eefded905e Mon Sep 17 00:00:00 2001 From: Max Regan Date: Wed, 30 Nov 2022 00:52:07 -0500 Subject: [PATCH] Add size-1 cache to arenas --- src/arena.c | 27 +++++++++++++++++++++++++++ src/scope.c | 8 ++++---- src/types.h | 2 ++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/arena.c b/src/arena.c index a6d0b7d..b9fd61c 100644 --- a/src/arena.c +++ b/src/arena.c @@ -20,6 +20,7 @@ struct ucl_arena *ucl_arena_create(size_t object_size, size_t capacity) { arena->capacity = capacity; arena->objects = malloc(capacity * object_size); arena->used_map = malloc(used_map_size); + arena->next_free = 0; arena->stats.used = 0; arena->stats.freed = 0; @@ -50,6 +51,26 @@ void ucl_arena_map(struct ucl_arena *arena, void (*map_function)(struct ucl_aren void *ucl_arena_get(struct ucl_arena *arena) { int used_map_ints = DIV_ROUND_UP(arena->capacity, INT_BITS); + + + if (arena->next_free != -1) { + // Cache hit + /* unsigned int int_index = arena->next_free / INT_BITS; */ + /* unsigned int bit_index = arena->next_free % INT_BITS; */ + + unsigned int int_index = arena->next_free >> 5; + unsigned int bit_index = arena->next_free & 31; + + arena->used_map[int_index] |= 1 << bit_index; + + void *ret = (char *) arena->objects + (arena->next_free * arena->object_size); + arena->next_free = -1; + + arena->stats.used += 1; + return ret; + } + + // Cache miss for (int i = 0; i < used_map_ints; i++ ) { // TODO: Maybe keep a cache of available used_map_ints int map = arena->used_map[i]; @@ -65,6 +86,7 @@ void *ucl_arena_get(struct ucl_arena *arena) { } arena->used_map[i] |= 1 << bit_index; arena->stats.used += 1; + return (char *) arena->objects + (index * arena->object_size); } @@ -90,6 +112,11 @@ void ucl_arena_put(struct ucl_arena *arena, void *object) { total_arena_puts++; arena->used_map[int_index] &= ~(1 << bit_index); + + /* if (arena->next_free == -1) { */ + arena->next_free = index; + /* } */ + arena->stats.used -= 1; arena->stats.freed += 1; } diff --git a/src/scope.c b/src/scope.c index 2cbf3b0..f622564 100644 --- a/src/scope.c +++ b/src/scope.c @@ -30,15 +30,16 @@ static struct ucl_object *ucl_scope_get_cell(struct ucl_scope *scope, const char struct ucl_object *ucl_scope_get(struct ucl *state, struct ucl_scope *scope, const char *name) { struct ucl_object *cell = ucl_scope_get_cell(scope, name); - if (cell == NULL) { + while (cell == NULL) { if (scope->parent == NULL) { // TODO: Include the symbol name return ucl_error_create(state, "Unbound symbol"); - } else { - return ucl_scope_get(state, scope->parent, name); } + scope = scope->parent; + cell = ucl_scope_get_cell(scope, name); } return ucl_list_nth(cell, DATA_POSITION); + } void ucl_scope_put(struct ucl *state, struct ucl_scope *scope, const char *name, struct ucl_object *obj) { @@ -51,7 +52,6 @@ void ucl_scope_put(struct ucl *state, struct ucl_scope *scope, const char *name, ucl_string_create(state, name), obj)); } else { - // TODO: Refcounting / cleanup cell->cell.cdr->cell.car = obj; } } diff --git a/src/types.h b/src/types.h index a9cce81..631e990 100644 --- a/src/types.h +++ b/src/types.h @@ -55,6 +55,8 @@ struct ucl_arena { size_t capacity; void *objects; int *used_map; + /** Cache of size 1 **/ + int next_free; struct { size_t used;