mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-22 05:34:59 -07:00
Begin clarifying allocation patterns by changing from heap_allocator to specific arenas
This commit is contained in:
+3
-1
@@ -690,8 +690,10 @@ void add_global_type_entity(String name, Type *type) {
|
||||
|
||||
void init_universal(void) {
|
||||
BuildContext *bc = &build_context;
|
||||
|
||||
// NOTE(bill): No need to free these
|
||||
gbAllocator a = heap_allocator();
|
||||
// gbAllocator a = heap_allocator();
|
||||
gbAllocator a = permanent_allocator();
|
||||
|
||||
builtin_pkg = gb_alloc_item(a, AstPackage);
|
||||
builtin_pkg->name = str_lit("builtin");
|
||||
|
||||
@@ -337,8 +337,6 @@ struct Checker {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
gb_global AstPackage *builtin_pkg = nullptr;
|
||||
gb_global AstPackage *intrinsics_pkg = nullptr;
|
||||
gb_global AstPackage *config_pkg = nullptr;
|
||||
|
||||
+40
-8
@@ -373,8 +373,8 @@ typedef struct Arena {
|
||||
gbAllocator backing;
|
||||
isize block_size;
|
||||
gbMutex mutex;
|
||||
|
||||
isize total_used;
|
||||
bool use_mutex;
|
||||
} Arena;
|
||||
|
||||
#define ARENA_MIN_ALIGNMENT 16
|
||||
@@ -388,8 +388,9 @@ void arena_init(Arena *arena, gbAllocator backing, isize block_size=ARENA_DEFAUL
|
||||
}
|
||||
|
||||
void arena_grow(Arena *arena, isize min_size) {
|
||||
// gb_mutex_lock(&arena->mutex);
|
||||
// defer (gb_mutex_unlock(&arena->mutex));
|
||||
if (arena->use_mutex) {
|
||||
gb_mutex_lock(&arena->mutex);
|
||||
}
|
||||
|
||||
isize size = gb_max(arena->block_size, min_size);
|
||||
size = ALIGN_UP(size, ARENA_MIN_ALIGNMENT);
|
||||
@@ -399,11 +400,16 @@ void arena_grow(Arena *arena, isize min_size) {
|
||||
GB_ASSERT(arena->ptr == ALIGN_DOWN_PTR(arena->ptr, ARENA_MIN_ALIGNMENT));
|
||||
arena->end = arena->ptr + size;
|
||||
array_add(&arena->blocks, arena->ptr);
|
||||
|
||||
if (arena->use_mutex) {
|
||||
gb_mutex_unlock(&arena->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
void *arena_alloc(Arena *arena, isize size, isize alignment) {
|
||||
// gb_mutex_lock(&arena->mutex);
|
||||
// defer (gb_mutex_unlock(&arena->mutex));
|
||||
if (arena->use_mutex) {
|
||||
gb_mutex_lock(&arena->mutex);
|
||||
}
|
||||
|
||||
arena->total_used += size;
|
||||
|
||||
@@ -419,12 +425,17 @@ void *arena_alloc(Arena *arena, isize size, isize alignment) {
|
||||
GB_ASSERT(arena->ptr <= arena->end);
|
||||
GB_ASSERT(ptr == ALIGN_DOWN_PTR(ptr, align));
|
||||
// zero_size(ptr, size);
|
||||
|
||||
if (arena->use_mutex) {
|
||||
gb_mutex_unlock(&arena->mutex);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void arena_free_all(Arena *arena) {
|
||||
// gb_mutex_lock(&arena->mutex);
|
||||
// defer (gb_mutex_unlock(&arena->mutex));
|
||||
if (arena->use_mutex) {
|
||||
gb_mutex_lock(&arena->mutex);
|
||||
}
|
||||
|
||||
for_array(i, arena->blocks) {
|
||||
gb_free(arena->backing, arena->blocks[i]);
|
||||
@@ -432,6 +443,10 @@ void arena_free_all(Arena *arena) {
|
||||
array_clear(&arena->blocks);
|
||||
arena->ptr = nullptr;
|
||||
arena->end = nullptr;
|
||||
|
||||
if (arena->use_mutex) {
|
||||
gb_mutex_unlock(&arena->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -460,7 +475,14 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
|
||||
// GB_PANIC("gbAllocation_Free not supported");
|
||||
break;
|
||||
case gbAllocation_Resize:
|
||||
GB_PANIC("gbAllocation_Resize: not supported");
|
||||
if (size == 0) {
|
||||
ptr = nullptr;
|
||||
} else if (size <= old_size) {
|
||||
ptr = old_memory;
|
||||
} else {
|
||||
ptr = arena_alloc(arena, size, alignment);
|
||||
gb_memmove(ptr, old_memory, old_size);
|
||||
}
|
||||
break;
|
||||
case gbAllocation_FreeAll:
|
||||
arena_free_all(arena);
|
||||
@@ -472,6 +494,16 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
|
||||
|
||||
|
||||
|
||||
gb_global Arena permanent_arena = {};
|
||||
gb_global Arena temporary_arena = {};
|
||||
|
||||
gbAllocator permanent_allocator() {
|
||||
return arena_allocator(&permanent_arena);
|
||||
}
|
||||
gbAllocator temporary_allocator() {
|
||||
return arena_allocator(&temporary_arena);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ bool entity_has_deferred_procedure(Entity *e) {
|
||||
gb_global u64 global_entity_id = 0;
|
||||
|
||||
Entity *alloc_entity(EntityKind kind, Scope *scope, Token token, Type *type) {
|
||||
gbAllocator a = heap_allocator();
|
||||
gbAllocator a = permanent_allocator();
|
||||
Entity *entity = gb_alloc_item(a, Entity);
|
||||
entity->kind = kind;
|
||||
entity->state = EntityState_Unresolved;
|
||||
|
||||
+6
-1
@@ -276,6 +276,9 @@ Type *alloc_type_struct_from_field_types(Type **field_types, isize field_count,
|
||||
}
|
||||
|
||||
Type *alloc_type_tuple_from_field_types(Type **field_types, isize field_count, bool is_packed, bool must_be_tuple) {
|
||||
if (field_count == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!must_be_tuple && field_count == 1) {
|
||||
return field_types[0];
|
||||
}
|
||||
@@ -297,7 +300,9 @@ Type *alloc_type_proc_from_types(Type **param_types, unsigned param_count, Type
|
||||
Type *params = alloc_type_tuple_from_field_types(param_types, param_count, false, true);
|
||||
isize results_count = 0;
|
||||
if (results != nullptr) {
|
||||
GB_ASSERT(results->kind == Type_Tuple);
|
||||
if (results->kind != Type_Tuple) {
|
||||
results = alloc_type_tuple_from_field_types(&results, 1, false, true);
|
||||
}
|
||||
results_count = results->Tuple.variables.count;
|
||||
}
|
||||
|
||||
|
||||
+114
-165
File diff suppressed because it is too large
Load Diff
+15
-1
@@ -1643,12 +1643,15 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
timings_init(timings, str_lit("Total Time"), 128);
|
||||
defer (timings_destroy(timings));
|
||||
|
||||
arena_init(&permanent_arena, heap_allocator());
|
||||
arena_init(&temporary_arena, heap_allocator());
|
||||
arena_init(&global_ast_arena, heap_allocator());
|
||||
|
||||
init_string_buffer_memory();
|
||||
init_string_interner();
|
||||
init_global_error_collector();
|
||||
init_keyword_hash_table();
|
||||
global_big_int_init();
|
||||
arena_init(&global_ast_arena, heap_allocator());
|
||||
|
||||
array_init(&library_collections, heap_allocator());
|
||||
// NOTE(bill): 'core' cannot be (re)defined by the user
|
||||
@@ -1795,6 +1798,8 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
arena_free_all(&temporary_arena);
|
||||
|
||||
if (build_context.generate_docs) {
|
||||
// generate_documentation(&parser);
|
||||
return 0;
|
||||
@@ -1812,6 +1817,7 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
check_parsed_files(&checker);
|
||||
}
|
||||
|
||||
arena_free_all(&temporary_arena);
|
||||
|
||||
if (build_context.no_output_files) {
|
||||
if (build_context.query_data_set_settings.ok) {
|
||||
@@ -1842,6 +1848,8 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
}
|
||||
lb_generate_code(&gen);
|
||||
|
||||
arena_free_all(&temporary_arena);
|
||||
|
||||
switch (build_context.build_mode) {
|
||||
case BuildMode_Executable:
|
||||
case BuildMode_DynamicLibrary:
|
||||
@@ -1919,12 +1927,18 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
timings_start_section(timings, str_lit("llvm ir gen"));
|
||||
ir_gen_tree(&ir_gen);
|
||||
|
||||
arena_free_all(&temporary_arena);
|
||||
|
||||
timings_start_section(timings, str_lit("llvm ir opt tree"));
|
||||
ir_opt_tree(&ir_gen);
|
||||
|
||||
arena_free_all(&temporary_arena);
|
||||
|
||||
timings_start_section(timings, str_lit("llvm ir print"));
|
||||
print_llvm_ir(&ir_gen);
|
||||
|
||||
arena_free_all(&temporary_arena);
|
||||
|
||||
|
||||
String output_name = ir_gen.output_name;
|
||||
String output_base = ir_gen.output_base;
|
||||
|
||||
+25
-18
@@ -108,6 +108,30 @@ Token ast_token(Ast *node) {
|
||||
return empty_token;
|
||||
}
|
||||
|
||||
|
||||
gb_global gbAtomic64 total_allocated_node_memory = {0};
|
||||
gb_global gbAtomic64 total_subtype_node_memory_test = {0};
|
||||
|
||||
isize ast_node_size(AstKind kind) {
|
||||
return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *));
|
||||
|
||||
}
|
||||
// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++
|
||||
Ast *alloc_ast_node(AstFile *f, AstKind kind) {
|
||||
gbAllocator a = ast_allocator(f);
|
||||
|
||||
isize size = ast_node_size(kind);
|
||||
|
||||
gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast)));
|
||||
gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind]));
|
||||
|
||||
// Ast *node = gb_alloc_item(a, Ast);
|
||||
Ast *node = cast(Ast *)gb_alloc(a, size);
|
||||
node->kind = kind;
|
||||
node->file = f;
|
||||
return node;
|
||||
}
|
||||
|
||||
Ast *clone_ast(Ast *node);
|
||||
Array<Ast *> clone_ast_array(Array<Ast *> array) {
|
||||
Array<Ast *> result = {};
|
||||
@@ -125,7 +149,7 @@ Ast *clone_ast(Ast *node) {
|
||||
return nullptr;
|
||||
}
|
||||
Ast *n = alloc_ast_node(node->file, node->kind);
|
||||
gb_memmove(n, node, gb_size_of(Ast));
|
||||
gb_memmove(n, node, ast_node_size(node->kind));
|
||||
|
||||
switch (n->kind) {
|
||||
default: GB_PANIC("Unhandled Ast %.*s", LIT(ast_strings[n->kind])); break;
|
||||
@@ -463,23 +487,6 @@ bool ast_node_expect(Ast *node, AstKind kind) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
gb_global gbAtomic64 total_allocated_node_memory = {0};
|
||||
gb_global gbAtomic64 total_subtype_node_memory_test = {0};
|
||||
|
||||
// NOTE(bill): And this below is why is I/we need a new language! Discriminated unions are a pain in C/C++
|
||||
Ast *alloc_ast_node(AstFile *f, AstKind kind) {
|
||||
gbAllocator a = ast_allocator(f);
|
||||
|
||||
gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast)));
|
||||
gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind]));
|
||||
|
||||
Ast *node = gb_alloc_item(a, Ast);
|
||||
node->kind = kind;
|
||||
node->file = f;
|
||||
return node;
|
||||
}
|
||||
|
||||
Ast *ast_bad_expr(AstFile *f, Token begin, Token end) {
|
||||
Ast *result = alloc_ast_node(f, Ast_BadExpr);
|
||||
result->BadExpr.begin = begin;
|
||||
|
||||
@@ -655,6 +655,7 @@ struct Ast {
|
||||
Scope * scope;
|
||||
TypeAndValue tav;
|
||||
|
||||
// IMPORTANT NOTE(bill): This must be at the end since the AST is allocated to be size of the variant
|
||||
union {
|
||||
#define AST_KIND(_kind_name_, name, ...) GB_JOIN2(Ast, _kind_name_) _kind_name_;
|
||||
AST_KINDS
|
||||
|
||||
+4
-4
@@ -771,7 +771,8 @@ void set_base_type(Type *t, Type *base) {
|
||||
|
||||
|
||||
Type *alloc_type(TypeKind kind) {
|
||||
gbAllocator a = heap_allocator();
|
||||
// gbAllocator a = heap_allocator();
|
||||
gbAllocator a = permanent_allocator();
|
||||
Type *t = gb_alloc_item(a, Type);
|
||||
zero_item(t);
|
||||
t->kind = kind;
|
||||
@@ -2340,7 +2341,7 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
||||
GB_ASSERT(is_type_struct(type) || is_type_union(type) || is_type_tuple(type));
|
||||
type = base_type(type);
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
gbAllocator a = permanent_allocator();
|
||||
isize max_count = 0;
|
||||
switch (type->kind) {
|
||||
case Type_Struct: max_count = type->Struct.fields.count; break;
|
||||
@@ -2397,7 +2398,6 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
||||
return empty_selection;
|
||||
}
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
Type *type = type_deref(type_);
|
||||
bool is_ptr = type != type_;
|
||||
sel.indirect = sel.indirect || is_ptr;
|
||||
@@ -2986,7 +2986,7 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
}
|
||||
|
||||
Array<i64> type_set_offsets_of(Array<Entity *> const &fields, bool is_packed, bool is_raw_union) {
|
||||
gbAllocator a = heap_allocator();
|
||||
gbAllocator a = permanent_allocator();
|
||||
auto offsets = array_make<i64>(a, fields.count);
|
||||
i64 curr_offset = 0;
|
||||
if (is_raw_union) {
|
||||
|
||||
Reference in New Issue
Block a user