mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Correct arena_temp_end usage when no allocation ever happens for that arena
This commit is contained in:
+19
-17
@@ -311,26 +311,28 @@ arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
|
|||||||
arena := temp.arena
|
arena := temp.arena
|
||||||
sync.mutex_guard(&arena.mutex)
|
sync.mutex_guard(&arena.mutex)
|
||||||
|
|
||||||
memory_block_found := false
|
if temp.block != nil {
|
||||||
for block := arena.curr_block; block != nil; block = block.prev {
|
memory_block_found := false
|
||||||
if block == temp.block {
|
for block := arena.curr_block; block != nil; block = block.prev {
|
||||||
memory_block_found = true
|
if block == temp.block {
|
||||||
break
|
memory_block_found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !memory_block_found {
|
||||||
|
assert(arena.curr_block == temp.block, "memory block stored within Arena_Temp not owned by Arena", loc)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if !memory_block_found {
|
|
||||||
assert(arena.curr_block == temp.block, "memory block stored within Arena_Temp not owned by Arena", loc)
|
|
||||||
}
|
|
||||||
|
|
||||||
for arena.curr_block != temp.block {
|
for arena.curr_block != temp.block {
|
||||||
arena_growing_free_last_memory_block(arena)
|
arena_growing_free_last_memory_block(arena)
|
||||||
}
|
}
|
||||||
|
|
||||||
if block := arena.curr_block; block != nil {
|
if block := arena.curr_block; block != nil {
|
||||||
assert(block.used >= temp.used, "out of order use of arena_temp_end", loc)
|
assert(block.used >= temp.used, "out of order use of arena_temp_end", loc)
|
||||||
amount_to_zero := min(block.used-temp.used, block.reserved-block.used)
|
amount_to_zero := min(block.used-temp.used, block.reserved-block.used)
|
||||||
mem.zero_slice(block.base[temp.used:][:amount_to_zero])
|
mem.zero_slice(block.base[temp.used:][:amount_to_zero])
|
||||||
block.used = temp.used
|
block.used = temp.used
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(arena.temp_count > 0, "double-use of arena_temp_end", loc)
|
assert(arena.temp_count > 0, "double-use of arena_temp_end", loc)
|
||||||
|
|||||||
@@ -2,6 +2,73 @@ package runtime
|
|||||||
|
|
||||||
_INTEGER_DIGITS :: "0123456789abcdefghijklmnopqrstuvwxyz"
|
_INTEGER_DIGITS :: "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
when !ODIN_DISALLOW_RTTI {
|
||||||
|
print_any_single :: proc(arg: any) {
|
||||||
|
x := arg
|
||||||
|
if loc, ok := x.(Source_Code_Location); ok {
|
||||||
|
print_caller_location(loc)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x.id = typeid_base(x.id)
|
||||||
|
switch v in x {
|
||||||
|
case typeid: print_typeid(v)
|
||||||
|
case ^Type_Info: print_type(v)
|
||||||
|
|
||||||
|
case string: print_string(v)
|
||||||
|
case cstring: print_string(string(v))
|
||||||
|
case []byte: print_string(string(v))
|
||||||
|
|
||||||
|
case rune: print_rune(v)
|
||||||
|
|
||||||
|
case u8: print_u64(u64(v))
|
||||||
|
case u16: print_u64(u64(v))
|
||||||
|
case u16le: print_u64(u64(v))
|
||||||
|
case u16be: print_u64(u64(v))
|
||||||
|
case u32: print_u64(u64(v))
|
||||||
|
case u32le: print_u64(u64(v))
|
||||||
|
case u32be: print_u64(u64(v))
|
||||||
|
case u64: print_u64(u64(v))
|
||||||
|
case u64le: print_u64(u64(v))
|
||||||
|
case u64be: print_u64(u64(v))
|
||||||
|
|
||||||
|
case i8: print_i64(i64(v))
|
||||||
|
case i16: print_i64(i64(v))
|
||||||
|
case i16le: print_i64(i64(v))
|
||||||
|
case i16be: print_i64(i64(v))
|
||||||
|
case i32: print_i64(i64(v))
|
||||||
|
case i32le: print_i64(i64(v))
|
||||||
|
case i32be: print_i64(i64(v))
|
||||||
|
case i64: print_i64(i64(v))
|
||||||
|
case i64le: print_i64(i64(v))
|
||||||
|
case i64be: print_i64(i64(v))
|
||||||
|
|
||||||
|
case int: print_int(v)
|
||||||
|
case uint: print_uint(v)
|
||||||
|
case uintptr: print_uintptr(v)
|
||||||
|
|
||||||
|
case:
|
||||||
|
ti := type_info_of(x.id)
|
||||||
|
#partial switch v in ti.variant {
|
||||||
|
case Type_Info_Pointer:
|
||||||
|
print_uintptr((^uintptr)(x.data)^)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
print_string("<invalid-value>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println_any :: proc(args: ..any) {
|
||||||
|
loop: for arg, i in args {
|
||||||
|
if i != 0 {
|
||||||
|
print_string(" ")
|
||||||
|
}
|
||||||
|
print_any_single(arg)
|
||||||
|
}
|
||||||
|
print_string("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
|
encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
|
||||||
r := c
|
r := c
|
||||||
|
|
||||||
|
|||||||
@@ -1050,7 +1050,6 @@ gb_internal bool has_asm_extension(String const &path) {
|
|||||||
|
|
||||||
// temporary
|
// temporary
|
||||||
gb_internal char *token_pos_to_string(TokenPos const &pos) {
|
gb_internal char *token_pos_to_string(TokenPos const &pos) {
|
||||||
TEMPORARY_ALLOCATOR_GUARD();
|
|
||||||
gbString s = gb_string_make_reserve(temporary_allocator(), 128);
|
gbString s = gb_string_make_reserve(temporary_allocator(), 128);
|
||||||
String file = get_file_path_string(pos.file_id);
|
String file = get_file_path_string(pos.file_id);
|
||||||
switch (build_context.ODIN_ERROR_POS_STYLE) {
|
switch (build_context.ODIN_ERROR_POS_STYLE) {
|
||||||
|
|||||||
+1
-3
@@ -2375,7 +2375,7 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEMPORARY_ALLOCATOR_GUARD();
|
||||||
gbString err_str = nullptr;
|
gbString err_str = nullptr;
|
||||||
|
|
||||||
if (check_is_assignable_to(c, x, y->type) ||
|
if (check_is_assignable_to(c, x, y->type) ||
|
||||||
@@ -2405,7 +2405,6 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok
|
|||||||
if (x->type == err_type && is_operand_nil(*x)) {
|
if (x->type == err_type && is_operand_nil(*x)) {
|
||||||
err_type = y->type;
|
err_type = y->type;
|
||||||
}
|
}
|
||||||
TEMPORARY_ALLOCATOR_GUARD();
|
|
||||||
gbString type_string = type_to_string(err_type, temporary_allocator());
|
gbString type_string = type_to_string(err_type, temporary_allocator());
|
||||||
err_str = gb_string_make(temporary_allocator(),
|
err_str = gb_string_make(temporary_allocator(),
|
||||||
gb_bprintf("operator '%.*s' not defined for type '%s'", LIT(token_strings[op]), type_string));
|
gb_bprintf("operator '%.*s' not defined for type '%s'", LIT(token_strings[op]), type_string));
|
||||||
@@ -2418,7 +2417,6 @@ gb_internal void check_comparison(CheckerContext *c, Operand *x, Operand *y, Tok
|
|||||||
add_comparison_procedures_for_fields(c, comparison_type);
|
add_comparison_procedures_for_fields(c, comparison_type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TEMPORARY_ALLOCATOR_GUARD();
|
|
||||||
gbString xt, yt;
|
gbString xt, yt;
|
||||||
if (x->mode == Addressing_ProcGroup) {
|
if (x->mode == Addressing_ProcGroup) {
|
||||||
xt = gb_string_make(temporary_allocator(), "procedure group");
|
xt = gb_string_make(temporary_allocator(), "procedure group");
|
||||||
|
|||||||
+499
-490
File diff suppressed because it is too large
Load Diff
+37
-23
@@ -271,35 +271,47 @@ void arena_temp_end(ArenaTemp const &temp) {
|
|||||||
Arena *arena = temp.arena;
|
Arena *arena = temp.arena;
|
||||||
MUTEX_GUARD(&arena->mutex);
|
MUTEX_GUARD(&arena->mutex);
|
||||||
|
|
||||||
bool memory_block_found = false;
|
if (temp.block) {
|
||||||
for (MemoryBlock *block = arena->curr_block; block != nullptr; block = block->prev) {
|
bool memory_block_found = false;
|
||||||
if (block == temp.block) {
|
for (MemoryBlock *block = arena->curr_block; block != nullptr; block = block->prev) {
|
||||||
memory_block_found = true;
|
if (block == temp.block) {
|
||||||
break;
|
memory_block_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
GB_ASSERT_MSG(memory_block_found, "memory block stored within ArenaTemp not owned by Arena");
|
||||||
GB_ASSERT_MSG(memory_block_found, "memory block stored within ArenaTemp not owned by Arena");
|
|
||||||
|
|
||||||
while (arena->curr_block != temp.block) {
|
while (arena->curr_block != temp.block) {
|
||||||
MemoryBlock *free_block = arena->curr_block;
|
MemoryBlock *free_block = arena->curr_block;
|
||||||
if (free_block != nullptr) {
|
if (free_block != nullptr) {
|
||||||
arena->curr_block = free_block->prev;
|
arena->curr_block = free_block->prev;
|
||||||
virtual_memory_dealloc(free_block);
|
virtual_memory_dealloc(free_block);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MemoryBlock *block = arena->curr_block;
|
MemoryBlock *block = arena->curr_block;
|
||||||
if (block) {
|
if (block) {
|
||||||
GB_ASSERT_MSG(block->used >= temp.used, "out of order use of arena_temp_end");
|
GB_ASSERT_MSG(block->used >= temp.used, "out of order use of arena_temp_end");
|
||||||
isize amount_to_zero = gb_min(block->used - temp.used, block->size - block->used);
|
isize amount_to_zero = gb_min(block->used - temp.used, block->size - block->used);
|
||||||
gb_zero_size(block->base + temp.used, amount_to_zero);
|
gb_zero_size(block->base + temp.used, amount_to_zero);
|
||||||
block->used = temp.used;
|
block->used = temp.used;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GB_ASSERT_MSG(arena->temp_count > 0, "double-use of arena_temp_end");
|
GB_ASSERT_MSG(arena->temp_count > 0, "double-use of arena_temp_end");
|
||||||
arena->temp_count -= 1;
|
arena->temp_count -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arena_temp_ignore(ArenaTemp const &temp) {
|
||||||
|
GB_ASSERT(temp.arena);
|
||||||
|
Arena *arena = temp.arena;
|
||||||
|
MUTEX_GUARD(&arena->mutex);
|
||||||
|
|
||||||
|
GB_ASSERT_MSG(arena->temp_count > 0, "double-use of arena_temp_end");
|
||||||
|
arena->temp_count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ArenaTempGuard {
|
struct ArenaTempGuard {
|
||||||
ArenaTempGuard(Arena *arena) {
|
ArenaTempGuard(Arena *arena) {
|
||||||
@@ -363,11 +375,13 @@ gb_internal gbAllocator temporary_allocator() {
|
|||||||
return arena_allocator(&temporary_arena);
|
return arena_allocator(&temporary_arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEMPORARY_ALLOCATOR_GUARD()
|
|
||||||
#define PERMANENT_ALLOCATOR_GUARD()
|
|
||||||
|
|
||||||
// #define TEMPORARY_ALLOCATOR_GUARD() ArenaTempGuard GB_DEFER_3(_arena_guard_){&temporary_arena}
|
#define TEMP_ARENA_GUARD(arena) ArenaTempGuard GB_DEFER_3(_arena_guard_){arena}
|
||||||
// #define PERMANENT_ALLOCATOR_GUARD() ArenaTempGuard GB_DEFER_3(_arena_guard_){&permanent_arena}
|
|
||||||
|
|
||||||
|
// #define TEMPORARY_ALLOCATOR_GUARD()
|
||||||
|
#define TEMPORARY_ALLOCATOR_GUARD() TEMP_ARENA_GUARD(&temporary_arena)
|
||||||
|
#define PERMANENT_ALLOCATOR_GUARD()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user