This commit is contained in:
Judah Caruso 2025-09-07 15:35:29 -06:00
parent cd4ad810a0
commit 872689bb42
2 changed files with 21 additions and 15 deletions

View file

@ -30,11 +30,12 @@ ArenaMode :: enum {
Restore; Restore;
} }
/// ArenaPush pushes a value of type T to the current context.arena.
ArenaPush :: ($T: Type, loc := #caller_location) -> *T { ArenaPush :: ($T: Type, loc := #caller_location) -> *T {
return ArenaPushSize(size_of(T), loc = loc).(*T); return ArenaPushSize(size_of(T), loc = loc).(*T);
} }
/// ArenaPushSize pushes size bytes to the current context.arena.
ArenaPushSize :: (size: int, align := DefaultAlign, loc := #caller_location) -> *void { ArenaPushSize :: (size: int, align := DefaultAlign, loc := #caller_location) -> *void {
if size < 0 if size < 0
{ Panic("jc: size cannot be negative", loc = loc); } { Panic("jc: size cannot be negative", loc = loc); }
@ -42,8 +43,6 @@ ArenaPushSize :: (size: int, align := DefaultAlign, loc := #caller_location) ->
return context.arena.proc(.Acquire, context.arena.data, size, 0, align, null, null, loc); return context.arena.proc(.Acquire, context.arena.data, size, 0, align, null, null, loc);
} }
ArenaSaveResult :: #type,distinct *void;
ArenaSave :: (loc := #caller_location) -> ArenaSaveResult { ArenaSave :: (loc := #caller_location) -> ArenaSaveResult {
TrySetupArena(*context.arena, loc); TrySetupArena(*context.arena, loc);
return context.arena.proc(.Save, context.arena.data, 0, 0, 0, null, null, loc).(ArenaSaveResult); return context.arena.proc(.Save, context.arena.data, 0, 0, 0, null, null, loc).(ArenaSaveResult);
@ -58,11 +57,18 @@ ArenaAutoRestore :: () #expand {
`defer ArenaRestore(wm); `defer ArenaRestore(wm);
} }
/// ArenaSaveResult is an arena-specific value used for saving/restoring.
/// see: ArenaSave
ArenaSaveResult :: #type,distinct *void;
/// ArenaReset resets arena's state, allowing its memory to be reused.
ArenaReset :: (loc := #caller_location) { ArenaReset :: (loc := #caller_location) {
TrySetupArena(*context.arena); TrySetupArena(*context.arena);
context.arena.proc(.Reset, context.arena.data, 0, 0, 0, null, null, loc); context.arena.proc(.Reset, context.arena.data, 0, 0, 0, null, null, loc);
} }
/// ArenaRelease frees an arena's memory.
ArenaRelease :: (loc := #caller_location) { ArenaRelease :: (loc := #caller_location) {
TrySetupArena(*context.arena, loc); TrySetupArena(*context.arena, loc);
context.arena.proc(.Teardown, context.arena.data, 0, 0, 0, null, null, loc); context.arena.proc(.Teardown, context.arena.data, 0, 0, 0, null, null, loc);
@ -150,7 +156,7 @@ BumpArenaProc :: (
if new_size == 0 if new_size == 0
{ return end; } { return end; }
ptr := MemAlignForward(end, align.(uint)); ptr := MemAlignForward(end, align);
size := new_size + (ptr - end); size := new_size + (ptr - end);
if bump.offset + size > bump.memory.count if bump.offset + size > bump.memory.count
{ Panic("jc: BumpArena out of memory", loc = caller); } { Panic("jc: BumpArena out of memory", loc = caller); }

View file

@ -60,39 +60,39 @@ MemReset :: (p: *$T) {
} }
} }
MemAligned :: (p: *void, align: uint = DefaultAlign) -> bool { MemAligned :: (p: *void, align: int = DefaultAlign) -> bool {
return Aligned(p.(uint), align); return Aligned(p.(int), align);
} }
MemAlignForward :: (p: *void, align: uint = DefaultAlign) -> *void { MemAlignForward :: (p: *void, align: int = DefaultAlign) -> *void {
return AlignForward(p.(uint), align).(*void); return AlignForward(p.(int), align).(*void);
} }
MemAlignBackward :: (p: *void, align: uint = DefaultAlign) -> *void { MemAlignBackward :: (p: *void, align: int = DefaultAlign) -> *void {
return AlignBackward(p.(uint), align).(*void); return AlignBackward(p.(int), align).(*void);
} }
Aligned :: (a: uint, align: uint = DefaultAlign) -> bool { Aligned :: (a: int, align: int = DefaultAlign) -> bool {
return (a & (align - 1)) == 0; return (a & (align - 1)) == 0;
} }
AlignForward :: (a: uint, align: uint = DefaultAlign) -> uint { AlignForward :: (a: int, align: int = DefaultAlign) -> int {
Assert(PowerOfTwo(align), "jc: must be a power of two"); Assert(PowerOfTwo(align), "jc: must be a power of two");
return (a + align - 1) & ~(align - 1); return (a + align - 1) & ~(align - 1);
} }
AlignBackward :: (a: uint, align: uint = DefaultAlign) -> uint { AlignBackward :: (a: int, align: int = DefaultAlign) -> int {
Assert(PowerOfTwo(align), "jc: must be a power of two"); Assert(PowerOfTwo(align), "jc: must be a power of two");
return a & ~(align - 1); return a & ~(align - 1);
} }
PowerOfTwo :: (x: uint) -> bool { PowerOfTwo :: (x: int) -> bool {
if x == 0 return false; if x == 0 return false;
return x & (x - 1) == 0; return x & (x - 1) == 0;
} }
NextPowerOfTwo :: (x: uint) -> uint #no_aoc { NextPowerOfTwo :: (x: int) -> int #no_aoc {
Assert(PowerOfTwo(x), "jc: must be a power of two"); Assert(PowerOfTwo(x), "jc: must be a power of two");
// Bit twiddling hacks next power of two // Bit twiddling hacks next power of two