From aad7b591796cb20bdd9bb0aed610d760fac49790 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Tue, 4 Nov 2025 15:17:11 -0500 Subject: [PATCH] WIP(untesed, not-compiled): Still curating, Ai code was terrible, scrapping most of it. --- C/watl.v0.llvm.lottes.c | 159 ++++++++------------------- C/watl.v0.llvm.lottes_hybrid.c | 171 +++++++++++++---------------- C/watl.v0.msvc.c | 193 ++++++++++++++------------------- 3 files changed, 203 insertions(+), 320 deletions(-) diff --git a/C/watl.v0.llvm.lottes.c b/C/watl.v0.llvm.lottes.c index c4740f1..155af5e 100644 --- a/C/watl.v0.llvm.lottes.c +++ b/C/watl.v0.llvm.lottes.c @@ -843,16 +843,17 @@ I_ U8 varena__make__u(U8 reserve_size, U8 commit_size, U8 flags, U8 base_addr) { return base; } void varena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 result) { - if (result == null || arena == null) { return; } - if (amount == 0) { struct_zero(Slice_Mem, result); return; } - U8 reg align = alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT; - U8 reg requested_size = amount * type_width; + assert(result != null); + assert(arena != null); + if (amount == 0) { struct_zero(Slice_Mem, result); return; } + U8 align = alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT; + U8 requested_size = amount * type_width; U8 reg aligned_size = align_pow2(requested_size, align); U8_R reg commit_used = u8_r(arena + offset_of(VArena, commit_used )); U8 reg reserve_left = u8_r(arena + offset_of(VArena, reserve ))[0] - commit_used[0]; if (aligned_size > reserve_left) { struct_zero(Slice_Mem, result); return; } U8 reg committed = u8_r(arena + offset_of(VArena, committed ))[0]; - U8 reg commit_left = committed - commit_used[0]; + U8 commit_left = committed - commit_used[0]; if (commit_left < aligned_size) { U8 reg commit_size = u8_r(arena + offset_of(VArena, commit_size))[0]; U8 reg next_commit = reserve_left > aligned_size ? max(commit_size, aligned_size) : reserve_left; @@ -872,47 +873,28 @@ void varena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 result struct_copy(Slice_Mem, result, (U8)& slice_mem(current_offset, requested_size)); } } +inline void varena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) { - if (result == null || arena == null) { return; } - if (old_ptr == 0 || requested_size <= old_len) { - struct_copy(Slice_Mem, result, (U8)& slice_mem(old_ptr, requested_size)); - return; - } - U8_R reg commit_used = u8_r(arena + offset_of(VArena, commit_used)); - U8 reg reserve_start = u8_r(arena + offset_of(VArena, reserve_start))[0]; - U8 reg current_offset = reserve_start + commit_used[0]; - if (old_ptr + old_len != current_offset) { - struct_zero(Slice_Mem, result); - return; - } - U8 reg grow_amount = requested_size - old_len; - uvar(Slice_Mem, extra) = {0}; - varena__push__u(arena, grow_amount, 1, alignment, u8_(extra)); - U8 extra_ptr = u8_r(extra + offset_of(Slice_Mem, ptr))[0]; - U8 extra_len = u8_r(extra + offset_of(Slice_Mem, len))[0]; - if (extra_ptr == 0) { - struct_zero(Slice_Mem, result); - return; - } - U8 reg new_len = old_len + extra_len; - struct_copy(Slice_Mem, result, (U8)& slice_mem(old_ptr, new_len)); - if (should_zero && grow_amount != 0) { - memory_zero(old_ptr + old_len, grow_amount); - } -} + assert(arena != null); + assert(result != null); +} +void varena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) { + +} +inline I_ void varena_release__u(U8 arena) { - if (arena == null) { return; } + assert(arena != null); os_vmem_release__u(arena, u8_r(arena + offset_of(VArena, reserve))[0]); } I_ void varena_reset__u(U8 arena) { - if (arena == null) { return; } + assert(arena != null); u8_r(arena + offset_of(VArena, commit_used))[0] = 0; } I_ void varena_rewind__u(U8 arena, U8 sp_type_sig, U8 sp_slot) { - if (arena == null) { return; } + assert(arena != null); assert(sp_type_sig == (U8) varena_allocator_proc); - U8 header = varena__header_size(); + U8 reg header = varena__header_size(); if (sp_slot < header) { sp_slot = header; } u8_r(arena + offset_of(VArena, commit_used))[0] = sp_slot; } @@ -922,114 +904,67 @@ I_ void varena_save__u(U8 arena, U8 sp_addr) { u8_r(sp_addr + offset_of(AllocatorSP, slot ))[0] = u8_r(arena + offset_of(VArena, commit_used))[0]; } -void varena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) { - if (result == null || arena == null) { return; } - if (old_ptr == 0 || requested_size >= old_len) { - struct_copy(Slice_Mem, result, (U8)& slice_mem(old_ptr, min(requested_size, old_len))); - return; - } - U8_R reg commit_used = u8_r(arena + offset_of(VArena, commit_used)); - U8 reg reserve_start = u8_r(arena + offset_of(VArena, reserve_start))[0]; - U8 reg current_offset = reserve_start + commit_used[0]; - if (old_ptr + old_len != current_offset) { - struct_copy(Slice_Mem, result, (U8)& slice_mem(old_ptr, requested_size)); - return; - } - U8 reg aligned_original = align_pow2(old_len, MEMORY_ALIGNMENT_DEFAULT); - U8 reg aligned_new = align_pow2(requested_size, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT); - if (aligned_new > aligned_original) { aligned_new = aligned_original; } - commit_used[0] -= (aligned_original - aligned_new); - struct_copy(Slice_Mem, result, (U8)& slice_mem(old_ptr, requested_size)); -} - I_ VArena* varena__make(Opts_varena_make* opts) { assert(opts != nullptr); return cast(VArena*, varena__make__u(opts->reserve_size, opts->commit_size, opts->flags, opts->base_addr)); } - -Slice_Mem varena__push(VArena_R arena, U8 amount, U8 type_width, Opts_varena* opts) { +I_ Slice_Mem varena__push(VArena_R arena, U8 amount, U8 type_width, Opts_varena* opts) { Slice_Mem result; varena__push__u(u8_(arena), amount, type_width, opts ? opts->alignment : 0, u8_(& result)); return result; } - -void varena_release(VArena_R arena) { varena_release__u(u8_(arena)); } -void varena_reset (VArena_R arena) { varena_reset__u (u8_(arena)); } - -void varena_rewind(VArena_R arena, AllocatorSP save_point) { - varena_rewind__u(u8_(arena), u8_(save_point.type_sig), save_point.slot); -} - -Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size, Opts_varena* opts) { +I_ Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size, Opts_varena* opts) { Slice_Mem result; varena__shrink__u(u8_(& result), u8_(arena), old_allocation.ptr, old_allocation.len, requested_size, opts ? opts->alignment : 0); return result; } -AllocatorSP varena_save(VArena_R arena) { - AllocatorSP sp; - varena_save__u(u8_(arena), u8_(& sp)); - return sp; +I_ void varena_release(VArena_R arena) { varena_release__u(u8_(arena)); } +I_ void varena_reset (VArena_R arena) { varena_reset__u (u8_(arena)); } + +I_ void varena_rewind (VArena_R arena, AllocatorSP save_point) { + varena_rewind__u(u8_(arena), u8_(save_point.type_sig), save_point.slot); } +I_ AllocatorSP varena_save(VArena_R arena) { AllocatorSP sp; varena_save__u(u8_(arena), u8_(& sp)); return sp; } void varena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr) { - AllocatorProc_Out* out = cast(AllocatorProc_Out*, out_addr); - U8 allocation_addr = out_addr ? out_addr + offset_of(AllocatorProc_Out, allocation) : 0; - if (arena == null) { - if (allocation_addr) { struct_zero(Slice_Mem, allocation_addr); } - return; - } + assert(arena != null); + assert(out_addr != null); + U8 out_allocation = out_addr ? out_addr + offset_of(AllocatorProc_Out, allocation) : 0; switch (op) { case AllocatorOp_Alloc: case AllocatorOp_Alloc_NoZero: - if (allocation_addr) { - varena__push__u(arena, requested_size, 1, alignment, allocation_addr); - if (op == AllocatorOp_Alloc) { - U8 ptr = u8_r(allocation_addr + offset_of(Slice_Mem, ptr))[0]; - U8 len = u8_r(allocation_addr + offset_of(Slice_Mem, len))[0]; - if (ptr && len) { memory_zero(ptr, len); } - } + varena__push__u(arena, requested_size, 1, alignment, out_allocation); + if (op == AllocatorOp_Alloc) { + U8 ptr = u8_r(out_allocation + offset_of(Slice_Mem, ptr))[0]; + U8 len = u8_r(out_allocation + offset_of(Slice_Mem, len))[0]; + if (ptr && len) { memory_zero(ptr, len); } } - break; + break; - case AllocatorOp_Free: - break; - - case AllocatorOp_Reset: - varena_reset__u(arena); - break; + case AllocatorOp_Free: break; + case AllocatorOp_Reset: varena_reset__u(arena); break; case AllocatorOp_Grow: case AllocatorOp_Grow_NoZero: - if (allocation_addr) { - varena__grow__u(allocation_addr, arena, old_ptr, old_len, requested_size, alignment, op - AllocatorOp_Grow_NoZero); - } - break; - + varena__grow__u(out_allocation, arena, old_ptr, old_len, requested_size, alignment, op - AllocatorOp_Grow_NoZero); + break; case AllocatorOp_Shrink: - if (allocation_addr) { - varena__shrink__u(allocation_addr, arena, old_ptr, old_len, requested_size, alignment); - } - break; + varena__shrink__u(out_allocation, arena, old_ptr, old_len, requested_size, alignment); + break; - case AllocatorOp_Rewind: - varena_rewind__u(arena, old_ptr, old_len); - break; - - case AllocatorOp_SavePoint: - if (out_addr) { varena_save__u(arena, out_addr + offset_of(AllocatorProc_Out, save_point)); } - break; + case AllocatorOp_Rewind: varena_rewind__u(arena, old_ptr, old_len); break; + case AllocatorOp_SavePoint: varena_save__u (arena, out_addr + offset_of(AllocatorProc_Out, save_point)); break; case AllocatorOp_Query: - if (out_addr) { u4_r(out_addr + offset_of(AllocatorQueryInfo, features))[0] = AllocatorQuery_Alloc | AllocatorQuery_Reset | AllocatorQuery_Resize | AllocatorQuery_Rewind; - U8 reserve = u8_r(arena + offset_of(VArena, reserve))[0]; + U8 reserve = u8_r(arena + offset_of(VArena, reserve ))[0]; U8 committed = u8_r(arena + offset_of(VArena, committed))[0]; U8 max_alloc = (reserve > committed) ? (reserve - committed) : 0; u8_r(out_addr + offset_of(AllocatorQueryInfo, max_alloc))[0] = max_alloc; @@ -1037,11 +972,7 @@ void varena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr u8_r(out_addr + offset_of(AllocatorQueryInfo, left ))[0] = max_alloc; AllocatorSP sp = { .type_sig = varena_allocator_proc, .slot = u8_r(arena + offset_of(VArena, commit_used))[0] }; struct_copy(AllocatorSP, out_addr + offset_of(AllocatorQueryInfo, save_point), (U8)& sp); - } - break; - - default: - break; + break; } } #pragma endregion VArena diff --git a/C/watl.v0.llvm.lottes_hybrid.c b/C/watl.v0.llvm.lottes_hybrid.c index 70250de..35921a3 100644 --- a/C/watl.v0.llvm.lottes_hybrid.c +++ b/C/watl.v0.llvm.lottes_hybrid.c @@ -473,7 +473,7 @@ VArena* varena__make(Opts_varena_make*R_ opts); finline void varena_release(VArena_R arena); finline void varena_rewind (VArena_R arena, AllocatorSP save_point); void varena_reset (VArena_R arena); - Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size, Opts_varena*R_ opts); + Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size); finline AllocatorSP varena_save (VArena_R arena); void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out); @@ -1159,21 +1159,21 @@ inline Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 no_zero) { Slice_Mem result; U8 grow_amount = requested_size - old_allocation.len; - if (grow_amount == 0) { result = old_allocation; return; } // Growing when not the last allocation not allowed + if (grow_amount == 0) { result = old_allocation; return result; } // Growing when not the last allocation not allowed U8 current_offset = vm->reserve_start + vm->commit_used; assert(old_allocation.ptr == current_offset); Slice_Mem allocation = varena_push_mem(vm, grow_amount, alignment); assert(allocation.ptr != 0); - result = (Slice_Mem){ old_allocation.ptr, requested_size + allocation.len }; memory_zero(result.ptr, result.len * no_zero); + result = (Slice_Mem){ old_allocation.ptr, requested_size + allocation.len }; + memory_zero(result.ptr, result.len * no_zero); + return result; } finline void varena_release(VArena_R arena) { os_vmem_release(u8_(arena), arena->reserve); } inline -Slice_Mem varena__shrink(VArena_R vm, Slice_Mem old_allocation, U8 requested_size, Opts_varena*R_ opts) { - assert(opts != nullptr); - Slice_Mem result = {0}; - U8 shrink_amount = old_allocation.len - requested_size; - if (lt_s(shrink_amount, 0)) { result = old_allocation; return result; } +Slice_Mem varena__shrink(VArena_R vm, Slice_Mem old_allocation, U8 requested_size) { + U8 shrink_amount = old_allocation.len - requested_size; + if (lt_s(shrink_amount, 0)) { return old_allocation; } U8 current_offset = vm->reserve_start + vm->commit_used; assert(old_allocation.ptr == current_offset); vm->commit_used -= shrink_amount; - result = (Slice_Mem){ old_allocation.ptr, requested_size }; return result; + return (Slice_Mem){ old_allocation.ptr, requested_size }; } finline void varena_rewind(VArena_R vm, AllocatorSP sp) { @@ -1197,32 +1197,11 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out) case AllocatorOp_Reset: vm->commit_used = 0; break; case AllocatorOp_Grow_NoZero: - case AllocatorOp_Grow: { - U8 grow_amount = in.requested_size - in.old_allocation.len; - if (grow_amount == 0) { - out->allocation = in.old_allocation; - return; - } - U8 current_offset = vm->reserve_start + vm->commit_used; - // Growing when not the last allocation not allowed - assert(in.old_allocation.ptr == current_offset); - Slice_Mem allocation = varena_push_mem(vm, grow_amount, .alignment = in.alignment); - assert(allocation.ptr != 0); - out->allocation = (Slice_Mem){ in.old_allocation.ptr, in.requested_size + allocation.len }; - memory_zero(out->allocation.ptr, out->allocation.len * (in.op - AllocatorOp_Grow_NoZero)); - } + case AllocatorOp_Grow: + out->allocation = varena__grow(vm, in.old_allocation, in.requested_size, in.alignment, in.op - AllocatorOp_Grow_NoZero); break; - case AllocatorOp_Shrink: { - U8 current_offset = vm->reserve_start + vm->commit_used; - U8 shrink_amount = in.old_allocation.len - in.requested_size; - if (lt_s(shrink_amount, 0)) { - out->allocation = in.old_allocation; - return; - } - assert(in.old_allocation.ptr == current_offset); - vm->commit_used -= shrink_amount; - out->allocation = (Slice_Mem){ in.old_allocation.ptr, in.requested_size }; - } + case AllocatorOp_Shrink: + out->allocation = varena__shrink(vm, in.old_allocation, in.requested_size); break; case AllocatorOp_Rewind: vm->commit_used = in.save_point.slot; break; @@ -1327,80 +1306,80 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out) assert(arena != nullptr); switch (in.op) { - case AllocatorOp_Alloc: - case AllocatorOp_Alloc_NoZero: - out->allocation = arena_push_mem(arena, in.requested_size, .alignment = in.alignment); - memory_zero(out->allocation.ptr, out->allocation.len * in.op); - break; + case AllocatorOp_Alloc: + case AllocatorOp_Alloc_NoZero: + out->allocation = arena_push_mem(arena, in.requested_size, .alignment = in.alignment); + memory_zero(out->allocation.ptr, out->allocation.len * in.op); + break; - case AllocatorOp_Free: break; - case AllocatorOp_Reset: arena_reset(arena); break; + case AllocatorOp_Free: break; + case AllocatorOp_Reset: arena_reset(arena); break; - case AllocatorOp_Grow: - case AllocatorOp_Grow_NoZero: { - Arena_R active = arena->current; - U8 alloc_end = in.old_allocation.ptr + in.old_allocation.len; - U8 arena_end = u8_(active) + active->pos; - if (alloc_end == arena_end) + case AllocatorOp_Grow: + case AllocatorOp_Grow_NoZero: { + Arena_R active = arena->current; + U8 alloc_end = in.old_allocation.ptr + in.old_allocation.len; + U8 arena_end = u8_(active) + active->pos; + if (alloc_end == arena_end) + { + U8 grow_amount = in.requested_size - in.old_allocation.len; + U8 aligned_grow = align_pow2(grow_amount, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); + if (active->pos + aligned_grow <= active->backing->reserve) { - U8 grow_amount = in.requested_size - in.old_allocation.len; - U8 aligned_grow = align_pow2(grow_amount, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); - if (active->pos + aligned_grow <= active->backing->reserve) + Slice_Mem vresult = varena_push_mem(active->backing, aligned_grow, .alignment = in.alignment); + if (vresult.ptr != null) { - Slice_Mem vresult = varena_push_mem(active->backing, aligned_grow, .alignment = in.alignment); - if (vresult.ptr != null) - { - active->pos += aligned_grow; - out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size}; - memory_zero(in.old_allocation.ptr + in.old_allocation.len, grow_amount * in.op - AllocatorOp_Grow_NoZero); - break; - } + active->pos += aligned_grow; + out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size}; + memory_zero(in.old_allocation.ptr + in.old_allocation.len, grow_amount * in.op - AllocatorOp_Grow_NoZero); + break; } } - Slice_Mem new_alloc = arena__push(arena, in.requested_size, 1, &(Opts_arena){.alignment = in.alignment}); - if (new_alloc.ptr == null) { - out->allocation = (Slice_Mem){0}; - break; - } - memory_copy(new_alloc.ptr, in.old_allocation.ptr, in.old_allocation.len); - memory_zero(new_alloc.ptr + in.old_allocation.len, (in.requested_size - in.old_allocation.len) * in.op - AllocatorOp_Grow_NoZero); - out->allocation = new_alloc; } - break; + Slice_Mem new_alloc = arena__push(arena, in.requested_size, 1, &(Opts_arena){.alignment = in.alignment}); + if (new_alloc.ptr == null) { + out->allocation = (Slice_Mem){0}; + break; + } + memory_copy(new_alloc.ptr, in.old_allocation.ptr, in.old_allocation.len); + memory_zero(new_alloc.ptr + in.old_allocation.len, (in.requested_size - in.old_allocation.len) * in.op - AllocatorOp_Grow_NoZero); + out->allocation = new_alloc; + } + break; - case AllocatorOp_Shrink: { - Arena_R active = arena->current; - U8 alloc_end = in.old_allocation.ptr + in.old_allocation.len; - U8 arena_end = u8_(active) + active->pos; - if (alloc_end != arena_end) { - out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size}; - break; - } - //SSIZE shrink_amount = in.old_allocation.len - in.requested_size; - U8 aligned_original = align_pow2(in.old_allocation.len, MEMORY_ALIGNMENT_DEFAULT); - U8 aligned_new = align_pow2(in.requested_size, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); - U8 pos_reduction = aligned_original - aligned_new; - active->pos -= pos_reduction; - varena__shrink(active->backing, in.old_allocation, in.requested_size, &(Opts_varena){.alignment = in.alignment}); + case AllocatorOp_Shrink: { + Arena_R active = arena->current; + U8 alloc_end = in.old_allocation.ptr + in.old_allocation.len; + U8 arena_end = u8_(active) + active->pos; + if (alloc_end != arena_end) { out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size}; + break; } - break; + //SSIZE shrink_amount = in.old_allocation.len - in.requested_size; + U8 aligned_original = align_pow2(in.old_allocation.len, MEMORY_ALIGNMENT_DEFAULT); + U8 aligned_new = align_pow2(in.requested_size, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); + U8 pos_reduction = aligned_original - aligned_new; + active->pos -= pos_reduction; + varena__shrink(active->backing, in.old_allocation, in.requested_size, &(Opts_varena){.alignment = in.alignment}); + out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size}; + } + break; - case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break; - case AllocatorOp_SavePoint: out->save_point = arena_save(arena); break; + case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break; + case AllocatorOp_SavePoint: out->save_point = arena_save(arena); break; - case AllocatorOp_Query: - out->features = - AllocatorQuery_Alloc - | AllocatorQuery_Resize - | AllocatorQuery_Reset - | AllocatorQuery_Rewind - ; - out->max_alloc = arena->backing->reserve; - out->min_alloc = kilo(4); - out->left = out->max_alloc - arena->backing->commit_used; - out->save_point = arena_save(arena); - break; + case AllocatorOp_Query: + out->features = + AllocatorQuery_Alloc + | AllocatorQuery_Resize + | AllocatorQuery_Reset + | AllocatorQuery_Rewind + ; + out->max_alloc = arena->backing->reserve; + out->min_alloc = kilo(4); + out->left = out->max_alloc - arena->backing->commit_used; + out->save_point = arena_save(arena); + break; } } #pragma endregion Arena diff --git a/C/watl.v0.msvc.c b/C/watl.v0.msvc.c index 65c0756..590fcd0 100644 --- a/C/watl.v0.msvc.c +++ b/C/watl.v0.msvc.c @@ -58,10 +58,11 @@ enum { false = 0, true = 1, true_overflow, }; #define offset_of(type, member) cast(SSIZE, & (((type*) 0)->member)) #define size_of(data) cast(SSIZE, sizeof(data)) -#define R_ __restrict -#define V_ volatile -#define r_(ptr) cast(typeof_ptr(ptr)*R_, ptr) -#define v_(ptr) cast(typeof_ptr(ptr)*V_, ptr) +// Not using this since its lottes related. +// #define R_ __restrict +// #define V_ volatile +// #define r_(ptr) cast(typeof_ptr(ptr)*R_, ptr) +// #define v_(ptr) cast(typeof_ptr(ptr)*V_, ptr) #define ssize(value) cast(SSIZE, value) #define kilo(n) (cast(SSIZE, n) << 10) @@ -369,7 +370,7 @@ Slice_Byte varena__push (VArena* arena, SSIZE amount, SSIZE type_width, Opts_v void varena_release(VArena* arena); void varena_rewind (VArena* arena, AllocatorSP save_point); void varena_reset (VArena* arena); -Slice_Byte varena__shrink(VArena* arena, Slice_Byte old_allocation, SSIZE requested_size, Opts_varena* opts); +Slice_Byte varena__shrink(VArena* arena, Slice_Byte old_allocation, SSIZE requested_size); AllocatorSP varena_save (VArena* arena); void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out); @@ -842,6 +843,44 @@ Slice_Byte farena__push(FArena* arena, SSIZE amount, SSIZE type_width, Opts_fare arena->used += to_commit; return (Slice_Byte){ptr, desired}; } +inline +Slice_Byte farena__grow(FArena* arena, SSIZE requested_size, Slice_Byte old_allocation, SSIZE alignment, B32 no_zero) { + // Check if the allocation is at the end of the arena + Byte* alloc_end = old_allocation.ptr + old_allocation.len; + Byte* arena_end = cast(Byte*, cast(SSIZE, arena->start) + arena->used); + if (alloc_end != arena_end) { + // Not at the end, can't grow in place + return (Slice_Byte){0}; + } + // Calculate growth + SSIZE grow_amount = requested_size - old_allocation.len; + SSIZE aligned_grow = align_pow2(grow_amount, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT); + SSIZE unused = arena->capacity - arena->used; + if (aligned_grow > unused) { + // Not enough space + return (Slice_Byte){0}; + } + arena->used += aligned_grow; + Slice_Byte result = (Slice_Byte){old_allocation.ptr, requested_size}; + memory_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(SSIZE, no_zero)); + return result; +} +inline +Slice_Byte farena__shrink(FArena* arena, Slice_Byte old_allocation, SSIZE requested_size, SSIZE alignment) { + // Check if the allocation is at the end of the arena + Byte* alloc_end = old_allocation.ptr + old_allocation.len; + Byte* arena_end = cast(Byte*, cast(SSIZE, arena->start) + arena->used); + if (alloc_end != arena_end) { + // Not at the end, can't shrink but return adjusted size + return (Slice_Byte){old_allocation.ptr, requested_size}; + } + // Calculate shrinkage + //SSIZE shrink_amount = in.old_allocation.len - in.requested_size; + SSIZE aligned_original = align_pow2(old_allocation.len, MEMORY_ALIGNMENT_DEFAULT); + SSIZE aligned_new = align_pow2(requested_size, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT); + arena->used -= (aligned_original - aligned_new); + return (Slice_Byte){old_allocation.ptr, requested_size}; +} inline void farena_reset(FArena* arena) { arena->used = 0; } inline void farena_rewind(FArena* arena, AllocatorSP save_point) { @@ -867,61 +906,19 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out) memory_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op)); break; - case AllocatorOp_Free: - break; - case AllocatorOp_Reset: - farena_reset(arena); - break; + case AllocatorOp_Free: break; + case AllocatorOp_Reset: farena_reset(arena); break; case AllocatorOp_Grow: - case AllocatorOp_Grow_NoZero: { - // Check if the allocation is at the end of the arena - Byte* alloc_end = in.old_allocation.ptr + in.old_allocation.len; - Byte* arena_end = cast(Byte*, cast(SSIZE, arena->start) + arena->used); - if (alloc_end != arena_end) { - // Not at the end, can't grow in place - out->allocation = (Slice_Byte){0}; - break; - } - // Calculate growth - SSIZE grow_amount = in.requested_size - in.old_allocation.len; - SSIZE aligned_grow = align_pow2(grow_amount, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); - SSIZE unused = arena->capacity - arena->used; - if (aligned_grow > unused) { - // Not enough space - out->allocation = (Slice_Byte){0}; - break; - } - arena->used += aligned_grow; - out->allocation = (Slice_Byte){in.old_allocation.ptr, in.requested_size}; - memory_zero(in.old_allocation.ptr + in.old_allocation.len, grow_amount * cast(SSIZE, in.op - AllocatorOp_Grow_NoZero)); - } + case AllocatorOp_Grow_NoZero: + out->allocation = farena__grow(arena, in.requested_size, in.old_allocation, in.alignment, in.op - AllocatorOp_Grow_NoZero); + break; + case AllocatorOp_Shrink: + out->allocation = farena__shrink(arena, in.old_allocation, in.requested_size, in.alignment); break; - case AllocatorOp_Shrink: { - // Check if the allocation is at the end of the arena - Byte* alloc_end = in.old_allocation.ptr + in.old_allocation.len; - Byte* arena_end = cast(Byte*, cast(SSIZE, arena->start) + arena->used); - if (alloc_end != arena_end) { - // Not at the end, can't shrink but return adjusted size - out->allocation = (Slice_Byte){in.old_allocation.ptr, in.requested_size}; - break; - } - // Calculate shrinkage - //SSIZE shrink_amount = in.old_allocation.len - in.requested_size; - SSIZE aligned_original = align_pow2(in.old_allocation.len, MEMORY_ALIGNMENT_DEFAULT); - SSIZE aligned_new = align_pow2(in.requested_size, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); - arena->used -= (aligned_original - aligned_new); - out->allocation = (Slice_Byte){in.old_allocation.ptr, in.requested_size}; - } - break; - - case AllocatorOp_Rewind: - farena_rewind(arena, in.save_point); - break; - case AllocatorOp_SavePoint: - out->save_point = farena_save(* arena); - break; + case AllocatorOp_Rewind: farena_rewind(arena, in.save_point); break; + case AllocatorOp_SavePoint: out->save_point = farena_save(* arena); break; case AllocatorOp_Query: out->features = @@ -1044,7 +1041,7 @@ inline void os_vmem_release(void* vm, SSIZE size) { VirtualFree(vm, 0, MS_MEM_R #pragma endregion OS #pragma region VArena (Virutal Address Space Arena) -finline U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); } +finline SSIZE varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); } inline VArena* varena__make(Opts_varena_make* opts) { assert(opts != nullptr); @@ -1094,21 +1091,26 @@ Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena* vm->commit_used = to_be_used; return (Slice_Byte){.ptr = cast(Byte*, current_offset), .len = requested_size}; } -inline void varena_release(VArena* arena) { os_vmem_release(arena, arena->reserve); } -inline Slice_Byte varena__shrink(VArena* vm, Slice_Byte old_allocation, SSIZE requested_size, Opts_varena* opts) { - assert(opts != nullptr); - Slice_Byte result = {0}; - SSIZE current_offset = vm->reserve_start + vm->commit_used; - SSIZE shrink_amount = old_allocation.len - requested_size; - if (shrink_amount < 0) { - result = old_allocation; - return result; - } - assert(old_allocation.ptr == cast(Byte*, current_offset)); - vm->commit_used -= shrink_amount; - result = (Slice_Byte){ old_allocation.ptr, requested_size }; +inline +Slice_Byte varena__grow(VArena* vm, SSIZE requested_size, Slice_Byte old_allocation, SSIZE alignment, B32 no_zero) { + assert(vm != nullptr); + SSIZE grow_amount = requested_size - old_allocation.len; + if (grow_amount == 0) { return old_allocation; } // Growing when not the last allocation not allowed + SSIZE current_offset = vm->reserve_start + vm->commit_used; assert(old_allocation.ptr == cast(Byte*, current_offset)); + Slice_Byte allocation = varena_push_array(vm, Byte, grow_amount, alignment); assert(allocation.ptr != nullptr); + Slice_Byte result = (Slice_Byte){ old_allocation.ptr, requested_size }; + memory_zero(allocation.ptr, allocation.len * no_zero); return result; } +inline Slice_Byte varena__shrink(VArena* vm, Slice_Byte old_allocation, SSIZE requested_size) { + SSIZE current_offset = vm->reserve_start + vm->commit_used; + SSIZE shrink_amount = old_allocation.len - requested_size; + if (shrink_amount < 0) { return old_allocation; } + assert(old_allocation.ptr == cast(Byte*, current_offset)); + vm->commit_used -= shrink_amount; + return (Slice_Byte){ old_allocation.ptr, requested_size }; +} +inline void varena_release(VArena* arena) { os_vmem_release(arena, arena->reserve); } inline void varena_rewind(VArena* vm, AllocatorSP sp) { assert(vm != nullptr); @@ -1127,47 +1129,19 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out) memory_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op)); break; - case AllocatorOp_Free: + case AllocatorOp_Free: break; + case AllocatorOp_Reset: vm->commit_used = 0; break; + + case AllocatorOp_Grow_NoZero: + case AllocatorOp_Grow: + out->allocation = varena__grow(vm, in.requested_size, in.old_allocation, in.alignment, in.op - AllocatorOp_Grow_NoZero); break; - case AllocatorOp_Reset: - vm->commit_used = 0; + case AllocatorOp_Shrink: + out->allocation = varena__shrink(vm, in.old_allocation, in.requested_size); break; - case AllocatorOp_Grow_NoZero: - case AllocatorOp_Grow: { - SSIZE grow_amount = in.requested_size - in.old_allocation.len; - if (grow_amount == 0) { - out->allocation = in.old_allocation; - return; - } - SSIZE current_offset = vm->reserve_start + vm->commit_used; - // Growing when not the last allocation not allowed - assert(in.old_allocation.ptr == cast(Byte*, current_offset)); - Slice_Byte allocation = varena_push_array(vm, Byte, grow_amount, .alignment = in.alignment); - assert(allocation.ptr != nullptr); - out->allocation = (Slice_Byte){ in.old_allocation.ptr, in.requested_size }; - memory_zero(out->allocation.ptr, out->allocation.len * (in.op - AllocatorOp_Grow_NoZero)); - } - break; - case AllocatorOp_Shrink: { - SSIZE current_offset = vm->reserve_start + vm->commit_used; - SSIZE shrink_amount = in.old_allocation.len - in.requested_size; - if (shrink_amount < 0) { - out->allocation = in.old_allocation; - return; - } - assert(in.old_allocation.ptr == cast(Byte*, current_offset)); - vm->commit_used -= shrink_amount; - out->allocation = (Slice_Byte){ in.old_allocation.ptr, in.requested_size }; - } - break; - - case AllocatorOp_Rewind: - vm->commit_used = in.save_point.slot; - break; - case AllocatorOp_SavePoint: - out->save_point = varena_save(vm); - break; + case AllocatorOp_Rewind: vm->commit_used = in.save_point.slot; break; + case AllocatorOp_SavePoint: out->save_point = varena_save(vm); break; case AllocatorOp_Query: out->features = @@ -1321,8 +1295,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out) SSIZE aligned_new = align_pow2(in.requested_size, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT); SSIZE pos_reduction = aligned_original - aligned_new; active->pos -= pos_reduction; - varena__shrink(active->backing, in.old_allocation, in.requested_size, &(Opts_varena){.alignment = in.alignment}); - out->allocation = (Slice_Byte){in.old_allocation.ptr, in.requested_size}; + out->allocation = varena__shrink(active->backing, in.old_allocation, in.requested_size); } break;