fix arena bugs

This commit is contained in:
Matthew 2025-09-27 20:40:36 +10:00
parent fe1a04d3b4
commit 6e1952eab0

41
alloc.d
View File

@ -24,13 +24,13 @@ struct ArenaPool
{
u8* mem;
u64 pos;
u64 length;
}
struct Arena
{
SLList!(ArenaPool) pools;
u64 pool_length;
u64 length;
u64 def_size;
}
struct TempArena
@ -107,11 +107,10 @@ Arena
CreateArena(u64 size)
{
Arena arena = {
length: size,
pool_length: size - Node!(ArenaPool).sizeof,
def_size: size,
};
AddArenaPool(&arena);
AddArenaPool(&arena, size);
return arena;
}
@ -182,14 +181,15 @@ Alloc(T)(TempArena* t)
}
void
AddArenaPool(Arena* arena)
AddArenaPool(Arena* arena, u64 size)
{
u8* mem = cast(u8*)MemAlloc(arena.length);
u8* mem = Alloc!(u8)(size + Node!(ArenaPool).sizeof).ptr;
Node!(ArenaPool)* node = cast(Node!(ArenaPool)*)mem;
node.value.mem = (cast(u8*)mem) + Node!(ArenaPool).sizeof;
node.value.pos = 0;
node.value.length = size;
assert(node.value.mem != null, "Unable to allocate memory for arena");
@ -229,8 +229,6 @@ Alloc(T)(Arena* arena)
void*
AllocAlign(Arena* arena, u64 size, u64 alignment)
{
assert(size <= arena.pool_length, "Unable to allocate memory within arena size");
void* ptr = null;
uintptr mem_pos, current, offset;
@ -239,7 +237,12 @@ AllocAlign(Arena* arena, u64 size, u64 alignment)
{
if(node == null)
{
AddArenaPool(arena);
if(size > arena.def_size)
{
size += arena.def_size;
}
AddArenaPool(arena, Max(size, arena.def_size));
node = arena.pools.first;
}
@ -247,7 +250,7 @@ AllocAlign(Arena* arena, u64 size, u64 alignment)
current = mem_pos + node.value.pos;
offset = AlignPow2(current, alignment) - mem_pos;
if(offset+size <= arena.pool_length)
if(offset+size <= node.value.length)
{
break;
}
@ -278,7 +281,7 @@ Free(Arena* arena)
Node!(ArenaPool)* node = arena.pools.first;
while (node != null)
{
MemFree(node.value.mem, arena.length);
Free(node);
node = node.next;
}
}
@ -329,9 +332,17 @@ ScratchAllocCopy(T)(T[] target)
unittest
{
u64[5] arr = [1, 2, 3, 4, 5];
{
u64[5] arr = [1, 2, 3, 4, 5];
u64[] copy = AllocCopy!(u64)(arr);
u64[] copy = AllocCopy!(u64)(arr);
assert(arr == copy);
assert(arr == copy);
}
{
Arena a = CreateArena(64);
u64[] arr = Alloc!(u64)(&a, 128);
}
}