Add size-1 cache to arenas
This commit is contained in:
27
src/arena.c
27
src/arena.c
@@ -20,6 +20,7 @@ struct ucl_arena *ucl_arena_create(size_t object_size, size_t capacity) {
|
|||||||
arena->capacity = capacity;
|
arena->capacity = capacity;
|
||||||
arena->objects = malloc(capacity * object_size);
|
arena->objects = malloc(capacity * object_size);
|
||||||
arena->used_map = malloc(used_map_size);
|
arena->used_map = malloc(used_map_size);
|
||||||
|
arena->next_free = 0;
|
||||||
arena->stats.used = 0;
|
arena->stats.used = 0;
|
||||||
arena->stats.freed = 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) {
|
void *ucl_arena_get(struct ucl_arena *arena) {
|
||||||
int used_map_ints = DIV_ROUND_UP(arena->capacity, INT_BITS);
|
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++ ) {
|
for (int i = 0; i < used_map_ints; i++ ) {
|
||||||
// TODO: Maybe keep a cache of available used_map_ints
|
// TODO: Maybe keep a cache of available used_map_ints
|
||||||
int map = arena->used_map[i];
|
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->used_map[i] |= 1 << bit_index;
|
||||||
arena->stats.used += 1;
|
arena->stats.used += 1;
|
||||||
|
|
||||||
return (char *) arena->objects + (index * arena->object_size);
|
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++;
|
total_arena_puts++;
|
||||||
|
|
||||||
arena->used_map[int_index] &= ~(1 << bit_index);
|
arena->used_map[int_index] &= ~(1 << bit_index);
|
||||||
|
|
||||||
|
/* if (arena->next_free == -1) { */
|
||||||
|
arena->next_free = index;
|
||||||
|
/* } */
|
||||||
|
|
||||||
arena->stats.used -= 1;
|
arena->stats.used -= 1;
|
||||||
arena->stats.freed += 1;
|
arena->stats.freed += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 *ucl_scope_get(struct ucl *state, struct ucl_scope *scope, const char *name) {
|
||||||
struct ucl_object *cell = ucl_scope_get_cell(scope, name);
|
struct ucl_object *cell = ucl_scope_get_cell(scope, name);
|
||||||
if (cell == NULL) {
|
while (cell == NULL) {
|
||||||
if (scope->parent == NULL) {
|
if (scope->parent == NULL) {
|
||||||
// TODO: Include the symbol name
|
// TODO: Include the symbol name
|
||||||
return ucl_error_create(state, "Unbound symbol");
|
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);
|
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) {
|
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),
|
ucl_string_create(state, name),
|
||||||
obj));
|
obj));
|
||||||
} else {
|
} else {
|
||||||
// TODO: Refcounting / cleanup
|
|
||||||
cell->cell.cdr->cell.car = obj;
|
cell->cell.cdr->cell.car = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ struct ucl_arena {
|
|||||||
size_t capacity;
|
size_t capacity;
|
||||||
void *objects;
|
void *objects;
|
||||||
int *used_map;
|
int *used_map;
|
||||||
|
/** Cache of size 1 **/
|
||||||
|
int next_free;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
size_t used;
|
size_t used;
|
||||||
|
|||||||
Reference in New Issue
Block a user