Fix potential overflow when we're nearing 4G blocks..

This commit is contained in:
2026-06-09 23:24:57 +02:00
parent 2b4660f7d5
commit 627c6d16ca
4 changed files with 84 additions and 52 deletions
+51 -7
View File
@@ -1,8 +1,10 @@
#include "base_core.h"
#include "arena.h"
#include "platform.h"
#include <stdio.h>
#include <stdlib.h>
void arena_dump(const Arena *arena)
{
return;
@@ -51,8 +53,8 @@ static void arena_test_2(void)
TRACEF("\n");
ArenaOptions arena_params = {};
U32 arena_size = MB(1) + MemoryBlock_Header_Size;
U32 commit_size = KB(16);
U32 arena_size = MB(3) + MemoryBlock_Header_Size;
U32 commit_size = KB(72);
U32 push_size = KB(32);
arena_params.size = arena_size;
arena_params.commit_size = commit_size;
@@ -66,7 +68,7 @@ static void arena_test_2(void)
arena_dump(&arena);
ArenaCheckpoint checkpoint = arena_temp_begin(&arena);
ptr = arena_push(&arena, MB(2), 8);
ptr = arena_push(&arena, MB(4)+3, 8);
MemoryZero(ptr, MB(2));
ptr = arena_push(&arena, commit_size * 3, 8);
@@ -92,8 +94,10 @@ static void arena_test_2(void)
arena_reset_to(&arena, 1089);
arena_dump(&arena);
arena_reset_to(&arena, 0);
ptr = arena_push(&arena, MB(1), 8);
MemoryZero(ptr, MB(1));
for (U64 i = 0; i < KB(1); i++) {
ptr = arena_push(&arena, MB(1) + 3, 8);
MemoryZero(ptr, MB(1));
}
arena_free(&arena);
}
@@ -120,9 +124,49 @@ static void arena_test_3(void)
arena_free(&arena);
}
// Exercises the alignment-padding edge case: a fresh block has first_free at
// MemoryBlock_Header_Size (64), so a large alignment pushes the user pointer
// well past the header. Requesting (block_size - 64) bytes with page alignment
// previously tripped the end_pos <= block->size assert because the alignment
// gap was not accounted for. After the fix this should allocate a larger block.
static void arena_test_4(void)
{
TRACEF("\n");
U32 page_size = platform_page_size();
ArenaOptions arena_params = {};
U32 arena_size = MB(1) + MemoryBlock_Header_Size;
U32 commit_size = KB(64);
arena_params.size = arena_size;
arena_params.commit_size = commit_size;
Arena arena;
arena_init(&arena, &arena_params);
// block_size is the page-aligned arena_size. Request nearly the whole block
// but with page alignment, so the alignment gap (a full page) forces a grow.
U32 block_size = arena.block_size;
U32 push_size = block_size - MemoryBlock_Header_Size;
void *ptr = arena_push(&arena, push_size, page_size);
Assert(IsAlignedTo((uintptr_t)ptr, page_size));
MemoryZero(ptr, push_size);
printf("test_4: allocated %u bytes page-aligned at %p\n", push_size, ptr);
arena_dump(&arena);
// A second page-aligned push to make sure the cursor math still holds.
ptr = arena_push(&arena, page_size, page_size);
Assert(IsAlignedTo((uintptr_t)ptr, page_size));
MemoryZero(ptr, page_size);
printf("test_4: allocated %u bytes page-aligned at %p\n", page_size, ptr);
arena_free(&arena);
}
int main(int argc, char *argv[])
{
arena_test_1();
// arena_test_1();
arena_test_2();
arena_test_3();
// arena_test_3();
arena_test_4();
}