mirror of
https://github.com/Ed94/WATL_Exercise.git
synced 2025-11-08 17:49:18 -08:00
Compare commits
3 Commits
7aaf617b3c
...
ac05262c8d
| Author | SHA1 | Date | |
|---|---|---|---|
| ac05262c8d | |||
| 3bb46692e1 | |||
| a7d17a8b70 |
@@ -12,7 +12,7 @@ https://youtu.be/RrL7121MOeA
|
|||||||
#pragma clang diagnostic ignored "-Wpre-c11-compat"
|
#pragma clang diagnostic ignored "-Wpre-c11-compat"
|
||||||
// #pragma clang diagnostic ignored "-Wc++-keyword"
|
// #pragma clang diagnostic ignored "-Wc++-keyword"
|
||||||
#pragma clang diagnostic ignored "-Wcast-qual"
|
#pragma clang diagnostic ignored "-Wcast-qual"
|
||||||
#pragma clang diagnostic ignored "-Wunused-const-variable"
|
// #pragma clang diagnostic ignored "-Wunused-constvariable"
|
||||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
|
||||||
#pragma clang diagnostic ignored "-Wswitch"
|
#pragma clang diagnostic ignored "-Wswitch"
|
||||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||||
@@ -40,15 +40,14 @@ https://youtu.be/RrL7121MOeA
|
|||||||
#pragma region Header
|
#pragma region Header
|
||||||
|
|
||||||
#pragma region DSL
|
#pragma region DSL
|
||||||
#define local_persist static
|
#define LP_ static
|
||||||
#define global static
|
#define G_ static
|
||||||
#define internal static
|
|
||||||
|
|
||||||
#define A_(x) __attribute__((aligned (x)))
|
#define A_(x) __attribute__((aligned (x)))
|
||||||
#define E_(x,y) __builtin_expect(x,y)
|
#define E_(x,y) __builtin_expect(x,y)
|
||||||
#define S_ static
|
#define S_ static
|
||||||
#define I_ internal inline __attribute__((always_inline))
|
#define I_ S_ inline __attribute__((always_inline))
|
||||||
#define N_ internal __attribute__((noinline))
|
#define N_ S_ __attribute__((noinline))
|
||||||
#define R_ __restrict
|
#define R_ __restrict
|
||||||
#define V_ volatile
|
#define V_ volatile
|
||||||
#define W_ __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__))
|
#define W_ __attribute((__stdcall__)) __attribute__((__force_align_arg_pointer__))
|
||||||
@@ -206,7 +205,7 @@ typedef def_struct(Slice_Str8) { U8 ptr; U8 len; };
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
// Deviation from Lottes's Convention: Don't want to mess with passing in typeless strings to the assert handler.
|
// Deviation from Lottes's Convention: Don't want to mess with passing in typeless strings to the assert handler.
|
||||||
void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... );
|
S_ void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... );
|
||||||
#else
|
#else
|
||||||
#define debug_trap()
|
#define debug_trap()
|
||||||
#define assert_trap(cond)
|
#define assert_trap(cond)
|
||||||
@@ -454,7 +453,7 @@ typedef def_struct(FArena) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
I_ void farena_init__u (U8 arena, U8 mem_ptr, U8 mem_len);
|
I_ void farena_init__u (U8 arena, U8 mem_ptr, U8 mem_len);
|
||||||
void farena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr);
|
S_ void farena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr);
|
||||||
I_ void farena_reset__u (U8 arena);
|
I_ void farena_reset__u (U8 arena);
|
||||||
I_ void farena_rewind__u(U8 arena, U8 sp_slot);
|
I_ void farena_rewind__u(U8 arena, U8 sp_slot);
|
||||||
I_ void farena_save__u (U8 arena, U8 sp);
|
I_ void farena_save__u (U8 arena, U8 sp);
|
||||||
@@ -466,7 +465,7 @@ I_ void farena_reset (FArena_R arena);
|
|||||||
I_ void farena_rewind(FArena_R arena, AllocatorSP save_point);
|
I_ void farena_rewind(FArena_R arena, AllocatorSP save_point);
|
||||||
I_ AllocatorSP farena_save (FArena arena);
|
I_ AllocatorSP farena_save (FArena arena);
|
||||||
|
|
||||||
void farena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
|
S_ void farena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
|
||||||
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) }
|
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) }
|
||||||
|
|
||||||
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
|
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
|
||||||
@@ -483,10 +482,10 @@ typedef def_struct(OS_SystemInfo) { U8 target_page_size; };
|
|||||||
typedef def_struct(Opts_vmem) { U8 base_addr; B4 no_large_pages; A4_B1 _PAD_; };
|
typedef def_struct(Opts_vmem) { U8 base_addr; B4 no_large_pages; A4_B1 _PAD_; };
|
||||||
|
|
||||||
typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; };
|
typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; };
|
||||||
global OS_Windows_State os__windows_info;
|
G_ OS_Windows_State os__windows_info;
|
||||||
|
|
||||||
I_ OS_SystemInfo* os_system_info(void);
|
I_ U8 os_system_info(void);
|
||||||
void os_init (void);
|
S_ void os_init (void);
|
||||||
|
|
||||||
I_ U8 os_vmem_reserve__u( U8 size, B4 no_large_pages, U8 base_addr);
|
I_ U8 os_vmem_reserve__u( U8 size, B4 no_large_pages, U8 base_addr);
|
||||||
I_ B4 os_vmem_commit__u (U8 vm, U8 size, B4 no_large_pages);
|
I_ B4 os_vmem_commit__u (U8 vm, U8 size, B4 no_large_pages);
|
||||||
@@ -520,14 +519,14 @@ typedef def_struct(Opts_varena_make) {
|
|||||||
VArenaFlags flags;
|
VArenaFlags flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
U8 varena__make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr);
|
S_ U8 varena__make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr);
|
||||||
I_ void varena_release__u(U8 arena);
|
I_ void varena_release__u(U8 arena);
|
||||||
I_ void varena_reset__u (U8 arena);
|
I_ void varena_reset__u (U8 arena);
|
||||||
I_ void varena_rewind__u (U8 arena, U8 sp_slot);
|
I_ void varena_rewind__u (U8 arena, U8 sp_slot);
|
||||||
I_ void varena_save__u (U8 arena, U8 sp_addr);
|
I_ void varena_save__u (U8 arena, U8 sp_addr);
|
||||||
void varena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr);
|
S_ void varena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignment, U8 slice_addr);
|
||||||
void varena__grow__u (U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero);
|
S_ void varena__grow__u (U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero);
|
||||||
void varena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment);
|
S_ void varena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment);
|
||||||
|
|
||||||
I_ VArena* varena__make (Opts_varena_make*R_ opts);
|
I_ VArena* varena__make (Opts_varena_make*R_ opts);
|
||||||
I_ Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
|
I_ Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
|
||||||
@@ -539,7 +538,7 @@ I_ AllocatorSP varena_save (VArena_R arena);
|
|||||||
|
|
||||||
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
||||||
|
|
||||||
void varena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
|
S_ void varena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
|
||||||
|
|
||||||
#define ainfo_varena(arena) (AllocatorInfo){ .proc = varena_allocator_proc, .data = u8_(arena) }
|
#define ainfo_varena(arena) (AllocatorInfo){ .proc = varena_allocator_proc, .data = u8_(arena) }
|
||||||
|
|
||||||
@@ -568,22 +567,22 @@ typedef def_struct(Arena) {
|
|||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
|
|
||||||
U8 arena_make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr);
|
S_ U8 arena_make__u (U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr);
|
||||||
void arena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignemnt, U8 out_mem);
|
S_ void arena__push__u (U8 arena, U8 amount, U8 type_width, U8 alignemnt, U8 out_mem);
|
||||||
void arena_release__u(U8 arena);
|
I_ void arena_release__u(U8 arena);
|
||||||
void arena_reset__u (U8 arena);
|
I_ void arena_reset__u (U8 arena);
|
||||||
void arena_rewind__u (U8 arena, U8 slot);
|
S_ void arena_rewind__u (U8 arena, U8 slot);
|
||||||
void arena_save__u (U8 arena, U8 out_sp);
|
I_ void arena_save__u (U8 arena, U8 out_sp);
|
||||||
|
|
||||||
typedef Opts_varena_make Opts_arena_make;
|
typedef Opts_varena_make Opts_arena_make;
|
||||||
Arena* arena__make (Opts_arena_make*R_ opts);
|
S_ Arena* arena__make (Opts_arena_make*R_ opts);
|
||||||
Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
|
S_ Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
|
||||||
I_ void arena_release(Arena_R arena);
|
I_ void arena_release(Arena_R arena);
|
||||||
I_ void arena_reset (Arena_R arena);
|
I_ void arena_reset (Arena_R arena);
|
||||||
void arena_rewind (Arena_R arena, AllocatorSP save_point);
|
S_ void arena_rewind (Arena_R arena, AllocatorSP save_point);
|
||||||
I_ AllocatorSP arena_save (Arena_R arena);
|
I_ AllocatorSP arena_save (Arena_R arena);
|
||||||
|
|
||||||
void arena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
|
S_ void arena_allocator_proc(U8 data, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out);
|
||||||
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) }
|
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) }
|
||||||
|
|
||||||
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
||||||
@@ -599,7 +598,7 @@ cast(type*, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(string
|
|||||||
|
|
||||||
#pragma region Hashing
|
#pragma region Hashing
|
||||||
I_ void hash64_fnv1a__u(U8 hash, U8 data_ptr, U8 data_len, U8 seed) {
|
I_ void hash64_fnv1a__u(U8 hash, U8 data_ptr, U8 data_len, U8 seed) {
|
||||||
local_persist U8 const default_seed = 0xcbf29ce484222325;
|
LP_ U8 const default_seed = 0xcbf29ce484222325;
|
||||||
if (seed != 0) { u8_r(hash)[0] = seed; }
|
if (seed != 0) { u8_r(hash)[0] = seed; }
|
||||||
else { u8_r(hash)[0] = default_seed; }
|
else { u8_r(hash)[0] = default_seed; }
|
||||||
U8 elem = data_ptr;
|
U8 elem = data_ptr;
|
||||||
@@ -642,7 +641,7 @@ typedef def_farray(Str8, 2);
|
|||||||
typedef def_Slice(A2_Str8);
|
typedef def_Slice(A2_Str8);
|
||||||
typedef def_KTL_Slot(Str8);
|
typedef def_KTL_Slot(Str8);
|
||||||
typedef def_KTL(Str8);
|
typedef def_KTL(Str8);
|
||||||
void ktl_populate_slice_a2_str8(U8 kt, U8 backing_proc, U8 backing_data, U8 values);
|
I_ void ktl_populate_slice_a2_str8(U8 kt, U8 backing_proc, U8 backing_data, U8 values);
|
||||||
#pragma endregion KTL
|
#pragma endregion KTL
|
||||||
|
|
||||||
#pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
|
#pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
|
||||||
@@ -651,7 +650,7 @@ void ktl_populate_slice_a2_str8(U8 kt, U8 backing_proc, U8 backing_data, U8 valu
|
|||||||
#pragma region String Operations
|
#pragma region String Operations
|
||||||
#pragma endregion String Operations
|
#pragma endregion String Operations
|
||||||
|
|
||||||
#pragma region FIle System
|
#pragma region File System
|
||||||
#pragma endregion FIle System
|
#pragma endregion FIle System
|
||||||
|
|
||||||
#pragma region WATL
|
#pragma region WATL
|
||||||
@@ -747,8 +746,8 @@ I_ void farena_init__u(U8 arena, U8 mem_ptr, U8 mem_len) {
|
|||||||
u8_r(arena + soff(FArena, capacity))[0] = mem_len;
|
u8_r(arena + soff(FArena, capacity))[0] = mem_len;
|
||||||
u8_r(arena + soff(FArena, used) )[0] = 0;
|
u8_r(arena + soff(FArena, used) )[0] = 0;
|
||||||
}
|
}
|
||||||
inline void farena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 result) {
|
S_ inline void farena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 result) {
|
||||||
if (amount == 0) { struct_zero(Slice_Mem, result); }
|
if (amount == 0) { slice_clear(result); }
|
||||||
U8 desired = type_width * amount;
|
U8 desired = type_width * amount;
|
||||||
U8 to_commit = align_pow2(desired, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
U8 to_commit = align_pow2(desired, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
||||||
U8_R used = u8_r(arena + soff(FArena, used));
|
U8_R used = u8_r(arena + soff(FArena, used));
|
||||||
@@ -757,7 +756,7 @@ inline void farena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8
|
|||||||
used[0] += to_commit;
|
used[0] += to_commit;
|
||||||
slice_assign_comp(result, ptr, desired);
|
slice_assign_comp(result, ptr, desired);
|
||||||
}
|
}
|
||||||
inline void farena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
|
S_ inline void farena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
|
||||||
assert(result != null);
|
assert(result != null);
|
||||||
assert(arena != null);
|
assert(arena != null);
|
||||||
U8_R used = u8_r(arena + soff(FArena, used));
|
U8_R used = u8_r(arena + soff(FArena, used));
|
||||||
@@ -783,7 +782,7 @@ inline void farena__grow__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requ
|
|||||||
slice_assign_comp(result, old_ptr, aligned_grow + requested_size);
|
slice_assign_comp(result, old_ptr, aligned_grow + requested_size);
|
||||||
mem_zero(old_ptr + old_len, grow_amount * cast(U8, should_zero));
|
mem_zero(old_ptr + old_len, grow_amount * cast(U8, should_zero));
|
||||||
}
|
}
|
||||||
inline void farena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
|
S_ inline void farena__shrink__u(U8 result, U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
|
||||||
assert(result != null);
|
assert(result != null);
|
||||||
assert(arena != null);
|
assert(arena != null);
|
||||||
U8_R used = u8_r(arena + soff(FArena, used));
|
U8_R used = u8_r(arena + soff(FArena, used));
|
||||||
@@ -812,7 +811,7 @@ I_ void farena_save__u(U8 arena, U8 sp) {
|
|||||||
u8_r(sp + soff(AllocatorSP, type_sig))[0] = (U8)& farena_allocator_proc;
|
u8_r(sp + soff(AllocatorSP, type_sig))[0] = (U8)& farena_allocator_proc;
|
||||||
u8_r(sp + soff(AllocatorSP, slot ))[0] = u8_r(arena + soff(FArena, used))[0];
|
u8_r(sp + soff(AllocatorSP, slot ))[0] = u8_r(arena + soff(FArena, used))[0];
|
||||||
}
|
}
|
||||||
void farena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out)
|
S_ void farena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, /*AllocatorProc_Out*/U8 out)
|
||||||
{
|
{
|
||||||
assert(out != null);
|
assert(out != null);
|
||||||
assert(arena != null);
|
assert(arena != null);
|
||||||
@@ -910,8 +909,8 @@ W_ MS_LPVOID ms_virtual_alloc(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD flAllocat
|
|||||||
W_ MS_BOOL ms_virtual_free(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD dwFreeType) __asm__("VirtualFree");
|
W_ MS_BOOL ms_virtual_free(MS_LPVOID lpAddress, U8 dwSize, MS_DWORD dwFreeType) __asm__("VirtualFree");
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
I_ OS_SystemInfo* os_system_info(void) {
|
I_ U8 os_system_info(void) {
|
||||||
return & os__windows_info.system_info;
|
return u8_(& os__windows_info.system_info);
|
||||||
}
|
}
|
||||||
I_ void os__enable_large_pages(void) {
|
I_ void os__enable_large_pages(void) {
|
||||||
MS_HANDLE token;
|
MS_HANDLE token;
|
||||||
@@ -927,10 +926,10 @@ I_ void os__enable_large_pages(void) {
|
|||||||
ms_close_handle(token);
|
ms_close_handle(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
S_ inline
|
||||||
void os_init(void) {
|
void os_init(void) {
|
||||||
// os__enable_large_pages();
|
// os__enable_large_pages();
|
||||||
os_system_info()->target_page_size = ms_get_larg_page_minimum();
|
u8_r(os_system_info() + soff(OS_SystemInfo, target_page_size))[0] = ms_get_larg_page_minimum();
|
||||||
}
|
}
|
||||||
I_ U8 os_vmem_reserve__u(U8 size, B4 no_large_pages, U8 base_addr) {
|
I_ U8 os_vmem_reserve__u(U8 size, B4 no_large_pages, U8 base_addr) {
|
||||||
return cast(U8, ms_virtual_alloc(cast(MS_LPVOID, base_addr), size, MS_MEM_RESERVE,
|
return cast(U8, ms_virtual_alloc(cast(MS_LPVOID, base_addr), size, MS_MEM_RESERVE,
|
||||||
@@ -957,10 +956,10 @@ I_ void os_vmem_release(U8 vm, U8 size) { os_vmem_release__u(vm, size); }
|
|||||||
#pragma region VArena (Virtual Address Space Arena)
|
#pragma region VArena (Virtual Address Space Arena)
|
||||||
I_ U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
|
I_ U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
|
||||||
|
|
||||||
inline U8 varena__make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
|
S_ inline U8 varena__make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
|
||||||
if (reserve_size == 0) { reserve_size = mega(64); }
|
if (reserve_size == 0) { reserve_size = mega(64); }
|
||||||
if (commit_size == 0) { commit_size = mega(64); }
|
if (commit_size == 0) { commit_size = mega(64); }
|
||||||
U8 page = os_system_info()->target_page_size;
|
U8 page = u8_r(os_system_info() + soff(OS_SystemInfo, target_page_size))[0];
|
||||||
U8 reserve_sz = align_pow2(reserve_size, page);
|
U8 reserve_sz = align_pow2(reserve_size, page);
|
||||||
U8 commit_sz = align_pow2(commit_size, page);
|
U8 commit_sz = align_pow2(commit_size, page);
|
||||||
B4 no_large = (flags & VArenaFlag_NoLargePages) != 0;
|
B4 no_large = (flags & VArenaFlag_NoLargePages) != 0;
|
||||||
@@ -976,8 +975,7 @@ inline U8 varena__make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_add
|
|||||||
u4_r(base + soff(VArena, flags ))[0] = flags;
|
u4_r(base + soff(VArena, flags ))[0] = flags;
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
inline
|
S_ inline void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
|
||||||
void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
|
|
||||||
assert(result != null);
|
assert(result != null);
|
||||||
assert(vm != null);
|
assert(vm != null);
|
||||||
if (amount == 0) { slice_clear(result); return; }
|
if (amount == 0) { slice_clear(result); return; }
|
||||||
@@ -997,7 +995,7 @@ void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
|
|||||||
B4 no_large_pages = (u4_r(vm + soff(VArena, flags))[0] & VArenaFlag_NoLargePages) != 0;
|
B4 no_large_pages = (u4_r(vm + soff(VArena, flags))[0] & VArenaFlag_NoLargePages) != 0;
|
||||||
U8 next_commit_start = vm + committed;
|
U8 next_commit_start = vm + committed;
|
||||||
if (os_vmem_commit__u(next_commit_start, next_commit_size, no_large_pages) == false) {
|
if (os_vmem_commit__u(next_commit_start, next_commit_size, no_large_pages) == false) {
|
||||||
struct_zero(Slice_Mem, result);
|
slice_clear(result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
committed += next_commit_size;
|
committed += next_commit_size;
|
||||||
@@ -1006,14 +1004,13 @@ void varena__push__u(U8 vm, U8 amount, U8 type_width, U8 alignment, U8 result) {
|
|||||||
}
|
}
|
||||||
commit_used[0] += aligned_size;
|
commit_used[0] += aligned_size;
|
||||||
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0];
|
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0];
|
||||||
slice_assign(result, (U8)& slice_mem(current_offset, requested_size));
|
slice_assign_comp(result, current_offset, requested_size);
|
||||||
}
|
}
|
||||||
inline
|
S_ inline void varena__grow__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
|
||||||
void varena__grow__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero) {
|
|
||||||
assert(vm != null);
|
assert(vm != null);
|
||||||
assert(result != null);
|
assert(result != null);
|
||||||
U8 grow_amount = requested_size - old_len;
|
U8 grow_amount = requested_size - old_len;
|
||||||
if (grow_amount == 0) { slice_assign(result, (U8)& slice_mem(old_ptr, old_len)); return; }
|
if (grow_amount == 0) { slice_assign_comp(result, old_ptr, old_len); return; }
|
||||||
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + u8_r(vm + soff(VArena, commit_used))[0];
|
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + u8_r(vm + soff(VArena, commit_used))[0];
|
||||||
// Growing when not the last allocation not allowed
|
// Growing when not the last allocation not allowed
|
||||||
assert(old_ptr == current_offset);
|
assert(old_ptr == current_offset);
|
||||||
@@ -1022,18 +1019,17 @@ void varena__grow__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size
|
|||||||
U8 a_len = u8_r(allocation + soff(Slice_Mem, len))[0];
|
U8 a_len = u8_r(allocation + soff(Slice_Mem, len))[0];
|
||||||
assert(a_ptr != 0);
|
assert(a_ptr != 0);
|
||||||
mem_zero(a_ptr, a_len * should_zero);
|
mem_zero(a_ptr, a_len * should_zero);
|
||||||
slice_assign(result, (U8)& slice_mem(old_ptr, old_len + a_len));
|
slice_assign_comp(result, old_ptr, old_len + a_len);
|
||||||
}
|
}
|
||||||
inline
|
S_ inline void varena__shrink__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
|
||||||
void varena__shrink__u(U8 result, U8 vm, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment) {
|
|
||||||
assert(vm != null);
|
assert(vm != null);
|
||||||
assert(result != null);
|
assert(result != null);
|
||||||
U8 shrink_amount = old_len - requested_size;
|
U8 shrink_amount = old_len - requested_size;
|
||||||
if (lt_s(shrink_amount, 0)) { slice_assign(result, (U8)& slice_mem(old_ptr, old_len)); return; }
|
if (lt_s(shrink_amount, 0)) { slice_assign_comp(result, old_ptr, old_len); return; }
|
||||||
U8_R commit_used = u8_r(vm + soff(VArena, commit_used));
|
U8_R commit_used = u8_r(vm + soff(VArena, commit_used));
|
||||||
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0]; assert(old_ptr == current_offset);
|
U8 current_offset = u8_r(vm + soff(VArena, reserve_start))[0] + commit_used[0]; assert(old_ptr == current_offset);
|
||||||
commit_used[0] -= shrink_amount;
|
commit_used[0] -= shrink_amount;
|
||||||
slice_assign(result, (U8)& slice_mem(old_ptr, requested_size));
|
slice_assign_comp(result, old_ptr, requested_size);
|
||||||
}
|
}
|
||||||
I_ void varena_release__u(U8 vm) {
|
I_ void varena_release__u(U8 vm) {
|
||||||
assert(vm != null);
|
assert(vm != null);
|
||||||
@@ -1079,8 +1075,7 @@ I_ void varena_rewind (VArena_R vm, AllocatorSP save_point) {
|
|||||||
varena_rewind__u(u8_(vm), save_point.slot);
|
varena_rewind__u(u8_(vm), save_point.slot);
|
||||||
}
|
}
|
||||||
I_ AllocatorSP varena_save(VArena_R vm) { AllocatorSP sp; varena_save__u(u8_(vm), u8_(& sp)); return sp; }
|
I_ AllocatorSP varena_save(VArena_R vm) { AllocatorSP sp; varena_save__u(u8_(vm), u8_(& sp)); return sp; }
|
||||||
|
S_ void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
|
||||||
void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
|
|
||||||
{
|
{
|
||||||
assert(vm != null);
|
assert(vm != null);
|
||||||
assert(out_addr != null);
|
assert(out_addr != null);
|
||||||
@@ -1133,7 +1128,7 @@ void varena_allocator_proc(U8 vm, U8 requested_size, U8 alignment, U8 old_ptr, U
|
|||||||
#pragma region Arena
|
#pragma region Arena
|
||||||
I_ U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); }
|
I_ U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); }
|
||||||
|
|
||||||
U8 arena_make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
|
S_ inline U8 arena_make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
|
||||||
U8 header_size = arena_header_size();
|
U8 header_size = arena_header_size();
|
||||||
U8 current = varena__make__u(reserve_size, commit_size, flags, base_addr); assert(current != null);
|
U8 current = varena__make__u(reserve_size, commit_size, flags, base_addr); assert(current != null);
|
||||||
U8 arena; varena__push__u(current, header_size, 1, MEMORY_ALIGNMENT_DEFAULT, (U8)& arena);
|
U8 arena; varena__push__u(current, header_size, 1, MEMORY_ALIGNMENT_DEFAULT, (U8)& arena);
|
||||||
@@ -1145,7 +1140,7 @@ U8 arena_make__u(U8 reserve_size, U8 commit_size, U4 flags, U8 base_addr) {
|
|||||||
u8_r(arena + soff(Arena, flags ))[0] = flags;
|
u8_r(arena + soff(Arena, flags ))[0] = flags;
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
void arena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 out_mem) {
|
S_ inline void arena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 out_mem) {
|
||||||
assert(arena != null);
|
assert(arena != null);
|
||||||
U8 active = u8_r(arena + soff(Arena, current ))[0];
|
U8 active = u8_r(arena + soff(Arena, current ))[0];
|
||||||
U8 size_requested = amount * type_width;
|
U8 size_requested = amount * type_width;
|
||||||
@@ -1178,6 +1173,42 @@ void arena__push__u(U8 arena, U8 amount, U8 type_width, U8 alignment, U8 out_mem
|
|||||||
assert(u8_r(out_mem + soff(Slice_Mem, len))[0] > 0);
|
assert(u8_r(out_mem + soff(Slice_Mem, len))[0] > 0);
|
||||||
u8_r(active + soff(Arena, pos))[0] = pos_pst;
|
u8_r(active + soff(Arena, pos))[0] = pos_pst;
|
||||||
}
|
}
|
||||||
|
S_ inline void arena__grow__u(U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, B4 should_zero, U8 out_mem) {
|
||||||
|
U8 active = arena + soff(Arena, current);
|
||||||
|
U8_R active_pos = u8_r(active + soff(Arena, pos));
|
||||||
|
U8 alloc_end = old_ptr + old_len;
|
||||||
|
U8 arena_end = active + active_pos[0];
|
||||||
|
if (alloc_end == arena_end)
|
||||||
|
{
|
||||||
|
U8 grow_amount = requested_size - old_len;
|
||||||
|
U8 aligned_grow = align_pow2(grow_amount, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
if (active_pos[0] + aligned_grow <= u8_r(active + soff(Arena, backing) + soff(VArena, reserve))[0]) {
|
||||||
|
uvar(Slice_Mem, vresult); varena__push__u(u8_r(active + soff(Arena, backing))[0], aligned_grow, 1, alignment, (U8)vresult);
|
||||||
|
if (u8_r(vresult + soff(Slice_Mem, ptr))[0] != null) {
|
||||||
|
active_pos[0] += aligned_grow;
|
||||||
|
mem_zero(old_ptr + old_len, aligned_grow * should_zero);
|
||||||
|
slice_assign_comp(out_mem, u8_(vresult) + soff(Slice_Mem, ptr), u8_(vresult) + soff(Slice_Mem, len));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arena__push__u(arena, requested_size, 1, alignment, out_mem);
|
||||||
|
if (u8_r(out_mem + soff(Slice_Mem, ptr))[0] == null) { slice_assign_comp(out_mem, 0, 0); return; }
|
||||||
|
mem_copy(u8_r(out_mem + soff(Slice_Mem, ptr))[0], old_ptr, old_len);
|
||||||
|
mem_zero(u8_r(out_mem + soff(Slice_Mem, ptr))[0], (u8_r(out_mem + soff(Slice_Mem, len))[0] - old_len) * should_zero);
|
||||||
|
}
|
||||||
|
S_ inline void arena__shrink__u(U8 arena, U8 old_ptr, U8 old_len, U8 requested_size, U8 alignment, U8 out_mem) {
|
||||||
|
U8 active = arena + soff(Arena, current);
|
||||||
|
U8_R active_pos = u8_r(active + soff(Arena, pos));
|
||||||
|
U8 alloc_end = old_ptr + old_len;
|
||||||
|
U8 arena_end = active + active_pos[0];
|
||||||
|
if (alloc_end != arena_end) { slice_assign_comp(out_mem, old_ptr, old_len); return; }
|
||||||
|
U8 aligned_original = align_pow2(old_len, MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
U8 aligned_new = align_pow2(requested_size, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
U8 pos_reduction = aligned_original - aligned_new;
|
||||||
|
u8_r(active + soff(Arena, pos))[0] -= pos_reduction;
|
||||||
|
varena__shrink__u(out_mem, active + soff(Arena, backing), old_ptr, old_len, requested_size, alignment);
|
||||||
|
}
|
||||||
I_ void arena_release__u(U8 arena) {
|
I_ void arena_release__u(U8 arena) {
|
||||||
assert(arena != null);
|
assert(arena != null);
|
||||||
U8 curr = arena + soff(Arena, current);
|
U8 curr = arena + soff(Arena, current);
|
||||||
@@ -1193,7 +1224,7 @@ void arena_rewind__u(U8 arena, U8 slot) {
|
|||||||
U8 header_size = arena_header_size();
|
U8 header_size = arena_header_size();
|
||||||
U8 curr = arena + soff(Arena, current);
|
U8 curr = arena + soff(Arena, current);
|
||||||
U8 big_pos = clamp_bot(header_size, slot);
|
U8 big_pos = clamp_bot(header_size, slot);
|
||||||
for (U8 prev = null; u8_r(curr, soff(Arena, base_pos))[0] >= big_pos; u8_r(curr) = prev) {
|
for (U8 prev = null; u8_r(curr + soff(Arena, base_pos))[0] >= big_pos; u8_r(curr)[0] = prev) {
|
||||||
prev = u8_r(curr + soff(Arena, prev))[0];
|
prev = u8_r(curr + soff(Arena, prev))[0];
|
||||||
varena_release__u(u8_r(curr + soff(Arena, backing))[0]);
|
varena_release__u(u8_r(curr + soff(Arena, backing))[0]);
|
||||||
}
|
}
|
||||||
@@ -1202,35 +1233,57 @@ void arena_rewind__u(U8 arena, U8 slot) {
|
|||||||
u8_r(curr + soff(Arena, pos))[0] = new_pos;
|
u8_r(curr + soff(Arena, pos))[0] = new_pos;
|
||||||
}
|
}
|
||||||
I_ void arena_save__u(U8 arena, U8 out_sp) {
|
I_ void arena_save__u(U8 arena, U8 out_sp) {
|
||||||
u8_r(out_sp + soff(AllocatorSP, type_sig))[0] = arena_allocator_proc;
|
u8_r(out_sp + soff(AllocatorSP, type_sig))[0] = (U8)& arena_allocator_proc;
|
||||||
u8_r(out_sp + soff(AllocatorSP, slot ))[0] =
|
u8_r(out_sp + soff(AllocatorSP, slot ))[0] =
|
||||||
u8_r(arena + soff(Arena, base_pos) )[0]
|
u8_r(arena + soff(Arena, base_pos) )[0]
|
||||||
+ u8_r(arena + soff(Arena, current) + soff(Arena, pos))[0];
|
+ u8_r(arena + soff(Arena, current) + soff(Arena, pos))[0];
|
||||||
}
|
}
|
||||||
void arena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
|
S_ inline void arena_allocator_proc(U8 arena, U8 requested_size, U8 alignment, U8 old_ptr, U8 old_len, U4 op, U8 out_addr)
|
||||||
{
|
{
|
||||||
assert(out_addr != null);
|
assert(out_addr != null);
|
||||||
assert(arena != null);
|
assert(arena != null);
|
||||||
|
U8 out_allocation = out_addr + soff(AllocatorProc_Out, allocation);
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case AllocatorOp_Alloc:
|
case AllocatorOp_Alloc:
|
||||||
case AllocatorOp_Alloc_NoZero:
|
case AllocatorOp_Alloc_NoZero:
|
||||||
|
arena__push__u(arena, requested_size, 1, alignment, out_allocation);
|
||||||
|
mem_zero(out_allocation, u8_r(out_allocation + soff(Slice_Mem, len))[0] * op);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Free: break;
|
case AllocatorOp_Free: break;
|
||||||
case AllocatorOp_Reset: break;
|
case AllocatorOp_Reset: arena_reset__u(arena); break;
|
||||||
|
|
||||||
case AllocatorOp_Grow:
|
case AllocatorOp_Grow:
|
||||||
case AllocatorOp_Grow_NoZero: break;
|
case AllocatorOp_Grow_NoZero:
|
||||||
case AllocatorOp_Shrink: break;
|
arena__grow__u(arena, old_ptr, old_len, requested_size, alignment, op - AllocatorOp_Grow_NoZero, out_allocation);
|
||||||
|
break;
|
||||||
|
case AllocatorOp_Shrink:
|
||||||
|
arena__shrink__u(arena, old_ptr, old_len, requested_size, alignment, out_allocation);
|
||||||
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Rewind: break;
|
case AllocatorOp_Rewind: arena_rewind__u(arena, old_len); break;
|
||||||
case AllocatorOp_SavePoint: break;
|
case AllocatorOp_SavePoint: arena_save__u(arena, out_addr + soff(AllocatorProc_Out, save_point)); break;
|
||||||
|
|
||||||
case AllocatorOp_Query:
|
case AllocatorOp_Query:
|
||||||
|
u4_r(out_addr + soff(AllocatorQueryInfo, features))[0] =
|
||||||
|
AllocatorQuery_Alloc
|
||||||
|
| AllocatorQuery_Resize
|
||||||
|
| AllocatorQuery_Reset
|
||||||
|
| AllocatorQuery_Rewind
|
||||||
|
;
|
||||||
|
u8_r(out_addr + soff(AllocatorQueryInfo, max_alloc ))[0] = u8_r(arena + soff(Arena, backing) + soff(VArena, reserve))[0];
|
||||||
|
u8_r(out_addr + soff(AllocatorQueryInfo, min_alloc ))[0] = kilo(4);
|
||||||
|
u8_r(out_addr + soff(AllocatorQueryInfo, left ))[0] = u8_r(out_addr + soff(AllocatorQueryInfo, max_alloc))[0] - u8_r(arena + soff(Arena, backing) + soff(VArena, commit_used))[0];
|
||||||
|
arena_save__u(arena, out_addr + soff(AllocatorQueryInfo, save_point));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
I_ Arena* arena__make(Opts_arena_make*R_ opts) {
|
||||||
|
assert(opts != nullptr);
|
||||||
|
return cast(Arena*, arena_make__u(opts->reserve_size, opts->commit_size, opts->flags, opts->base_addr));
|
||||||
|
}
|
||||||
#pragma endregion Arena
|
#pragma endregion Arena
|
||||||
|
|
||||||
#pragma region Key Table Linear (KTL)
|
#pragma region Key Table Linear (KTL)
|
||||||
@@ -1241,7 +1294,7 @@ I_ void ktl_populate_slice_a2_str8(U8 kt, U8 backing_ptr, U8 backing_len, U8 val
|
|||||||
mem__alloc__u(kt, backing_ptr, backing_len, size_of(KTL_Slot_Str8) * values_len, 0, false);
|
mem__alloc__u(kt, backing_ptr, backing_len, size_of(KTL_Slot_Str8) * values_len, 0, false);
|
||||||
for (U8 id = 0; id < values_len; ++id) {
|
for (U8 id = 0; id < values_len; ++id) {
|
||||||
U8 kt_slot = kt + soff(KTL_Str8, ptr) * id;
|
U8 kt_slot = kt + soff(KTL_Str8, ptr) * id;
|
||||||
U8 value = u8_r(values + soff(Slice_A2_Str8, ptr))[0] + size_of(A2_Str8) * id;
|
U8 value = u8_r(values + soff(Slice_A2_Str8, ptr) + size_of(A2_Str8) * id)[0];
|
||||||
mem_copy (kt_slot + soff(KTL_Slot_Str8, value), value + size_of(Str8) * 1, size_of(Str8));
|
mem_copy (kt_slot + soff(KTL_Slot_Str8, value), value + size_of(Str8) * 1, size_of(Str8));
|
||||||
hash64__fnv1a__u(kt_slot + soff(KTL_Slot_Str8, key), value);
|
hash64__fnv1a__u(kt_slot + soff(KTL_Slot_Str8, key), value);
|
||||||
}
|
}
|
||||||
@@ -1276,11 +1329,10 @@ typedef def_struct(__crt_locale_pointers) { struct __crt_locale_data* locinfo; s
|
|||||||
typedef __crt_locale_pointers* _locale_t;
|
typedef __crt_locale_pointers* _locale_t;
|
||||||
typedef char* va_list;
|
typedef char* va_list;
|
||||||
MS_FILE* __cdecl __acrt_iob_func(unsigned _Ix);
|
MS_FILE* __cdecl __acrt_iob_func(unsigned _Ix);
|
||||||
N_
|
N_ U8* __cdecl __local_stdio_printf_options(void) {
|
||||||
U8* __cdecl __local_stdio_printf_options(void) {
|
|
||||||
// NOTE(CRT): This function must not be inlined into callers to avoid ODR violations. The
|
// NOTE(CRT): This function must not be inlined into callers to avoid ODR violations. The
|
||||||
// static local variable has different names in C and in C++ translation units.
|
// static local variable has different names in C and in C++ translation units.
|
||||||
local_persist U8 _OptionsStorage; return &_OptionsStorage;
|
LP_ U8 _OptionsStorage; return &_OptionsStorage;
|
||||||
}
|
}
|
||||||
int __cdecl __stdio_common_vfprintf_s(
|
int __cdecl __stdio_common_vfprintf_s(
|
||||||
U8 _Options,
|
U8 _Options,
|
||||||
@@ -1298,7 +1350,7 @@ I_ int printf_err(char const* fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) {
|
S_ inline void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) {
|
||||||
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
||||||
if ( condition )
|
if ( condition )
|
||||||
printf_err( "`%s` \n", condition );
|
printf_err( "`%s` \n", condition );
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Version: 0 (From Scratch, 1-Stage Compilation, LLVM & WinAPI Only, Win CRT Mul
|
|||||||
Host: Windows 11 (x86-64)
|
Host: Windows 11 (x86-64)
|
||||||
Toolchain: LLVM (2025-08-30), C-Stanard: 11
|
Toolchain: LLVM (2025-08-30), C-Stanard: 11
|
||||||
|
|
||||||
Based on: Neokineogfx - Fixing C, personalized to include typeinfo more readily.
|
Based on: Neokineogfx - Fixing C, personalized to utilize typeinfo.
|
||||||
https://youtu.be/RrL7121MOeA
|
https://youtu.be/RrL7121MOeA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -185,7 +185,7 @@ typedef def_struct(Slice_Str8) { Str8* ptr; U8 len; };
|
|||||||
debug_trap(); \
|
debug_trap(); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... );
|
internal void assert_handler(UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... );
|
||||||
#else
|
#else
|
||||||
#define debug_trap()
|
#define debug_trap()
|
||||||
#define assert_trap(cond)
|
#define assert_trap(cond)
|
||||||
@@ -406,12 +406,12 @@ typedef def_struct(FArena) {
|
|||||||
};
|
};
|
||||||
finline FArena farena_make (Slice_Mem mem);
|
finline FArena farena_make (Slice_Mem mem);
|
||||||
finline void farena_init (FArena_R arena, Slice_Mem byte);
|
finline void farena_init (FArena_R arena, Slice_Mem byte);
|
||||||
Slice_Mem farena__push (FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts);
|
internal Slice_Mem farena__push (FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts);
|
||||||
finline void farena_reset (FArena_R arena);
|
finline void farena_reset (FArena_R arena);
|
||||||
finline void farena_rewind(FArena_R arena, AllocatorSP save_point);
|
finline void farena_rewind(FArena_R arena, AllocatorSP save_point);
|
||||||
finline AllocatorSP farena_save (FArena arena);
|
finline AllocatorSP farena_save (FArena arena);
|
||||||
|
|
||||||
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
internal void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
||||||
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) }
|
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = u8_(& arena) }
|
||||||
|
|
||||||
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
|
#define farena_push_mem(arena, amount, ...) farena__push(arena, amount, 1, opt_args(Opts_farena, lit(stringify(B1)), __VA_ARGS__))
|
||||||
@@ -435,7 +435,7 @@ typedef def_struct(Opts_vmem) {
|
|||||||
B4 no_large_pages;
|
B4 no_large_pages;
|
||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
void os_init(void);
|
internal void os_init (void);
|
||||||
finline OS_SystemInfo* os_system_info(void);
|
finline OS_SystemInfo* os_system_info(void);
|
||||||
|
|
||||||
finline B4 os__vmem_commit (U8 vm, U8 size, Opts_vmem*R_ opts);
|
finline B4 os__vmem_commit (U8 vm, U8 size, Opts_vmem*R_ opts);
|
||||||
@@ -467,17 +467,17 @@ typedef def_struct(Opts_varena_make) {
|
|||||||
VArenaFlags flags;
|
VArenaFlags flags;
|
||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
VArena* varena__make(Opts_varena_make*R_ opts);
|
internal VArena* varena__make(Opts_varena_make*R_ opts);
|
||||||
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
||||||
|
|
||||||
Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
|
internal Slice_Mem varena__push (VArena_R arena, U8 amount, U8 type_width, Opts_varena*R_ opts);
|
||||||
finline void varena_release(VArena_R arena);
|
finline void varena_release(VArena_R arena);
|
||||||
finline void varena_rewind (VArena_R arena, AllocatorSP save_point);
|
finline void varena_rewind (VArena_R arena, AllocatorSP save_point);
|
||||||
void varena_reset (VArena_R arena);
|
internal void varena_reset (VArena_R arena);
|
||||||
Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size);
|
internal Slice_Mem varena__shrink(VArena_R arena, Slice_Mem old_allocation, U8 requested_size);
|
||||||
finline AllocatorSP varena_save (VArena_R arena);
|
finline AllocatorSP varena_save (VArena_R arena);
|
||||||
|
|
||||||
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
internal void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
||||||
#define ainfo_varena(varena) (AllocatorInfo) { .proc = & varena_allocator_proc, .data = u8_(varena) }
|
#define ainfo_varena(varena) (AllocatorInfo) { .proc = & varena_allocator_proc, .data = u8_(varena) }
|
||||||
|
|
||||||
#define varena_push_mem(arena, amount, ...) varena__push(arena, amount, 1, opt_args(Opts_varena, lit(stringify(B1)), __VA_ARGS__))
|
#define varena_push_mem(arena, amount, ...) varena__push(arena, amount, 1, opt_args(Opts_varena, lit(stringify(B1)), __VA_ARGS__))
|
||||||
@@ -505,14 +505,14 @@ typedef def_struct(Arena) {
|
|||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
typedef Opts_varena_make Opts_arena_make;
|
typedef Opts_varena_make Opts_arena_make;
|
||||||
Arena* arena__make (Opts_arena_make*R_ opts);
|
internal Arena* arena__make (Opts_arena_make*R_ opts);
|
||||||
Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
|
internal Slice_Mem arena__push (Arena_R arena, U8 amount, U8 type_width, Opts_arena*R_ opts);
|
||||||
finline void arena_release(Arena_R arena);
|
finline void arena_release(Arena_R arena);
|
||||||
finline void arena_reset (Arena_R arena);
|
finline void arena_reset (Arena_R arena);
|
||||||
void arena_rewind (Arena_R arena, AllocatorSP save_point);
|
internal void arena_rewind (Arena_R arena, AllocatorSP save_point);
|
||||||
finline AllocatorSP arena_save (Arena_R arena);
|
finline AllocatorSP arena_save (Arena_R arena);
|
||||||
|
|
||||||
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
internal void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out_R out);
|
||||||
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) }
|
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = u8_(arena) }
|
||||||
|
|
||||||
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
||||||
@@ -568,7 +568,7 @@ typedef def_farray(Str8, 2);
|
|||||||
typedef def_Slice(A2_Str8);
|
typedef def_Slice(A2_Str8);
|
||||||
typedef def_KTL_Slot(Str8);
|
typedef def_KTL_Slot(Str8);
|
||||||
typedef def_KTL(Str8);
|
typedef def_KTL(Str8);
|
||||||
void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values);
|
finline void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values);
|
||||||
#pragma endregion KTL
|
#pragma endregion KTL
|
||||||
|
|
||||||
#pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
|
#pragma region Key Table 1-Layer Chained-Chunked-Cells (KT1CX)
|
||||||
@@ -623,11 +623,11 @@ typedef def_struct(KT1CX_Info) {
|
|||||||
AllocatorInfo backing_table;
|
AllocatorInfo backing_table;
|
||||||
AllocatorInfo backing_cells;
|
AllocatorInfo backing_cells;
|
||||||
};
|
};
|
||||||
void kt1cx_init (KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result);
|
internal void kt1cx_init (KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result);
|
||||||
void kt1cx_clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
|
internal void kt1cx_clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
|
||||||
finline U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
finline U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
||||||
U8 kt1cx_get (KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
internal U8 kt1cx_get (KT1CX_Byte kt, U8 key, KT1CX_ByteMeta meta);
|
||||||
U8 kt1cx_set (KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
internal U8 kt1cx_set (KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
||||||
|
|
||||||
#define kt1cx_assert(kt) do { \
|
#define kt1cx_assert(kt) do { \
|
||||||
slice_assert(kt.table); \
|
slice_assert(kt.table); \
|
||||||
@@ -643,13 +643,13 @@ finline U1 integer_symbols(U1 value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
finline char* str8_to_cstr_capped(Str8 content, Slice_Mem mem);
|
finline char* str8_to_cstr_capped(Str8 content, Slice_Mem mem);
|
||||||
Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator);
|
internal Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator);
|
||||||
|
|
||||||
finline Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries);
|
finline Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries);
|
||||||
#define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \
|
#define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \
|
||||||
str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
|
|
||||||
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries);
|
internal Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries);
|
||||||
#define str8_fmt(fmt_template, ...) str8__fmt(lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
#define str8_fmt(fmt_template, ...) str8__fmt(lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
|
|
||||||
#define Str8Cache_CELL_DEPTH 4
|
#define Str8Cache_CELL_DEPTH 4
|
||||||
@@ -672,7 +672,7 @@ typedef def_struct(Opts_str8cache_init) {
|
|||||||
U8 cell_pool_size;
|
U8 cell_pool_size;
|
||||||
U8 table_size;
|
U8 table_size;
|
||||||
};
|
};
|
||||||
void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts);
|
internal void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts);
|
||||||
finline Str8Cache str8cache__make( Opts_str8cache_init*R_ opts);
|
finline Str8Cache str8cache__make( Opts_str8cache_init*R_ opts);
|
||||||
|
|
||||||
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__))
|
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__))
|
||||||
@@ -698,7 +698,7 @@ finline Str8Gen str8gen_make( AllocatorInfo backing);
|
|||||||
finline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){ cast(UTF8_R, gen.ptr), gen.len}; }
|
finline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){ cast(UTF8_R, gen.ptr), gen.len}; }
|
||||||
|
|
||||||
finline void str8gen_append_str8(Str8Gen_R gen, Str8 str);
|
finline void str8gen_append_str8(Str8Gen_R gen, Str8 str);
|
||||||
void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ tokens);
|
internal void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ tokens);
|
||||||
|
|
||||||
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
#pragma endregion String Operations
|
#pragma endregion String Operations
|
||||||
@@ -712,8 +712,8 @@ typedef def_struct(Opts_read_file_contents) {
|
|||||||
B4 zero_backing;
|
B4 zero_backing;
|
||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts);
|
internal void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts);
|
||||||
void file_write_str8 (Str8 path, Str8 content);
|
internal void file_write_str8 (Str8 path, Str8 content);
|
||||||
|
|
||||||
finline FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts);
|
finline FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts);
|
||||||
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_read_file_contents, __VA_ARGS__))
|
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_read_file_contents, __VA_ARGS__))
|
||||||
@@ -756,8 +756,8 @@ typedef def_struct(Opts_watl_lex) {
|
|||||||
B1 failon_slice_constraint_fail;
|
B1 failon_slice_constraint_fail;
|
||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts);
|
internal void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts);
|
||||||
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex*R_ opts);
|
finline WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex*R_ opts);
|
||||||
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
|
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
|
||||||
|
|
||||||
typedef Str8 WATL_Node; typedef def_ptr_set(WATL_Node);
|
typedef Str8 WATL_Node; typedef def_ptr_set(WATL_Node);
|
||||||
@@ -788,11 +788,11 @@ typedef def_struct(Opts_watl_parse) {
|
|||||||
B4 failon_slice_constraint_fail;
|
B4 failon_slice_constraint_fail;
|
||||||
A4_B1 _PAD_;
|
A4_B1 _PAD_;
|
||||||
};
|
};
|
||||||
void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
|
internal void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
|
||||||
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
|
finline WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts);
|
||||||
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
|
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
|
||||||
|
|
||||||
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
|
internal Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
|
||||||
#pragma endregion WATL
|
#pragma endregion WATL
|
||||||
|
|
||||||
#pragma endregion Header
|
#pragma endregion Header
|
||||||
@@ -824,8 +824,7 @@ void mem_rewind(AllocatorInfo ainfo, AllocatorSP save_point) {
|
|||||||
finline
|
finline
|
||||||
AllocatorSP mem_save_point(AllocatorInfo ainfo) {
|
AllocatorSP mem_save_point(AllocatorInfo ainfo) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
AllocatorProc_Out out;
|
AllocatorProc_Out out; ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
|
||||||
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
|
|
||||||
return out.save_point;
|
return out.save_point;
|
||||||
}
|
}
|
||||||
finline
|
finline
|
||||||
@@ -838,8 +837,7 @@ Slice_Mem mem__alloc(AllocatorInfo ainfo, U8 size, Opts_mem_alloc*R_ opts) {
|
|||||||
.requested_size = size,
|
.requested_size = size,
|
||||||
.alignment = opts->alignment,
|
.alignment = opts->alignment,
|
||||||
};
|
};
|
||||||
AllocatorProc_Out out;
|
AllocatorProc_Out out; ainfo.proc(in, & out);
|
||||||
ainfo.proc(in, & out);
|
|
||||||
return out.allocation;
|
return out.allocation;
|
||||||
}
|
}
|
||||||
finline
|
finline
|
||||||
@@ -853,8 +851,7 @@ Slice_Mem mem__grow(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_grow*R
|
|||||||
.alignment = opts->alignment,
|
.alignment = opts->alignment,
|
||||||
.old_allocation = mem
|
.old_allocation = mem
|
||||||
};
|
};
|
||||||
AllocatorProc_Out out;
|
AllocatorProc_Out out; ainfo.proc(in, & out);
|
||||||
ainfo.proc(in, & out);
|
|
||||||
return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
||||||
}
|
}
|
||||||
finline
|
finline
|
||||||
@@ -868,8 +865,7 @@ Slice_Mem mem__resize(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_resi
|
|||||||
.alignment = opts->alignment,
|
.alignment = opts->alignment,
|
||||||
.old_allocation = mem,
|
.old_allocation = mem,
|
||||||
};
|
};
|
||||||
AllocatorProc_Out out;
|
AllocatorProc_Out out; ainfo.proc(in, & out);
|
||||||
ainfo.proc(in, & out);
|
|
||||||
return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
return (Slice_Mem){ out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
||||||
}
|
}
|
||||||
finline
|
finline
|
||||||
@@ -883,8 +879,7 @@ Slice_Mem mem__shrink(AllocatorInfo ainfo, Slice_Mem mem, U8 size, Opts_mem_shri
|
|||||||
.alignment = opts->alignment,
|
.alignment = opts->alignment,
|
||||||
.old_allocation = mem
|
.old_allocation = mem
|
||||||
};
|
};
|
||||||
AllocatorProc_Out out;
|
AllocatorProc_Out out; ainfo.proc(in, & out);
|
||||||
ainfo.proc(in, & out);
|
|
||||||
return out.allocation;
|
return out.allocation;
|
||||||
}
|
}
|
||||||
#pragma endregion Allocator Interface
|
#pragma endregion Allocator Interface
|
||||||
@@ -898,7 +893,7 @@ void farena_init(FArena_R arena, Slice_Mem mem) {
|
|||||||
arena->used = 0;
|
arena->used = 0;
|
||||||
}
|
}
|
||||||
finline FArena farena_make(Slice_Mem mem) { FArena a; farena_init(& a, mem); return a; }
|
finline FArena farena_make(Slice_Mem mem) { FArena a; farena_init(& a, mem); return a; }
|
||||||
inline
|
internal inline
|
||||||
Slice_Mem farena__push(FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts) {
|
Slice_Mem farena__push(FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_ opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
if (amount == 0) { return (Slice_Mem){}; }
|
if (amount == 0) { return (Slice_Mem){}; }
|
||||||
@@ -909,7 +904,7 @@ Slice_Mem farena__push(FArena_R arena, U8 amount, U8 type_width, Opts_farena*R_
|
|||||||
arena->used += to_commit;
|
arena->used += to_commit;
|
||||||
return (Slice_Mem){ptr, desired};
|
return (Slice_Mem){ptr, desired};
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Mem farena__grow(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
|
Slice_Mem farena__grow(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
|
||||||
// Check if the allocation is at the end of the arena
|
// Check if the allocation is at the end of the arena
|
||||||
U8 alloc_end = old_allocation.ptr + old_allocation.len;
|
U8 alloc_end = old_allocation.ptr + old_allocation.len;
|
||||||
@@ -927,11 +922,10 @@ Slice_Mem farena__grow(FArena_R arena, Slice_Mem old_allocation, U8 requested_si
|
|||||||
return (Slice_Mem){0};
|
return (Slice_Mem){0};
|
||||||
}
|
}
|
||||||
arena->used += aligned_grow;
|
arena->used += aligned_grow;
|
||||||
Slice_Mem result = (Slice_Mem){ old_allocation.ptr, aligned_grow + requested_size };
|
|
||||||
mem_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(U8, should_zero));
|
mem_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(U8, should_zero));
|
||||||
return result;
|
return (Slice_Mem){ old_allocation.ptr, aligned_grow + requested_size };
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Mem farena__shrink(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment)
|
Slice_Mem farena__shrink(FArena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment)
|
||||||
{
|
{
|
||||||
// Check if the allocation is at the end of the arena
|
// Check if the allocation is at the end of the arena
|
||||||
@@ -957,6 +951,7 @@ finline
|
|||||||
AllocatorSP farena_save (FArena arena) {
|
AllocatorSP farena_save (FArena arena) {
|
||||||
return (AllocatorSP){ .type_sig = & farena_allocator_proc, .slot = arena.used };
|
return (AllocatorSP){ .type_sig = & farena_allocator_proc, .slot = arena.used };
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
|
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
|
||||||
{
|
{
|
||||||
assert(out != nullptr);
|
assert(out != nullptr);
|
||||||
@@ -1057,7 +1052,7 @@ typedef def_struct(OS_Windows_State) { OS_SystemInfo system_info; };
|
|||||||
global OS_Windows_State os__windows_info;
|
global OS_Windows_State os__windows_info;
|
||||||
|
|
||||||
finline OS_SystemInfo* os_system_info(void) { return & os__windows_info.system_info; }
|
finline OS_SystemInfo* os_system_info(void) { return & os__windows_info.system_info; }
|
||||||
inline
|
internal inline
|
||||||
void os__enable_large_pages(void) {
|
void os__enable_large_pages(void) {
|
||||||
MS_HANDLE token;
|
MS_HANDLE token;
|
||||||
if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
|
if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
|
||||||
@@ -1074,7 +1069,7 @@ void os__enable_large_pages(void) {
|
|||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void os_init(void) {
|
void os_init(void) {
|
||||||
os__enable_large_pages();
|
os__enable_large_pages();
|
||||||
OS_SystemInfo*R_ info = & os__windows_info.system_info;
|
OS_SystemInfo*R_ info = & os__windows_info.system_info;
|
||||||
@@ -1096,12 +1091,12 @@ finline B4 os__vmem_commit(U8 vm, U8 size, Opts_vmem*R_ opts) {
|
|||||||
B4 result = (VirtualAlloc(cast(MS_LPVOID, vm), size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
|
B4 result = (VirtualAlloc(cast(MS_LPVOID, vm), size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline void os_vmem_release(U8 vm, U8 size) { VirtualFree(cast(MS_LPVOID, vm), 0, MS_MEM_RESERVE); }
|
internal inline void os_vmem_release(U8 vm, U8 size) { VirtualFree(cast(MS_LPVOID, vm), 0, MS_MEM_RESERVE); }
|
||||||
#pragma endregion OS
|
#pragma endregion OS
|
||||||
|
|
||||||
#pragma region VArena (Virutal Address Space Arena)
|
#pragma region VArena (Virutal Address Space Arena)
|
||||||
finline U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
|
finline U8 varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
|
||||||
inline
|
internal inline
|
||||||
VArena* varena__make(Opts_varena_make*R_ opts) {
|
VArena* varena__make(Opts_varena_make*R_ opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
|
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
|
||||||
@@ -1123,7 +1118,7 @@ VArena* varena__make(Opts_varena_make*R_ opts) {
|
|||||||
};
|
};
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Mem varena__push(VArena_R vm, U8 amount, U8 type_width, Opts_varena*R_ opts) {
|
Slice_Mem varena__push(VArena_R vm, U8 amount, U8 type_width, Opts_varena*R_ opts) {
|
||||||
assert(vm != nullptr);
|
assert(vm != nullptr);
|
||||||
assert(amount != 0);
|
assert(amount != 0);
|
||||||
@@ -1146,11 +1141,11 @@ Slice_Mem varena__push(VArena_R vm, U8 amount, U8 type_width, Opts_varena*R_ opt
|
|||||||
vm->committed += next_commit_size;
|
vm->committed += next_commit_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vm->commit_used = to_be_used;
|
|
||||||
U8 current_offset = vm->reserve_start + vm->commit_used;
|
U8 current_offset = vm->reserve_start + vm->commit_used;
|
||||||
|
vm->commit_used = to_be_used;
|
||||||
return (Slice_Mem){.ptr = current_offset, .len = requested_size};
|
return (Slice_Mem){.ptr = current_offset, .len = requested_size};
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
|
Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
|
||||||
U8 grow_amount = requested_size - old_allocation.len;
|
U8 grow_amount = requested_size - old_allocation.len;
|
||||||
if (grow_amount == 0) { return old_allocation; } // Growing when not the last allocation not allowed
|
if (grow_amount == 0) { return old_allocation; } // Growing when not the last allocation not allowed
|
||||||
@@ -1160,7 +1155,7 @@ Slice_Mem varena__grow(VArena_R vm, Slice_Mem old_allocation, U8 requested_size,
|
|||||||
return (Slice_Mem){ old_allocation.ptr, old_allocation.len + allocation.len };
|
return (Slice_Mem){ old_allocation.ptr, old_allocation.len + allocation.len };
|
||||||
}
|
}
|
||||||
finline void varena_release(VArena_R arena) { os_vmem_release(u8_(arena), arena->reserve); }
|
finline void varena_release(VArena_R arena) { os_vmem_release(u8_(arena), arena->reserve); }
|
||||||
inline
|
internal inline
|
||||||
Slice_Mem varena__shrink(VArena_R vm, Slice_Mem old_allocation, U8 requested_size) {
|
Slice_Mem varena__shrink(VArena_R vm, Slice_Mem old_allocation, U8 requested_size) {
|
||||||
U8 shrink_amount = old_allocation.len - requested_size;
|
U8 shrink_amount = old_allocation.len - requested_size;
|
||||||
if (lt_s(shrink_amount, 0)) { return old_allocation; }
|
if (lt_s(shrink_amount, 0)) { return old_allocation; }
|
||||||
@@ -1175,6 +1170,7 @@ void varena_rewind(VArena_R vm, AllocatorSP sp) {
|
|||||||
vm->commit_used = max(sp.slot, sizeof(VArena));
|
vm->commit_used = max(sp.slot, sizeof(VArena));
|
||||||
}
|
}
|
||||||
finline AllocatorSP varena_save(VArena_R vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
finline AllocatorSP varena_save(VArena_R vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
||||||
|
internal
|
||||||
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||||
{
|
{
|
||||||
VArena_R vm = cast(VArena_R, in.data);
|
VArena_R vm = cast(VArena_R, in.data);
|
||||||
@@ -1218,7 +1214,7 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
|
|
||||||
#pragma region Arena (Chained Arena)
|
#pragma region Arena (Chained Arena)
|
||||||
finline U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); }
|
finline U8 arena_header_size(void) { return align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT); }
|
||||||
inline
|
internal inline
|
||||||
Arena* arena__make(Opts_arena_make*R_ opts) {
|
Arena* arena__make(Opts_arena_make*R_ opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
U8 header_size = arena_header_size();
|
U8 header_size = arena_header_size();
|
||||||
@@ -1233,6 +1229,7 @@ Arena* arena__make(Opts_arena_make*R_ opts) {
|
|||||||
};
|
};
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
Slice_Mem arena__push(Arena_R arena, U8 amount, U8 type_width, Opts_arena* opts) {
|
Slice_Mem arena__push(Arena_R arena, U8 amount, U8 type_width, Opts_arena* opts) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -1264,6 +1261,45 @@ Slice_Mem arena__push(Arena_R arena, U8 amount, U8 type_width, Opts_arena* opts)
|
|||||||
active->pos = pos_pst;
|
active->pos = pos_pst;
|
||||||
return vresult;
|
return vresult;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
|
Slice_Mem arena__grow(Arena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment, B4 should_zero) {
|
||||||
|
Arena_R active = arena->current;
|
||||||
|
U8 alloc_end = old_allocation.ptr + old_allocation.len + requested_size;
|
||||||
|
U8 arena_end = u8_(active) + active->pos;
|
||||||
|
if (alloc_end == arena_end)
|
||||||
|
{
|
||||||
|
U8 grow_amount = requested_size - old_allocation.len;
|
||||||
|
U8 aligned_grow = align_pow2(grow_amount, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
if (active->pos + aligned_grow <= active->backing->reserve) {
|
||||||
|
Slice_Mem vresult = varena_push_mem(active->backing, aligned_grow, .alignment = alignment);
|
||||||
|
if (vresult.ptr != null) {
|
||||||
|
active->pos += aligned_grow;
|
||||||
|
mem_zero(old_allocation.ptr + old_allocation.len, aligned_grow * (U8)should_zero);
|
||||||
|
return (Slice_Mem){old_allocation.ptr, aligned_grow + old_allocation.len};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wnrvo"
|
||||||
|
Slice_Mem new_alloc = arena__push(arena, requested_size, 1, &(Opts_arena){.alignment = alignment});
|
||||||
|
if (new_alloc.ptr == null) { return (Slice_Mem){0}; }
|
||||||
|
mem_copy(new_alloc.ptr, old_allocation.ptr, old_allocation.len);
|
||||||
|
mem_zero(new_alloc.ptr + old_allocation.len, (new_alloc.len - old_allocation.len) * (U8)should_zero);
|
||||||
|
return new_alloc;
|
||||||
|
#pragma diagnostic pop
|
||||||
|
}
|
||||||
|
internal inline
|
||||||
|
Slice_Mem arena__shrink(Arena_R arena, Slice_Mem old_allocation, U8 requested_size, U8 alignment) {
|
||||||
|
Arena_R active = arena->current;
|
||||||
|
U8 alloc_end = old_allocation.ptr + old_allocation.len;
|
||||||
|
U8 arena_end = u8_(active) + active->pos;
|
||||||
|
if (alloc_end != arena_end) { return (Slice_Mem){old_allocation.ptr, requested_size}; }
|
||||||
|
U8 aligned_original = align_pow2(old_allocation.len, MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
U8 aligned_new = align_pow2(requested_size, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
U8 pos_reduction = aligned_original - aligned_new;
|
||||||
|
active->pos -= pos_reduction;
|
||||||
|
return varena__shrink(active->backing, old_allocation, requested_size);
|
||||||
|
}
|
||||||
finline
|
finline
|
||||||
void arena_release(Arena_R arena) {
|
void arena_release(Arena_R arena) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
@@ -1275,6 +1311,7 @@ void arena_release(Arena_R arena) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
finline void arena_reset(Arena_R arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); }
|
finline void arena_reset(Arena_R arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); }
|
||||||
|
internal inline
|
||||||
void arena_rewind(Arena_R arena, AllocatorSP save_point) {
|
void arena_rewind(Arena_R arena, AllocatorSP save_point) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
assert(save_point.type_sig == arena_allocator_proc);
|
assert(save_point.type_sig == arena_allocator_proc);
|
||||||
@@ -1291,6 +1328,7 @@ void arena_rewind(Arena_R arena, AllocatorSP save_point) {
|
|||||||
varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos + size_of(VArena)});
|
varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos + size_of(VArena)});
|
||||||
}
|
}
|
||||||
finline AllocatorSP arena_save(Arena_R arena) { return (AllocatorSP){arena_allocator_proc, arena->base_pos + arena->current->pos}; }
|
finline AllocatorSP arena_save(Arena_R arena) { return (AllocatorSP){arena_allocator_proc, arena->base_pos + arena->current->pos}; }
|
||||||
|
internal
|
||||||
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
|
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
|
||||||
{
|
{
|
||||||
assert(out != nullptr);
|
assert(out != nullptr);
|
||||||
@@ -1308,53 +1346,11 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
|
|||||||
case AllocatorOp_Reset: arena_reset(arena); break;
|
case AllocatorOp_Reset: arena_reset(arena); break;
|
||||||
|
|
||||||
case AllocatorOp_Grow:
|
case AllocatorOp_Grow:
|
||||||
case AllocatorOp_Grow_NoZero: {
|
case AllocatorOp_Grow_NoZero:
|
||||||
Arena_R active = arena->current;
|
out->allocation = arena__grow(arena, in.old_allocation, in.requested_size, in.alignment, in.op - AllocatorOp_Grow_NoZero);
|
||||||
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)
|
|
||||||
{
|
|
||||||
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};
|
|
||||||
mem_zero(in.old_allocation.ptr + in.old_allocation.len, grow_amount * in.op - AllocatorOp_Grow_NoZero);
|
|
||||||
break;
|
break;
|
||||||
}
|
case AllocatorOp_Shrink:
|
||||||
}
|
out->allocation = arena__shrink(arena, in.old_allocation, in.requested_size, in.alignment);
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
mem_copy(new_alloc.ptr, in.old_allocation.ptr, in.old_allocation.len);
|
|
||||||
mem_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);
|
|
||||||
out->allocation = (Slice_Mem){in.old_allocation.ptr, in.requested_size};
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break;
|
case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break;
|
||||||
@@ -1377,7 +1373,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out*R_ out)
|
|||||||
#pragma endregion Arena
|
#pragma endregion Arena
|
||||||
|
|
||||||
#pragma region Key Table Linear (KTL)
|
#pragma region Key Table Linear (KTL)
|
||||||
inline
|
finline
|
||||||
void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values) {
|
void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_Str8 values) {
|
||||||
assert(kt != nullptr);
|
assert(kt != nullptr);
|
||||||
if (values.len == 0) return;
|
if (values.len == 0) return;
|
||||||
@@ -1390,7 +1386,7 @@ void ktl_populate_slice_a2_str8(KTL_Str8*R_ kt, AllocatorInfo backing, Slice_A2_
|
|||||||
#pragma endregion KTL
|
#pragma endregion KTL
|
||||||
|
|
||||||
#pragma region Key Table 1-Layer Chained-Chunked_Cells (KT1CX)
|
#pragma region Key Table 1-Layer Chained-Chunked_Cells (KT1CX)
|
||||||
inline
|
internal inline
|
||||||
void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) {
|
void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) {
|
||||||
assert(result != nullptr);
|
assert(result != nullptr);
|
||||||
assert(info.backing_cells.proc != nullptr);
|
assert(info.backing_cells.proc != nullptr);
|
||||||
@@ -1402,7 +1398,7 @@ void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte*R_ result) {
|
|||||||
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
||||||
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
||||||
U8 cell_cursor = kt.table.ptr;
|
U8 cell_cursor = kt.table.ptr;
|
||||||
U8 table_len = kt.table.len * m.cell_size;
|
U8 table_len = kt.table.len * m.cell_size;
|
||||||
@@ -1425,9 +1421,9 @@ void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
|||||||
}
|
}
|
||||||
finline
|
finline
|
||||||
U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
|
U8 kt1cx_slot_id(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
|
||||||
U8 hash_index = key % kt.table.len;
|
return key % kt.table.len;
|
||||||
return hash_index;
|
|
||||||
}
|
}
|
||||||
|
inline
|
||||||
U8 kt1cx_get(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
|
U8 kt1cx_get(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
|
||||||
U8 hash_index = kt1cx_slot_id(kt, key, m);
|
U8 hash_index = kt1cx_slot_id(kt, key, m);
|
||||||
U8 cell_offset = hash_index * m.cell_size;
|
U8 cell_offset = hash_index * m.cell_size;
|
||||||
@@ -1454,7 +1450,7 @@ U8 kt1cx_get(KT1CX_Byte kt, U8 key, KT1CX_ByteMeta m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
internal
|
||||||
U8 kt1cx_set(KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
|
U8 kt1cx_set(KT1CX_Byte kt, U8 key, Slice_Mem value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
|
||||||
U8 hash_index = kt1cx_slot_id(kt, key, m);
|
U8 hash_index = kt1cx_slot_id(kt, key, m);
|
||||||
U8 cell_offset = hash_index * m.cell_size;
|
U8 cell_offset = hash_index * m.cell_size;
|
||||||
@@ -1504,6 +1500,7 @@ char* str8_to_cstr_capped(Str8 content, Slice_Mem mem) {
|
|||||||
u1_r(mem.ptr)[copy_len] = '\0';
|
u1_r(mem.ptr)[copy_len] = '\0';
|
||||||
return cast(char*, mem.ptr);
|
return cast(char*, mem.ptr);
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator)
|
Str8 str8_from_u32(AllocatorInfo ainfo, U4 num, U4 radix, U4 min_digits, U4 digit_group_separator)
|
||||||
{
|
{
|
||||||
Str8 result = {0};
|
Str8 result = {0};
|
||||||
@@ -1663,17 +1660,16 @@ finline
|
|||||||
Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries) {
|
Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8*R_ entries) {
|
||||||
KTL_Str8 kt; kt1l_populate_slice_a2_str8(& kt, tbl_backing, entries[0] );
|
KTL_Str8 kt; kt1l_populate_slice_a2_str8(& kt, tbl_backing, entries[0] );
|
||||||
U8 buf_size = kilo(64); Slice_Mem buffer = mem_alloc(buf_backing, buf_size);
|
U8 buf_size = kilo(64); Slice_Mem buffer = mem_alloc(buf_backing, buf_size);
|
||||||
Str8 result = str8__fmt_ktl(buf_backing, & buffer, kt, fmt_template);
|
return str8__fmt_ktl(buf_backing, & buffer, kt, fmt_template);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
finline
|
||||||
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries) {
|
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8*R_ entries) {
|
||||||
local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
||||||
local_persist B1 buf_mem[kilo(64)];
|
local_persist B1 buf_mem[kilo(64)];
|
||||||
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] );
|
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] );
|
||||||
Str8 result = str8__fmt_ktl((AllocatorInfo){0}, & slice_fmem(buf_mem), kt, fmt_template);
|
return str8__fmt_ktl((AllocatorInfo){0}, & slice_fmem(buf_mem), kt, fmt_template);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts) {
|
void str8cache__init(Str8Cache_R cache, Opts_str8cache_init*R_ opts) {
|
||||||
assert(cache != nullptr);
|
assert(cache != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -1761,8 +1757,7 @@ finline
|
|||||||
Str8 cache_str8(Str8Cache_R cache, Str8 str) {
|
Str8 cache_str8(Str8Cache_R cache, Str8 str) {
|
||||||
assert(cache != nullptr);
|
assert(cache != nullptr);
|
||||||
U8 key = 0; hash64_fnv1a(& key, slice_mem_s(str));
|
U8 key = 0; hash64_fnv1a(& key, slice_mem_s(str));
|
||||||
Str8_R result = str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve);
|
return str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve)[0];
|
||||||
return result[0];
|
|
||||||
}
|
}
|
||||||
finline
|
finline
|
||||||
void str8gen_init(Str8Gen_R gen, AllocatorInfo backing) {
|
void str8gen_init(Str8Gen_R gen, AllocatorInfo backing) {
|
||||||
@@ -1784,6 +1779,7 @@ void str8gen_append_str8(Str8Gen_R gen, Str8 str){
|
|||||||
gen->len += str.len;
|
gen->len += str.len;
|
||||||
gen->cap = result.len;
|
gen->cap = result.len;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ entries){
|
void str8gen__append_fmt(Str8Gen_R gen, Str8 fmt_template, Slice_A2_Str8*R_ entries){
|
||||||
local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
local_persist B1 tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
||||||
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] );
|
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), entries[0] );
|
||||||
@@ -1839,6 +1835,7 @@ FileOpInfo file__read_contents(Str8 path, Opts_read_file_contents*R_ opts) {
|
|||||||
FileOpInfo result = {0}; api_file_read_contents(& result, path, opts[0]);
|
FileOpInfo result = {0}; api_file_read_contents(& result, path, opts[0]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts)
|
void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_contents opts)
|
||||||
{
|
{
|
||||||
assert(result != nullptr);
|
assert(result != nullptr);
|
||||||
@@ -1898,6 +1895,7 @@ void api_file_read_contents(FileOpInfo_R result, Str8 path, Opts_read_file_conte
|
|||||||
result->content.len = u8_(file_size.QuadPart);
|
result->content.len = u8_(file_size.QuadPart);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
void file_write_str8(Str8 path, Str8 content)
|
void file_write_str8(Str8 path, Str8 content)
|
||||||
{
|
{
|
||||||
slice_assert(path);
|
slice_assert(path);
|
||||||
@@ -1972,6 +1970,7 @@ int printf_err(char const* fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) {
|
void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line, UTF8*R_ msg, ... ) {
|
||||||
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
||||||
if ( condition )
|
if ( condition )
|
||||||
@@ -1988,6 +1987,7 @@ void assert_handler( UTF8*R_ condition, UTF8*R_ file, UTF8*R_ function, S4 line,
|
|||||||
#pragma endregion Debug
|
#pragma endregion Debug
|
||||||
|
|
||||||
#pragma region WATL
|
#pragma region WATL
|
||||||
|
internal
|
||||||
void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts)
|
void api_watl_lex(WATL_LexInfo_R info, Str8 source, Opts_watl_lex*R_ opts)
|
||||||
{
|
{
|
||||||
if (source.len == 0) { return; }
|
if (source.len == 0) { return; }
|
||||||
@@ -2077,7 +2077,7 @@ slice_constraint_fail:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inline WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex*R_ opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; }
|
inline WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex*R_ opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; }
|
||||||
|
internal
|
||||||
void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts)
|
void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts)
|
||||||
{
|
{
|
||||||
if (tokens.len == 0) { return; }
|
if (tokens.len == 0) { return; }
|
||||||
@@ -2138,8 +2138,8 @@ void api_watl_parse(WATL_ParseInfo_R info, Slice_WATL_Tok tokens, Opts_watl_pars
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inline WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; }
|
finline WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse*R_ opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; }
|
||||||
|
internal
|
||||||
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||||
{
|
{
|
||||||
local_persist B1 scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena);
|
local_persist B1 scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena);
|
||||||
@@ -2159,8 +2159,7 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
|||||||
for slice_iter(line[0], chunk)
|
for slice_iter(line[0], chunk)
|
||||||
{
|
{
|
||||||
Str8 id;
|
Str8 id;
|
||||||
switch (chunk->ptr[0])
|
switch (chunk->ptr[0]) {
|
||||||
{
|
|
||||||
case WATL_Tok_Space: id = lit("Space"); break;
|
case WATL_Tok_Space: id = lit("Space"); break;
|
||||||
case WATL_Tok_Tab: id = lit("Tab"); break;
|
case WATL_Tok_Tab: id = lit("Tab"); break;
|
||||||
default: id = lit("Visible"); break;
|
default: id = lit("Visible"); break;
|
||||||
@@ -2180,7 +2179,6 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
|||||||
#pragma endregion WATL
|
#pragma endregion WATL
|
||||||
|
|
||||||
#pragma endregion Implementation
|
#pragma endregion Implementation
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
os_init();
|
os_init();
|
||||||
|
|||||||
459
C/watl.v0.msvc.c
459
C/watl.v0.msvc.c
@@ -58,11 +58,6 @@ enum { false = 0, true = 1, true_overflow, };
|
|||||||
#define offset_of(type, member) cast(SSIZE, & (((type*) 0)->member))
|
#define offset_of(type, member) cast(SSIZE, & (((type*) 0)->member))
|
||||||
#define size_of(data) cast(SSIZE, sizeof(data))
|
#define size_of(data) cast(SSIZE, sizeof(data))
|
||||||
|
|
||||||
// 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 ssize(value) cast(SSIZE, value)
|
||||||
|
|
||||||
#define kilo(n) (cast(SSIZE, n) << 10)
|
#define kilo(n) (cast(SSIZE, n) << 10)
|
||||||
@@ -104,12 +99,40 @@ typedef def_struct(Slice_Str8) { Str8* ptr; SSIZE len; };
|
|||||||
debug_trap(); \
|
debug_trap(); \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... );
|
internal void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... );
|
||||||
#endif
|
#endif
|
||||||
#pragma endregion Debug
|
#pragma endregion Debug
|
||||||
|
|
||||||
#pragma region Memory
|
#pragma region Memory
|
||||||
inline SSIZE align_pow2(SSIZE x, SSIZE b);
|
// #include <memory.h>
|
||||||
|
void* __cdecl memcpy (void* _Dst, void const* _Src, USIZE _Size);
|
||||||
|
void* __cdecl memmove(void* _Dst, void const* _Src, USIZE _Size);
|
||||||
|
void* __cdecl memset (void* _Dst, int _Val, USIZE _Size);
|
||||||
|
|
||||||
|
internal inline
|
||||||
|
SSIZE align_pow2(SSIZE x, SSIZE b) {
|
||||||
|
assert(b != 0);
|
||||||
|
assert((b & (b - 1)) == 0); // Check power of 2
|
||||||
|
return ((x + b - 1) & (~(b - 1)));
|
||||||
|
}
|
||||||
|
internal inline
|
||||||
|
void* mem_copy(void* restrict dest, void const* restrict src, USIZE length) {
|
||||||
|
if (dest == nullptr || src == nullptr) { return nullptr; }
|
||||||
|
memcpy(dest, src, length);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
internal inline
|
||||||
|
void* memory_copy_overlapping(void* restrict dest, void const* restrict src, USIZE length) {
|
||||||
|
if (dest == nullptr || src == nullptr) { return nullptr; }
|
||||||
|
memmove(dest, src, length);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
internal inline
|
||||||
|
B32 mem_zero(void* dest, USIZE length) {
|
||||||
|
if (dest == nullptr) return false;
|
||||||
|
memset((unsigned char*)dest, 0, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#define align_struct(type_width) ((SSIZE)(((type_width) + 7) / 8 * 8))
|
#define align_struct(type_width) ((SSIZE)(((type_width) + 7) / 8 * 8))
|
||||||
|
|
||||||
@@ -118,10 +141,6 @@ inline SSIZE align_pow2(SSIZE x, SSIZE b);
|
|||||||
assert(ssize(point) <= ssize(end)); \
|
assert(ssize(point) <= ssize(end)); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
void* memory_copy (void* restrict dest, void const* restrict src, USIZE length);
|
|
||||||
void* memory_copy_overlapping(void* restrict dest, void const* restrict src, USIZE length);
|
|
||||||
B32 memory_zero (void* dest, USIZE length);
|
|
||||||
|
|
||||||
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
|
#define check_nil(nil, p) ((p) == 0 || (p) == nil)
|
||||||
#define set_nil(nil, p) ((p) = nil)
|
#define set_nil(nil, p) ((p) = nil)
|
||||||
|
|
||||||
@@ -156,8 +175,14 @@ typedef def_Slice(Byte);
|
|||||||
#define slice_fmem(mem) ((Slice_Byte){ mem, size_of(mem) })
|
#define slice_fmem(mem) ((Slice_Byte){ mem, size_of(mem) })
|
||||||
#define slice_to_bytes(slice) ((Slice_Byte){cast(Byte*, (slice).ptr), (slice).len * size_of_slice_type(slice)})
|
#define slice_to_bytes(slice) ((Slice_Byte){cast(Byte*, (slice).ptr), (slice).len * size_of_slice_type(slice)})
|
||||||
|
|
||||||
void slice__copy(Slice_Byte dest, SSIZE dest_typewidth, Slice_Byte src, SSIZE src_typewidth);
|
internal inline void slice__zero(Slice_Byte mem, SSIZE typewidth) { slice_assert(mem); mem_zero(mem.ptr, mem.len); }
|
||||||
void slice__zero(Slice_Byte mem, SSIZE typewidth);
|
internal inline
|
||||||
|
void slice__copy(Slice_Byte dest, SSIZE dest_typewidth, Slice_Byte src, SSIZE src_typewidth) {
|
||||||
|
assert(dest.len >= src.len);
|
||||||
|
slice_assert(dest);
|
||||||
|
slice_assert(src);
|
||||||
|
mem_copy(dest.ptr, src.ptr, src.len);
|
||||||
|
}
|
||||||
#define slice_copy(dest, src) do { \
|
#define slice_copy(dest, src) do { \
|
||||||
static_assert(typeof_same(dest, src)); \
|
static_assert(typeof_same(dest, src)); \
|
||||||
slice__copy(slice_to_bytes(dest), size_of_slice_type(dest), slice_to_bytes(src), size_of_slice_type(src)); \
|
slice__copy(slice_to_bytes(dest), size_of_slice_type(dest), slice_to_bytes(src), size_of_slice_type(src)); \
|
||||||
@@ -271,20 +296,20 @@ static_assert(size_of(AllocatorProc_Out) == size_of(AllocatorQueryInfo));
|
|||||||
|
|
||||||
AllocatorQueryInfo allocator_query(AllocatorInfo ainfo);
|
AllocatorQueryInfo allocator_query(AllocatorInfo ainfo);
|
||||||
|
|
||||||
void mem_free (AllocatorInfo ainfo, Slice_Byte mem);
|
internal void mem_free (AllocatorInfo ainfo, Slice_Byte mem);
|
||||||
void mem_reset (AllocatorInfo ainfo);
|
internal void mem_reset (AllocatorInfo ainfo);
|
||||||
void mem_rewind (AllocatorInfo ainfo, AllocatorSP save_point);
|
internal void mem_rewind (AllocatorInfo ainfo, AllocatorSP save_point);
|
||||||
AllocatorSP mem_save_point(AllocatorInfo ainfo);
|
internal AllocatorSP mem_save_point(AllocatorInfo ainfo);
|
||||||
|
|
||||||
typedef def_struct(Opts_mem_alloc) { SSIZE alignment; B32 no_zero; byte_pad(4); };
|
typedef def_struct(Opts_mem_alloc) { SSIZE alignment; B32 no_zero; byte_pad(4); };
|
||||||
typedef def_struct(Opts_mem_grow) { SSIZE alignment; B32 no_zero; B32 give_actual; };
|
typedef def_struct(Opts_mem_grow) { SSIZE alignment; B32 no_zero; B32 give_actual; };
|
||||||
typedef def_struct(Opts_mem_shrink) { SSIZE alignment; };
|
typedef def_struct(Opts_mem_shrink) { SSIZE alignment; };
|
||||||
typedef def_struct(Opts_mem_resize) { SSIZE alignment; B32 no_zero; B32 give_actual; };
|
typedef def_struct(Opts_mem_resize) { SSIZE alignment; B32 no_zero; B32 give_actual; };
|
||||||
|
|
||||||
Slice_Byte mem__alloc (AllocatorInfo ainfo, SSIZE size, Opts_mem_alloc* opts);
|
internal Slice_Byte mem__alloc (AllocatorInfo ainfo, SSIZE size, Opts_mem_alloc* opts);
|
||||||
Slice_Byte mem__grow (AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_grow* opts);
|
internal Slice_Byte mem__grow (AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_grow* opts);
|
||||||
Slice_Byte mem__resize(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_resize* opts);
|
internal Slice_Byte mem__resize(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_resize* opts);
|
||||||
Slice_Byte mem__shrink(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_shrink* opts);
|
internal Slice_Byte mem__shrink(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_shrink* opts);
|
||||||
|
|
||||||
#define mem_alloc(ainfo, size, ...) mem__alloc (ainfo, size, opt_args(Opts_mem_alloc, __VA_ARGS__))
|
#define mem_alloc(ainfo, size, ...) mem__alloc (ainfo, size, opt_args(Opts_mem_alloc, __VA_ARGS__))
|
||||||
#define mem_grow(ainfo, mem, size, ...) mem__grow (ainfo, mem, size, opt_args(Opts_mem_grow, __VA_ARGS__))
|
#define mem_grow(ainfo, mem, size, ...) mem__grow (ainfo, mem, size, opt_args(Opts_mem_grow, __VA_ARGS__))
|
||||||
@@ -305,12 +330,12 @@ typedef def_struct(FArena) {
|
|||||||
SSIZE capacity;
|
SSIZE capacity;
|
||||||
SSIZE used;
|
SSIZE used;
|
||||||
};
|
};
|
||||||
FArena farena_make (Slice_Byte mem);
|
internal FArena farena_make (Slice_Byte mem);
|
||||||
void farena_init (FArena* arena, Slice_Byte byte);
|
internal void farena_init (FArena* arena, Slice_Byte byte);
|
||||||
Slice_Byte farena__push (FArena* arena, SSIZE amount, SSIZE type_width, Opts_farena* opts);
|
internal Slice_Byte farena__push (FArena* arena, SSIZE amount, SSIZE type_width, Opts_farena* opts);
|
||||||
void farena_reset (FArena* arena);
|
internal void farena_reset (FArena* arena);
|
||||||
void farena_rewind(FArena* arena, AllocatorSP save_point);
|
internal void farena_rewind(FArena* arena, AllocatorSP save_point);
|
||||||
AllocatorSP farena_save (FArena arena);
|
internal AllocatorSP farena_save (FArena arena);
|
||||||
|
|
||||||
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
||||||
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = & arena }
|
#define ainfo_farena(arena) (AllocatorInfo){ .proc = farena_allocator_proc, .data = & arena }
|
||||||
@@ -331,12 +356,12 @@ typedef def_struct(Opts_vmem) {
|
|||||||
B32 no_large_pages;
|
B32 no_large_pages;
|
||||||
byte_pad(4);
|
byte_pad(4);
|
||||||
};
|
};
|
||||||
void os_init(void);
|
internal void os_init (void);
|
||||||
OS_SystemInfo* os_system_info(void);
|
internal OS_SystemInfo* os_system_info(void);
|
||||||
|
|
||||||
inline B32 os__vmem_commit (void* vm, SSIZE size, Opts_vmem* opts);
|
internal inline B32 os__vmem_commit (void* vm, SSIZE size, Opts_vmem* opts);
|
||||||
inline Byte* os__vmem_reserve( SSIZE size, Opts_vmem* opts);
|
internal inline Byte* os__vmem_reserve( SSIZE size, Opts_vmem* opts);
|
||||||
inline void os_vmem_release (void* vm, SSIZE size);
|
internal inline void os_vmem_release (void* vm, SSIZE size);
|
||||||
|
|
||||||
#define os_vmem_reserve(size, ...) os__vmem_reserve( size, opt_args(Opts_vmem, __VA_ARGS__))
|
#define os_vmem_reserve(size, ...) os__vmem_reserve( size, opt_args(Opts_vmem, __VA_ARGS__))
|
||||||
#define os_vmem_commit(vm, size, ...) os__vmem_commit(vm, size, opt_args(Opts_vmem, __VA_ARGS__))
|
#define os_vmem_commit(vm, size, ...) os__vmem_commit(vm, size, opt_args(Opts_vmem, __VA_ARGS__))
|
||||||
@@ -363,17 +388,17 @@ typedef def_struct(Opts_varena_make) {
|
|||||||
VArenaFlags flags;
|
VArenaFlags flags;
|
||||||
byte_pad(4);
|
byte_pad(4);
|
||||||
};
|
};
|
||||||
VArena* varena__make(Opts_varena_make* opts);
|
internal VArena* varena__make(Opts_varena_make* opts);
|
||||||
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
#define varena_make(...) varena__make(opt_args(Opts_varena_make, __VA_ARGS__))
|
||||||
|
|
||||||
Slice_Byte varena__push (VArena* arena, SSIZE amount, SSIZE type_width, Opts_varena* opts);
|
internal Slice_Byte varena__push (VArena* arena, SSIZE amount, SSIZE type_width, Opts_varena* opts);
|
||||||
void varena_release(VArena* arena);
|
internal void varena_release(VArena* arena);
|
||||||
void varena_rewind (VArena* arena, AllocatorSP save_point);
|
internal void varena_rewind (VArena* arena, AllocatorSP save_point);
|
||||||
void varena_reset (VArena* arena);
|
internal void varena_reset (VArena* arena);
|
||||||
Slice_Byte varena__shrink(VArena* arena, Slice_Byte old_allocation, SSIZE requested_size);
|
internal Slice_Byte varena__shrink(VArena* arena, Slice_Byte old_allocation, SSIZE requested_size);
|
||||||
AllocatorSP varena_save (VArena* arena);
|
internal AllocatorSP varena_save (VArena* arena);
|
||||||
|
|
||||||
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
internal void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
||||||
#define ainfo_varena(varena) (AllocatorInfo) { .proc = & varena_allocator_proc, .data = varena }
|
#define ainfo_varena(varena) (AllocatorInfo) { .proc = & varena_allocator_proc, .data = varena }
|
||||||
|
|
||||||
#define varena_push(arena, type, ...) \
|
#define varena_push(arena, type, ...) \
|
||||||
@@ -399,14 +424,14 @@ typedef def_struct(Arena) {
|
|||||||
byte_pad(4);
|
byte_pad(4);
|
||||||
};
|
};
|
||||||
typedef Opts_varena_make Opts_arena_make;
|
typedef Opts_varena_make Opts_arena_make;
|
||||||
Arena* arena__make (Opts_arena_make* opts);
|
internal Arena* arena__make (Opts_arena_make* opts);
|
||||||
Slice_Byte arena__push (Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena* opts);
|
internal Slice_Byte arena__push (Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena* opts);
|
||||||
void arena_release(Arena* arena);
|
internal void arena_release(Arena* arena);
|
||||||
void arena_reset (Arena* arena);
|
internal void arena_reset (Arena* arena);
|
||||||
void arena_rewind (Arena* arena, AllocatorSP save_point);
|
internal void arena_rewind (Arena* arena, AllocatorSP save_point);
|
||||||
AllocatorSP arena_save (Arena* arena);
|
internal AllocatorSP arena_save (Arena* arena);
|
||||||
|
|
||||||
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
internal void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out);
|
||||||
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = arena }
|
#define ainfo_arena(arena) (AllocatorInfo){ .proc = & arena_allocator_proc, .data = arena }
|
||||||
|
|
||||||
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
#define arena_make(...) arena__make(opt_args(Opts_arena_make, __VA_ARGS__))
|
||||||
@@ -420,7 +445,7 @@ cast(type*, arena__push(arena, 1, size_of(type), opt_args(Opts_arena, lit(string
|
|||||||
|
|
||||||
#pragma region Hashing
|
#pragma region Hashing
|
||||||
typedef def_struct(Opts_hash64_fnv1a) { U64 seed; };
|
typedef def_struct(Opts_hash64_fnv1a) { U64 seed; };
|
||||||
inline
|
internal inline
|
||||||
void hash64__fnv1a(U64* hash, Slice_Byte data, Opts_hash64_fnv1a* opts) {
|
void hash64__fnv1a(U64* hash, Slice_Byte data, Opts_hash64_fnv1a* opts) {
|
||||||
local_persist U64 const default_seed = 0xcbf29ce484222325;
|
local_persist U64 const default_seed = 0xcbf29ce484222325;
|
||||||
assert(opts != nullptr); if (opts->seed == 0) opts->seed = default_seed;
|
assert(opts != nullptr); if (opts->seed == 0) opts->seed = default_seed;
|
||||||
@@ -451,13 +476,13 @@ typedef def_farray(Str8, 2);
|
|||||||
typedef def_Slice(A2_Str8);
|
typedef def_Slice(A2_Str8);
|
||||||
typedef def_KTL_Slot(Str8);
|
typedef def_KTL_Slot(Str8);
|
||||||
typedef def_KTL(Str8);
|
typedef def_KTL(Str8);
|
||||||
inline
|
internal inline
|
||||||
void ktl_populate_slice_a2_str8(KTL_Str8* kt, AllocatorInfo backing, Slice_A2_Str8 values) {
|
void ktl_populate_slice_a2_str8(KTL_Str8* kt, AllocatorInfo backing, Slice_A2_Str8 values) {
|
||||||
assert(kt != nullptr);
|
assert(kt != nullptr);
|
||||||
if (values.len == 0) return;
|
if (values.len == 0) return;
|
||||||
* kt = alloc_slice(backing, KTL_Slot_Str8, values.len);
|
* kt = alloc_slice(backing, KTL_Slot_Str8, values.len);
|
||||||
for span_iter(SSIZE, id, 0, <, values.len) {
|
for span_iter(SSIZE, id, 0, <, values.len) {
|
||||||
memory_copy(& kt->ptr[id.cursor].value, & values.ptr[id.cursor][1], size_of(Str8));
|
mem_copy(& kt->ptr[id.cursor].value, & values.ptr[id.cursor][1], size_of(Str8));
|
||||||
hash64_fnv1a(& kt->ptr[id.cursor].key, slice_to_bytes(values.ptr[id.cursor][0]));
|
hash64_fnv1a(& kt->ptr[id.cursor].key, slice_to_bytes(values.ptr[id.cursor][0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -515,11 +540,11 @@ typedef def_struct(KT1CX_Info) {
|
|||||||
AllocatorInfo backing_table;
|
AllocatorInfo backing_table;
|
||||||
AllocatorInfo backing_cells;
|
AllocatorInfo backing_cells;
|
||||||
};
|
};
|
||||||
void kt1cx_init (KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result);
|
internal void kt1cx_init (KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result);
|
||||||
void kt1cx_clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
|
internal void kt1cx_clear (KT1CX_Byte kt, KT1CX_ByteMeta meta);
|
||||||
U64 kt1cx_slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
internal U64 kt1cx_slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||||
Byte* kt1cx_get (KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
internal Byte* kt1cx_get (KT1CX_Byte kt, U64 key, KT1CX_ByteMeta meta);
|
||||||
Byte* kt1cx_set (KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
internal Byte* kt1cx_set (KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta meta);
|
||||||
|
|
||||||
#define kt1cx_assert(kt) do { \
|
#define kt1cx_assert(kt) do { \
|
||||||
slice_assert(kt.table); \
|
slice_assert(kt.table); \
|
||||||
@@ -528,20 +553,20 @@ Byte* kt1cx_set (KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo bac
|
|||||||
#pragma endregion KT1CX
|
#pragma endregion KT1CX
|
||||||
|
|
||||||
#pragma region String Operations
|
#pragma region String Operations
|
||||||
inline B32 char_is_upper(U8 c) { return('A' <= c && c <= 'Z'); }
|
internal inline B32 char_is_upper(U8 c) { return('A' <= c && c <= 'Z'); }
|
||||||
inline U8 char_to_lower(U8 c) { if (char_is_upper(c)) { c += ('a' - 'A'); } return(c); }
|
internal inline U8 char_to_lower(U8 c) { if (char_is_upper(c)) { c += ('a' - 'A'); } return(c); }
|
||||||
inline U8 integer_symbols(U8 value) {
|
internal inline U8 integer_symbols(U8 value) {
|
||||||
local_persist U8 lookup_table[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', }; return lookup_table[value];
|
local_persist U8 lookup_table[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', }; return lookup_table[value];
|
||||||
}
|
}
|
||||||
|
|
||||||
char* str8_to_cstr_capped(Str8 content, Slice_Byte mem);
|
internal char* str8_to_cstr_capped(Str8 content, Slice_Byte mem);
|
||||||
Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 digit_group_separator);
|
internal Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 digit_group_separator);
|
||||||
|
|
||||||
Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8* entries);
|
internal Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8* entries);
|
||||||
#define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \
|
#define str8_fmt_backed(tbl_backing, buf_backing, fmt_template, ...) \
|
||||||
str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
str8__fmt_backed(tbl_backing, buf_backing, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
|
|
||||||
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8* entries);
|
internal Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8* entries);
|
||||||
#define str8_fmt(fmt_template, ...) str8__fmt(lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
#define str8_fmt(fmt_template, ...) str8__fmt(lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
|
|
||||||
#define Str8Cache_CELL_DEPTH 4
|
#define Str8Cache_CELL_DEPTH 4
|
||||||
@@ -564,17 +589,17 @@ typedef def_struct(Opts_str8cache_init) {
|
|||||||
SSIZE cell_pool_size;
|
SSIZE cell_pool_size;
|
||||||
SSIZE table_size;
|
SSIZE table_size;
|
||||||
};
|
};
|
||||||
void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts);
|
internal void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts);
|
||||||
Str8Cache str8cache__make( Opts_str8cache_init* opts);
|
internal Str8Cache str8cache__make( Opts_str8cache_init* opts);
|
||||||
|
|
||||||
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__))
|
#define str8cache_init(cache, ...) str8cache__init(cache, opt_args(Opts_str8cache_init, __VA_ARGS__))
|
||||||
#define str8cache_make(...) str8cache__make( opt_args(Opts_str8cache_init, __VA_ARGS__))
|
#define str8cache_make(...) str8cache__make( opt_args(Opts_str8cache_init, __VA_ARGS__))
|
||||||
|
|
||||||
void str8cache_clear(KT1CX_Str8 kt);
|
internal void str8cache_clear(KT1CX_Str8 kt);
|
||||||
Str8* str8cache_get (KT1CX_Str8 kt, U64 key);
|
internal Str8* str8cache_get (KT1CX_Str8 kt, U64 key);
|
||||||
Str8* str8cache_set (KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells);
|
internal Str8* str8cache_set (KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells);
|
||||||
|
|
||||||
Str8 cache_str8(Str8Cache* cache, Str8 str);
|
internal Str8 cache_str8(Str8Cache* cache, Str8 str);
|
||||||
|
|
||||||
typedef def_struct(Str8Gen) {
|
typedef def_struct(Str8Gen) {
|
||||||
AllocatorInfo backing;
|
AllocatorInfo backing;
|
||||||
@@ -582,15 +607,15 @@ typedef def_struct(Str8Gen) {
|
|||||||
SSIZE len;
|
SSIZE len;
|
||||||
SSIZE cap;
|
SSIZE cap;
|
||||||
};
|
};
|
||||||
void str8gen_init(Str8Gen* gen, AllocatorInfo backing);
|
internal void str8gen_init(Str8Gen* gen, AllocatorInfo backing);
|
||||||
Str8Gen str8gen_make( AllocatorInfo backing);
|
internal Str8Gen str8gen_make( AllocatorInfo backing);
|
||||||
|
|
||||||
#define str8gen_slice_byte(gen) (Slice_Byte){ cast(Byte*, (gen).ptr), (gen).cap }
|
#define str8gen_slice_byte(gen) (Slice_Byte){ cast(Byte*, (gen).ptr), (gen).cap }
|
||||||
|
|
||||||
inline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){gen.ptr, gen.len}; }
|
internal inline Str8 str8_from_str8gen(Str8Gen gen) { return (Str8){gen.ptr, gen.len}; }
|
||||||
|
|
||||||
void str8gen_append_str8(Str8Gen* gen, Str8 str);
|
internal void str8gen_append_str8(Str8Gen* gen, Str8 str);
|
||||||
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* tokens);
|
internal void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* tokens);
|
||||||
|
|
||||||
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
#define str8gen_append_fmt(gen, fmt_template, ...) str8gen__append_fmt(gen, lit(fmt_template), slice_arg_from_array(A2_Str8, __VA_ARGS__))
|
||||||
#pragma endregion String Operations
|
#pragma endregion String Operations
|
||||||
@@ -604,10 +629,10 @@ typedef def_struct(Opts_file_read_contents) {
|
|||||||
B32 zero_backing;
|
B32 zero_backing;
|
||||||
byte_pad(4);
|
byte_pad(4);
|
||||||
};
|
};
|
||||||
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_contents opts);
|
internal void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_contents opts);
|
||||||
void file_write_str8 (Str8 path, Str8 content);
|
internal void file_write_str8 (Str8 path, Str8 content);
|
||||||
|
|
||||||
FileOpInfo file__read_contents(Str8 path, Opts_file_read_contents* opts);
|
internal FileOpInfo file__read_contents(Str8 path, Opts_file_read_contents* opts);
|
||||||
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_file_read_contents, __VA_ARGS__))
|
#define file_read_contents(path, ...) file__read_contents(path, opt_args(Opts_file_read_contents, __VA_ARGS__))
|
||||||
#pragma endregion File System
|
#pragma endregion File System
|
||||||
|
|
||||||
@@ -648,8 +673,8 @@ typedef def_struct(Opts_watl_lex) {
|
|||||||
B8 failon_slice_constraint_fail;
|
B8 failon_slice_constraint_fail;
|
||||||
byte_pad(5);
|
byte_pad(5);
|
||||||
};
|
};
|
||||||
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts);
|
internal void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts);
|
||||||
WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex* opts);
|
internal WATL_LexInfo watl__lex ( Str8 source, Opts_watl_lex* opts);
|
||||||
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
|
#define watl_lex(source, ...) watl__lex(source, opt_args(Opts_watl_lex, __VA_ARGS__))
|
||||||
|
|
||||||
typedef Str8 WATL_Node;
|
typedef Str8 WATL_Node;
|
||||||
@@ -680,87 +705,47 @@ typedef def_struct(Opts_watl_parse) {
|
|||||||
B32 failon_slice_constraint_fail;
|
B32 failon_slice_constraint_fail;
|
||||||
byte_pad(4);
|
byte_pad(4);
|
||||||
};
|
};
|
||||||
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
internal void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
||||||
WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
internal WATL_ParseInfo watl__parse ( Slice_WATL_Tok tokens, Opts_watl_parse* opts);
|
||||||
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
|
#define watl_parse(tokens, ...) watl__parse(tokens, opt_args(Opts_watl_parse, __VA_ARGS__))
|
||||||
|
|
||||||
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
|
internal Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines);
|
||||||
#pragma endregion WATL
|
#pragma endregion WATL
|
||||||
|
|
||||||
#pragma endregion Header
|
#pragma endregion Header
|
||||||
|
|
||||||
#pragma region Implementation
|
#pragma region Implementation
|
||||||
|
|
||||||
#pragma region Memory Operations
|
|
||||||
// #include <memory.h>
|
|
||||||
void* __cdecl memcpy (void* _Dst, void const* _Src, USIZE _Size);
|
|
||||||
void* __cdecl memmove(void* _Dst, void const* _Src, USIZE _Size);
|
|
||||||
void* __cdecl memset (void* _Dst, int _Val, USIZE _Size);
|
|
||||||
|
|
||||||
inline
|
|
||||||
SSIZE align_pow2(SSIZE x, SSIZE b) {
|
|
||||||
assert(b != 0);
|
|
||||||
assert((b & (b - 1)) == 0); // Check power of 2
|
|
||||||
return ((x + b - 1) & (~(b - 1)));
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
void* memory_copy(void* restrict dest, void const* restrict src, USIZE length) {
|
|
||||||
if (dest == nullptr || src == nullptr) { return nullptr; }
|
|
||||||
memcpy(dest, src, length);
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
void* memory_copy_overlapping(void* restrict dest, void const* restrict src, USIZE length) {
|
|
||||||
if (dest == nullptr || src == nullptr) { return nullptr; }
|
|
||||||
memmove(dest, src, length);
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
B32 memory_zero(void* dest, USIZE length) {
|
|
||||||
if (dest == nullptr) return false;
|
|
||||||
memset((unsigned char*)dest, 0, length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
inline void slice__zero(Slice_Byte mem, SSIZE typewidth) { slice_assert(mem); memory_zero(mem.ptr, mem.len); }
|
|
||||||
inline
|
|
||||||
void slice__copy(Slice_Byte dest, SSIZE dest_typewidth, Slice_Byte src, SSIZE src_typewidth) {
|
|
||||||
assert(dest.len >= src.len);
|
|
||||||
slice_assert(dest);
|
|
||||||
slice_assert(src);
|
|
||||||
memory_copy(dest.ptr, src.ptr, src.len);
|
|
||||||
}
|
|
||||||
#pragma endregion Memory Operations
|
|
||||||
|
|
||||||
#pragma region Allocator Interface
|
#pragma region Allocator Interface
|
||||||
inline
|
internal inline
|
||||||
AllocatorQueryInfo allocator_query(AllocatorInfo ainfo) {
|
AllocatorQueryInfo allocator_query(AllocatorInfo ainfo) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
AllocatorQueryInfo out; ainfo.proc((AllocatorProc_In){ .data = ainfo.data, .op = AllocatorOp_Query}, (AllocatorProc_Out*)& out);
|
AllocatorQueryInfo out; ainfo.proc((AllocatorProc_In){ .data = ainfo.data, .op = AllocatorOp_Query}, (AllocatorProc_Out*)& out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void mem_free(AllocatorInfo ainfo, Slice_Byte mem) {
|
void mem_free(AllocatorInfo ainfo, Slice_Byte mem) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_Free, .old_allocation = mem}, &(AllocatorProc_Out){});
|
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_Free, .old_allocation = mem}, &(AllocatorProc_Out){});
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void mem_reset(AllocatorInfo ainfo) {
|
void mem_reset(AllocatorInfo ainfo) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_Reset}, &(AllocatorProc_Out){});
|
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_Reset}, &(AllocatorProc_Out){});
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void mem_rewind(AllocatorInfo ainfo, AllocatorSP save_point) {
|
void mem_rewind(AllocatorInfo ainfo, AllocatorSP save_point) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_Rewind, .save_point = save_point}, &(AllocatorProc_Out){});
|
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_Rewind, .save_point = save_point}, &(AllocatorProc_Out){});
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
AllocatorSP mem_save_point(AllocatorInfo ainfo) {
|
AllocatorSP mem_save_point(AllocatorInfo ainfo) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
AllocatorProc_Out out;
|
AllocatorProc_Out out;
|
||||||
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
|
ainfo.proc((AllocatorProc_In){.data = ainfo.data, .op = AllocatorOp_SavePoint}, & out);
|
||||||
return out.save_point;
|
return out.save_point;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte mem__alloc(AllocatorInfo ainfo, SSIZE size, Opts_mem_alloc* opts) {
|
Slice_Byte mem__alloc(AllocatorInfo ainfo, SSIZE size, Opts_mem_alloc* opts) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -774,7 +759,7 @@ Slice_Byte mem__alloc(AllocatorInfo ainfo, SSIZE size, Opts_mem_alloc* opts) {
|
|||||||
ainfo.proc(in, & out);
|
ainfo.proc(in, & out);
|
||||||
return out.allocation;
|
return out.allocation;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte mem__grow(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_grow* opts) {
|
Slice_Byte mem__grow(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_grow* opts) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -789,7 +774,7 @@ Slice_Byte mem__grow(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_g
|
|||||||
ainfo.proc(in, & out);
|
ainfo.proc(in, & out);
|
||||||
return (Slice_Byte){out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
return (Slice_Byte){out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte mem__resize(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_resize* opts) {
|
Slice_Byte mem__resize(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_resize* opts) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -804,7 +789,7 @@ Slice_Byte mem__resize(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem
|
|||||||
ainfo.proc(in, & out);
|
ainfo.proc(in, & out);
|
||||||
return (Slice_Byte){out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
return (Slice_Byte){out.allocation.ptr, opts->give_actual ? out.allocation.len : in.requested_size };
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte mem__shrink(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_shrink* opts) {
|
Slice_Byte mem__shrink(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem_shrink* opts) {
|
||||||
assert(ainfo.proc != nullptr);
|
assert(ainfo.proc != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -822,15 +807,15 @@ Slice_Byte mem__shrink(AllocatorInfo ainfo, Slice_Byte mem, SSIZE size, Opts_mem
|
|||||||
#pragma endregion Allocator Interface
|
#pragma endregion Allocator Interface
|
||||||
|
|
||||||
#pragma region FArena (Fixed-Sized Arena)
|
#pragma region FArena (Fixed-Sized Arena)
|
||||||
inline
|
internal inline
|
||||||
void farena_init(FArena* arena, Slice_Byte mem) {
|
void farena_init(FArena* arena, Slice_Byte mem) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
arena->start = mem.ptr;
|
arena->start = mem.ptr;
|
||||||
arena->capacity = mem.len;
|
arena->capacity = mem.len;
|
||||||
arena->used = 0;
|
arena->used = 0;
|
||||||
}
|
}
|
||||||
inline FArena farena_make(Slice_Byte mem) { FArena a; farena_init(& a, mem); return a; }
|
internal inline FArena farena_make(Slice_Byte mem) { FArena a; farena_init(& a, mem); return a; }
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte farena__push(FArena* arena, SSIZE amount, SSIZE type_width, Opts_farena* opts) {
|
Slice_Byte farena__push(FArena* arena, SSIZE amount, SSIZE type_width, Opts_farena* opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
if (amount == 0) {
|
if (amount == 0) {
|
||||||
@@ -843,7 +828,7 @@ Slice_Byte farena__push(FArena* arena, SSIZE amount, SSIZE type_width, Opts_fare
|
|||||||
arena->used += to_commit;
|
arena->used += to_commit;
|
||||||
return (Slice_Byte){ptr, desired};
|
return (Slice_Byte){ptr, desired};
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte farena__grow(FArena* arena, SSIZE requested_size, Slice_Byte old_allocation, SSIZE alignment, B32 should_zero) {
|
Slice_Byte farena__grow(FArena* arena, SSIZE requested_size, Slice_Byte old_allocation, SSIZE alignment, B32 should_zero) {
|
||||||
// Check if the allocation is at the end of the arena
|
// Check if the allocation is at the end of the arena
|
||||||
Byte* alloc_end = old_allocation.ptr + old_allocation.len;
|
Byte* alloc_end = old_allocation.ptr + old_allocation.len;
|
||||||
@@ -861,10 +846,10 @@ Slice_Byte farena__grow(FArena* arena, SSIZE requested_size, Slice_Byte old_allo
|
|||||||
return (Slice_Byte){0};
|
return (Slice_Byte){0};
|
||||||
}
|
}
|
||||||
arena->used += aligned_grow;
|
arena->used += aligned_grow;
|
||||||
memory_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(SSIZE, should_zero));
|
mem_zero(old_allocation.ptr + old_allocation.len, grow_amount * cast(SSIZE, should_zero));
|
||||||
return (Slice_Byte){old_allocation.ptr, requested_size};
|
return (Slice_Byte){old_allocation.ptr, requested_size};
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte farena__shrink(FArena* arena, Slice_Byte old_allocation, SSIZE requested_size, SSIZE alignment) {
|
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
|
// Check if the allocation is at the end of the arena
|
||||||
Byte* alloc_end = old_allocation.ptr + old_allocation.len;
|
Byte* alloc_end = old_allocation.ptr + old_allocation.len;
|
||||||
@@ -880,17 +865,18 @@ Slice_Byte farena__shrink(FArena* arena, Slice_Byte old_allocation, SSIZE reques
|
|||||||
arena->used -= (aligned_original - aligned_new);
|
arena->used -= (aligned_original - aligned_new);
|
||||||
return (Slice_Byte){old_allocation.ptr, requested_size};
|
return (Slice_Byte){old_allocation.ptr, requested_size};
|
||||||
}
|
}
|
||||||
inline void farena_reset(FArena* arena) { arena->used = 0; }
|
internal inline void farena_reset(FArena* arena) { arena->used = 0; }
|
||||||
inline
|
internal inline
|
||||||
void farena_rewind(FArena* arena, AllocatorSP save_point) {
|
void farena_rewind(FArena* arena, AllocatorSP save_point) {
|
||||||
assert(save_point.type_sig == & farena_allocator_proc);
|
assert(save_point.type_sig == & farena_allocator_proc);
|
||||||
Byte* end = cast(Byte*, cast(SSIZE, arena->start) + arena->used); assert_bounds(save_point.slot, arena->start, end);
|
Byte* end = cast(Byte*, cast(SSIZE, arena->start) + arena->used); assert_bounds(save_point.slot, arena->start, end);
|
||||||
arena->used -= save_point.slot - cast(SSIZE, arena->start);
|
arena->used -= save_point.slot - cast(SSIZE, arena->start);
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
AllocatorSP farena_save (FArena arena) {
|
AllocatorSP farena_save (FArena arena) {
|
||||||
return (AllocatorSP){ .type_sig = & farena_allocator_proc, .slot = cast(SSIZE, arena.used) };
|
return (AllocatorSP){ .type_sig = & farena_allocator_proc, .slot = cast(SSIZE, arena.used) };
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||||
{
|
{
|
||||||
assert(out != nullptr);
|
assert(out != nullptr);
|
||||||
@@ -901,7 +887,7 @@ void farena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
case AllocatorOp_Alloc:
|
case AllocatorOp_Alloc:
|
||||||
case AllocatorOp_Alloc_NoZero:
|
case AllocatorOp_Alloc_NoZero:
|
||||||
out->allocation = farena__push(arena, in.requested_size, 1, &(Opts_farena){.type_name = lit("Byte"), .alignment = in.alignment});
|
out->allocation = farena__push(arena, in.requested_size, 1, &(Opts_farena){.type_name = lit("Byte"), .alignment = in.alignment});
|
||||||
memory_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op));
|
mem_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Free: break;
|
case AllocatorOp_Free: break;
|
||||||
@@ -992,11 +978,11 @@ typedef def_struct(OS_Windows_State) {
|
|||||||
};
|
};
|
||||||
global OS_Windows_State os__windows_info;
|
global OS_Windows_State os__windows_info;
|
||||||
|
|
||||||
inline
|
internal inline
|
||||||
OS_SystemInfo* os_system_info(void) {
|
OS_SystemInfo* os_system_info(void) {
|
||||||
return & os__windows_info.system_info;
|
return & os__windows_info.system_info;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void os__enable_large_pages(void) {
|
void os__enable_large_pages(void) {
|
||||||
MS_HANDLE token;
|
MS_HANDLE token;
|
||||||
if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
|
if (OpenProcessToken(GetCurrentProcess(), MS_TOKEN_ADJUST_PRIVILEGES | MS_TOKEN_QUERY, &token))
|
||||||
@@ -1013,14 +999,15 @@ void os__enable_large_pages(void) {
|
|||||||
CloseHandle(token);
|
CloseHandle(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void os_init(void) {
|
void os_init(void) {
|
||||||
os__enable_large_pages();
|
os__enable_large_pages();
|
||||||
OS_SystemInfo* info = & os__windows_info.system_info;
|
OS_SystemInfo* info = & os__windows_info.system_info;
|
||||||
info->target_page_size = (SSIZE)GetLargePageMinimum();
|
info->target_page_size = (SSIZE)GetLargePageMinimum();
|
||||||
}
|
}
|
||||||
// TODO(Ed): Large pages disabled for now... (not failing gracefully)
|
// TODO(Ed): Large pages disabled for now... (not failing gracefully)
|
||||||
inline Byte* os__vmem_reserve(SSIZE size, Opts_vmem* opts) {
|
internal inline
|
||||||
|
Byte* os__vmem_reserve(SSIZE size, Opts_vmem* opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
void* result = VirtualAlloc(cast(void*, opts->base_addr), size
|
void* result = VirtualAlloc(cast(void*, opts->base_addr), size
|
||||||
, MS_MEM_RESERVE
|
, MS_MEM_RESERVE
|
||||||
@@ -1029,18 +1016,18 @@ inline Byte* os__vmem_reserve(SSIZE size, Opts_vmem* opts) {
|
|||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline B32 os__vmem_commit(void* vm, SSIZE size, Opts_vmem* opts) {
|
internal inline B32 os__vmem_commit(void* vm, SSIZE size, Opts_vmem* opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
// if (opts->no_large_pages == false ) { return 1; }
|
// if (opts->no_large_pages == false ) { return 1; }
|
||||||
B32 result = (VirtualAlloc(vm, size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
|
B32 result = (VirtualAlloc(vm, size, MS_MEM_COMMIT, MS_PAGE_READWRITE) != 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline void os_vmem_release(void* vm, SSIZE size) { VirtualFree(vm, 0, MS_MEM_RESERVE); }
|
internal inline void os_vmem_release(void* vm, SSIZE size) { VirtualFree(vm, 0, MS_MEM_RESERVE); }
|
||||||
#pragma endregion OS
|
#pragma endregion OS
|
||||||
|
|
||||||
#pragma region VArena (Virutal Address Space Arena)
|
#pragma region VArena (Virutal Address Space Arena)
|
||||||
finline SSIZE varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
|
internal finline SSIZE varena_header_size(void) { return align_pow2(size_of(VArena), MEMORY_ALIGNMENT_DEFAULT); }
|
||||||
inline
|
internal inline
|
||||||
VArena* varena__make(Opts_varena_make* opts) {
|
VArena* varena__make(Opts_varena_make* opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
|
if (opts->reserve_size == 0) { opts->reserve_size = mega(64); }
|
||||||
@@ -1062,7 +1049,7 @@ VArena* varena__make(Opts_varena_make* opts) {
|
|||||||
};
|
};
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena* opts) {
|
Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena* opts) {
|
||||||
assert(vm != nullptr);
|
assert(vm != nullptr);
|
||||||
assert(amount != 0);
|
assert(amount != 0);
|
||||||
@@ -1085,21 +1072,21 @@ Slice_Byte varena__push(VArena* vm, SSIZE amount, SSIZE type_width, Opts_varena*
|
|||||||
vm->committed += next_commit_size;
|
vm->committed += next_commit_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vm->commit_used = to_be_used;
|
|
||||||
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||||
|
vm->commit_used = to_be_used;
|
||||||
return (Slice_Byte){.ptr = cast(Byte*, current_offset), .len = requested_size};
|
return (Slice_Byte){.ptr = cast(Byte*, current_offset), .len = requested_size};
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Slice_Byte varena__grow(VArena* vm, SSIZE requested_size, Slice_Byte old_allocation, SSIZE alignment, B32 should_zero) {
|
Slice_Byte varena__grow(VArena* vm, SSIZE requested_size, Slice_Byte old_allocation, SSIZE alignment, B32 should_zero) {
|
||||||
assert(vm != nullptr);
|
assert(vm != nullptr);
|
||||||
SSIZE grow_amount = requested_size - old_allocation.len;
|
SSIZE grow_amount = requested_size - old_allocation.len;
|
||||||
if (grow_amount == 0) { return old_allocation; } // Growing when not the last allocation not allowed
|
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));
|
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 allocation = varena_push_array(vm, Byte, grow_amount, alignment); assert(allocation.ptr != nullptr);
|
||||||
memory_zero(allocation.ptr, allocation.len * should_zero);
|
mem_zero(allocation.ptr, allocation.len * should_zero);
|
||||||
return (Slice_Byte){ old_allocation.ptr, old_allocation.len + allocation.len };
|
return (Slice_Byte){ old_allocation.ptr, old_allocation.len + allocation.len };
|
||||||
}
|
}
|
||||||
inline Slice_Byte varena__shrink(VArena* vm, Slice_Byte old_allocation, SSIZE requested_size) {
|
internal inline Slice_Byte varena__shrink(VArena* vm, Slice_Byte old_allocation, SSIZE requested_size) {
|
||||||
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
SSIZE current_offset = vm->reserve_start + vm->commit_used;
|
||||||
SSIZE shrink_amount = old_allocation.len - requested_size;
|
SSIZE shrink_amount = old_allocation.len - requested_size;
|
||||||
if (shrink_amount < 0) { return old_allocation; }
|
if (shrink_amount < 0) { return old_allocation; }
|
||||||
@@ -1107,14 +1094,15 @@ inline Slice_Byte varena__shrink(VArena* vm, Slice_Byte old_allocation, SSIZE re
|
|||||||
vm->commit_used -= shrink_amount;
|
vm->commit_used -= shrink_amount;
|
||||||
return (Slice_Byte){ old_allocation.ptr, requested_size };
|
return (Slice_Byte){ old_allocation.ptr, requested_size };
|
||||||
}
|
}
|
||||||
inline void varena_release(VArena* arena) { os_vmem_release(arena, arena->reserve); }
|
internal inline void varena_release(VArena* arena) { os_vmem_release(arena, arena->reserve); }
|
||||||
inline
|
internal inline
|
||||||
void varena_rewind(VArena* vm, AllocatorSP sp) {
|
void varena_rewind(VArena* vm, AllocatorSP sp) {
|
||||||
assert(vm != nullptr);
|
assert(vm != nullptr);
|
||||||
assert(sp.type_sig == & varena_allocator_proc);
|
assert(sp.type_sig == & varena_allocator_proc);
|
||||||
vm->commit_used = max(sp.slot, sizeof(VArena));
|
vm->commit_used = max(sp.slot, sizeof(VArena));
|
||||||
}
|
}
|
||||||
inline AllocatorSP varena_save(VArena* vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
internal inline AllocatorSP varena_save(VArena* vm) { return (AllocatorSP){varena_allocator_proc, vm->commit_used}; }
|
||||||
|
internal
|
||||||
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||||
{
|
{
|
||||||
VArena* vm = cast(VArena*, in.data);
|
VArena* vm = cast(VArena*, in.data);
|
||||||
@@ -1123,7 +1111,7 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
case AllocatorOp_Alloc:
|
case AllocatorOp_Alloc:
|
||||||
case AllocatorOp_Alloc_NoZero:
|
case AllocatorOp_Alloc_NoZero:
|
||||||
out->allocation = varena_push_array(vm, Byte, in.requested_size, .alignment = in.alignment);
|
out->allocation = varena_push_array(vm, Byte, in.requested_size, .alignment = in.alignment);
|
||||||
memory_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op));
|
mem_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Free: break;
|
case AllocatorOp_Free: break;
|
||||||
@@ -1157,7 +1145,7 @@ void varena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
#pragma endregion VArena
|
#pragma endregion VArena
|
||||||
|
|
||||||
#pragma region Arena (Chained Arena)
|
#pragma region Arena (Chained Arena)
|
||||||
inline
|
internal inline
|
||||||
Arena* arena__make(Opts_arena_make* opts) {
|
Arena* arena__make(Opts_arena_make* opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
SSIZE header_size = align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT);
|
SSIZE header_size = align_pow2(size_of(Arena), MEMORY_ALIGNMENT_DEFAULT);
|
||||||
@@ -1172,6 +1160,7 @@ Arena* arena__make(Opts_arena_make* opts) {
|
|||||||
};
|
};
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
Slice_Byte arena__push(Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena* opts) {
|
Slice_Byte arena__push(Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena* opts) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -1203,6 +1192,44 @@ Slice_Byte arena__push(Arena* arena, SSIZE amount, SSIZE type_width, Opts_arena*
|
|||||||
active->pos = pos_pst;
|
active->pos = pos_pst;
|
||||||
return vresult;
|
return vresult;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
|
Slice_Byte arena__grow(Arena* arena, Slice_Byte old_allocation, SSIZE requested_size, SSIZE alignment, B32 should_zero) {
|
||||||
|
Arena* active = arena->current;
|
||||||
|
Byte* alloc_end = old_allocation.ptr + old_allocation.len;
|
||||||
|
Byte* arena_end = cast(Byte*, active) + active->pos;
|
||||||
|
if (alloc_end == arena_end)
|
||||||
|
{
|
||||||
|
SSIZE grow_amount = requested_size - old_allocation.len;
|
||||||
|
SSIZE aligned_grow = align_pow2(grow_amount, alignment ? alignment : MEMORY_ALIGNMENT_DEFAULT);
|
||||||
|
if (active->pos + aligned_grow <= active->backing->reserve) {
|
||||||
|
Slice_Byte vresult = varena_push_array(active->backing, Byte, aligned_grow, .alignment = alignment);
|
||||||
|
if (vresult.ptr != nullptr) {
|
||||||
|
active->pos += aligned_grow;
|
||||||
|
mem_zero(old_allocation.ptr + old_allocation.len, grow_amount * (SSIZE)should_zero);
|
||||||
|
return (Slice_Byte){old_allocation.ptr, old_allocation.len + vresult.len};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Slice_Byte new_alloc = arena__push(arena, requested_size, 1, &(Opts_arena){.alignment = alignment});
|
||||||
|
if (new_alloc.ptr == nullptr) { return (Slice_Byte){0}; }
|
||||||
|
mem_copy(new_alloc.ptr, old_allocation.ptr, old_allocation.len);
|
||||||
|
mem_zero(new_alloc.ptr + old_allocation.len, (new_alloc.len - old_allocation.len) * (SSIZE)should_zero);
|
||||||
|
return new_alloc;
|
||||||
|
}
|
||||||
|
internal inline
|
||||||
|
Slice_Byte arena__shrink(Arena* arena, Slice_Byte old_allocation, SSIZE requested_size, SSIZE alignment) {
|
||||||
|
Arena* active = arena->current;
|
||||||
|
Byte* alloc_end = old_allocation.ptr + old_allocation.len;
|
||||||
|
Byte* arena_end = cast(Byte*, active) + active->pos;
|
||||||
|
if (alloc_end != arena_end) {
|
||||||
|
return (Slice_Byte){old_allocation.ptr, 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);
|
||||||
|
SSIZE pos_reduction = aligned_original - aligned_new;
|
||||||
|
active->pos -= pos_reduction;
|
||||||
|
return varena__shrink(active->backing, old_allocation, requested_size);
|
||||||
|
}
|
||||||
inline
|
inline
|
||||||
void arena_release(Arena* arena) {
|
void arena_release(Arena* arena) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
@@ -1213,7 +1240,8 @@ void arena_release(Arena* arena) {
|
|||||||
varena_release(curr->backing);
|
varena_release(curr->backing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void arena_reset(Arena* arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); }
|
internal inline void arena_reset(Arena* arena) { arena_rewind(arena, (AllocatorSP){.type_sig = arena_allocator_proc, .slot = 0}); }
|
||||||
|
internal inline
|
||||||
void arena_rewind(Arena* arena, AllocatorSP save_point) {
|
void arena_rewind(Arena* arena, AllocatorSP save_point) {
|
||||||
assert(arena != nullptr);
|
assert(arena != nullptr);
|
||||||
assert(save_point.type_sig == arena_allocator_proc);
|
assert(save_point.type_sig == arena_allocator_proc);
|
||||||
@@ -1230,7 +1258,8 @@ void arena_rewind(Arena* arena, AllocatorSP save_point) {
|
|||||||
curr->pos = new_pos;
|
curr->pos = new_pos;
|
||||||
varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos + sizeof(VArena)});
|
varena_rewind(curr->backing, (AllocatorSP){varena_allocator_proc, curr->pos + sizeof(VArena)});
|
||||||
}
|
}
|
||||||
inline AllocatorSP arena_save(Arena* arena) { return (AllocatorSP){arena_allocator_proc, arena->base_pos + arena->current->pos}; };
|
internal inline AllocatorSP arena_save(Arena* arena) { return (AllocatorSP){arena_allocator_proc, arena->base_pos + arena->current->pos}; };
|
||||||
|
internal
|
||||||
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
||||||
{
|
{
|
||||||
assert(out != nullptr);
|
assert(out != nullptr);
|
||||||
@@ -1241,59 +1270,18 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
case AllocatorOp_Alloc:
|
case AllocatorOp_Alloc:
|
||||||
case AllocatorOp_Alloc_NoZero:
|
case AllocatorOp_Alloc_NoZero:
|
||||||
out->allocation = arena_push_array(arena, Byte, in.requested_size, .alignment = in.alignment);
|
out->allocation = arena_push_array(arena, Byte, in.requested_size, .alignment = in.alignment);
|
||||||
memory_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op));
|
mem_zero(out->allocation.ptr, out->allocation.len * cast(SSIZE, in.op));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Free: break;
|
case AllocatorOp_Free: break;
|
||||||
case AllocatorOp_Reset: arena_reset(arena); break;
|
case AllocatorOp_Reset: arena_reset(arena); break;
|
||||||
|
|
||||||
case AllocatorOp_Grow:
|
case AllocatorOp_Grow:
|
||||||
case AllocatorOp_Grow_NoZero: {
|
case AllocatorOp_Grow_NoZero:
|
||||||
Arena* active = arena->current;
|
out->allocation = arena__grow(arena, in.old_allocation, in.requested_size, in.alignment, (cast(SSIZE, in.op) - AllocatorOp_Grow_NoZero));
|
||||||
Byte* alloc_end = in.old_allocation.ptr + in.old_allocation.len;
|
|
||||||
Byte* arena_end = cast(Byte*, active) + active->pos;
|
|
||||||
if (alloc_end == arena_end)
|
|
||||||
{
|
|
||||||
SSIZE grow_amount = in.requested_size - in.old_allocation.len;
|
|
||||||
SSIZE aligned_grow = align_pow2(grow_amount, in.alignment ? in.alignment : MEMORY_ALIGNMENT_DEFAULT);
|
|
||||||
if (active->pos + aligned_grow <= active->backing->reserve)
|
|
||||||
{
|
|
||||||
Slice_Byte vresult = varena_push_array(active->backing, Byte, aligned_grow, .alignment = in.alignment);
|
|
||||||
if (vresult.ptr != nullptr)
|
|
||||||
{
|
|
||||||
active->pos += 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));
|
|
||||||
break;
|
break;
|
||||||
}
|
case AllocatorOp_Shrink:
|
||||||
}
|
out->allocation = arena__shrink(arena, in.old_allocation, in.requested_size, in.alignment);
|
||||||
}
|
|
||||||
Slice_Byte new_alloc = arena__push(arena, in.requested_size, 1, &(Opts_arena){.alignment = in.alignment});
|
|
||||||
if (new_alloc.ptr == nullptr) {
|
|
||||||
out->allocation = (Slice_Byte){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) * (cast(SSIZE, in.op) - AllocatorOp_Grow_NoZero) );
|
|
||||||
out->allocation = new_alloc;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AllocatorOp_Shrink: {
|
|
||||||
Arena* active = arena->current;
|
|
||||||
Byte* alloc_end = in.old_allocation.ptr + in.old_allocation.len;
|
|
||||||
Byte* arena_end = cast(Byte*, active) + active->pos;
|
|
||||||
if (alloc_end != arena_end) {
|
|
||||||
out->allocation = (Slice_Byte){in.old_allocation.ptr, in.requested_size};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//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);
|
|
||||||
SSIZE pos_reduction = aligned_original - aligned_new;
|
|
||||||
active->pos -= pos_reduction;
|
|
||||||
out->allocation = varena__shrink(active->backing, in.old_allocation, in.requested_size);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break;
|
case AllocatorOp_Rewind: arena_rewind(arena, in.save_point); break;
|
||||||
@@ -1316,7 +1304,7 @@ void arena_allocator_proc(AllocatorProc_In in, AllocatorProc_Out* out)
|
|||||||
#pragma endregion Arena
|
#pragma endregion Arena
|
||||||
|
|
||||||
#pragma region Key Table 1-Layer Chained-Chunked_Cells (KT1CX)
|
#pragma region Key Table 1-Layer Chained-Chunked_Cells (KT1CX)
|
||||||
inline
|
internal inline
|
||||||
void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result) {
|
void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result) {
|
||||||
assert(result != nullptr);
|
assert(result != nullptr);
|
||||||
assert(info.backing_cells.proc != nullptr);
|
assert(info.backing_cells.proc != nullptr);
|
||||||
@@ -1328,6 +1316,7 @@ void kt1cx_init(KT1CX_Info info, KT1CX_InfoMeta m, KT1CX_Byte* result) {
|
|||||||
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
result->table = mem_alloc(info.backing_table, m.table_size * m.cell_size); slice_assert(result->table);
|
||||||
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
result->table.len = m.table_size; // Setting to the table number of elements instead of byte length.
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
||||||
Byte* cell_cursor = kt.table.ptr;
|
Byte* cell_cursor = kt.table.ptr;
|
||||||
SSIZE table_len = kt.table.len * m.cell_size;
|
SSIZE table_len = kt.table.len * m.cell_size;
|
||||||
@@ -1348,11 +1337,12 @@ void kt1cx_clear(KT1CX_Byte kt, KT1CX_ByteMeta m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
U64 kt1cx_slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
U64 kt1cx_slot_id(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
||||||
U64 hash_index = key % cast(U64, kt.table.len);
|
U64 hash_index = key % cast(U64, kt.table.len);
|
||||||
return hash_index;
|
return hash_index;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
Byte* kt1cx__get(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
Byte* kt1cx__get(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
||||||
U64 hash_index = kt1cx_slot_id(kt, key, m);
|
U64 hash_index = kt1cx_slot_id(kt, key, m);
|
||||||
SSIZE cell_offset = hash_index * m.cell_size;
|
SSIZE cell_offset = hash_index * m.cell_size;
|
||||||
@@ -1379,7 +1369,7 @@ Byte* kt1cx__get(KT1CX_Byte kt, U64 key, KT1CX_ByteMeta m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline
|
internal
|
||||||
Byte* kt1cx_set(KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
|
Byte* kt1cx_set(KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_cells, KT1CX_ByteMeta m) {
|
||||||
U64 hash_index = kt1cx_slot_id(kt, key, m);
|
U64 hash_index = kt1cx_slot_id(kt, key, m);
|
||||||
SSIZE cell_offset = hash_index * m.cell_size;
|
SSIZE cell_offset = hash_index * m.cell_size;
|
||||||
@@ -1421,13 +1411,14 @@ Byte* kt1cx_set(KT1CX_Byte kt, U64 key, Slice_Byte value, AllocatorInfo backing_
|
|||||||
#pragma endregion Key Table
|
#pragma endregion Key Table
|
||||||
|
|
||||||
#pragma region String Operations
|
#pragma region String Operations
|
||||||
inline
|
internal inline
|
||||||
char* str8_to_cstr_capped(Str8 content, Slice_Byte mem) {
|
char* str8_to_cstr_capped(Str8 content, Slice_Byte mem) {
|
||||||
SSIZE copy_len = min(content.len, mem.len - 1);
|
SSIZE copy_len = min(content.len, mem.len - 1);
|
||||||
memory_copy(mem.ptr, content.ptr, copy_len);
|
mem_copy(mem.ptr, content.ptr, copy_len);
|
||||||
mem.ptr[copy_len] = '\0';
|
mem.ptr[copy_len] = '\0';
|
||||||
return cast(char*, mem.ptr);
|
return cast(char*, mem.ptr);
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 digit_group_separator)
|
Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 digit_group_separator)
|
||||||
{
|
{
|
||||||
Str8 result = {0};
|
Str8 result = {0};
|
||||||
@@ -1503,6 +1494,7 @@ Str8 str8_from_u32(AllocatorInfo ainfo, U32 num, U32 radix, U8 min_digits, U8 di
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
Str8 str8__fmt_ktl(AllocatorInfo ainfo, Slice_Byte* _buffer, KTL_Str8 table, Str8 fmt_template)
|
Str8 str8__fmt_ktl(AllocatorInfo ainfo, Slice_Byte* _buffer, KTL_Str8 table, Str8 fmt_template)
|
||||||
{
|
{
|
||||||
assert(_buffer != nullptr);
|
assert(_buffer != nullptr);
|
||||||
@@ -1523,7 +1515,7 @@ Str8 str8__fmt_ktl(AllocatorInfo ainfo, Slice_Byte* _buffer, KTL_Str8 table, Str
|
|||||||
while (cursor_fmt[copy_offset] != cast(UTF8, '<') && (cursor_fmt + copy_offset) < slice_end(fmt_template)) {
|
while (cursor_fmt[copy_offset] != cast(UTF8, '<') && (cursor_fmt + copy_offset) < slice_end(fmt_template)) {
|
||||||
++ copy_offset;
|
++ copy_offset;
|
||||||
}
|
}
|
||||||
memory_copy(cursor_buffer, cursor_fmt, copy_offset);
|
mem_copy(cursor_buffer, cursor_fmt, copy_offset);
|
||||||
buffer_remaining -= copy_offset;
|
buffer_remaining -= copy_offset;
|
||||||
left_fmt -= copy_offset;
|
left_fmt -= copy_offset;
|
||||||
cursor_buffer += copy_offset;
|
cursor_buffer += copy_offset;
|
||||||
@@ -1560,7 +1552,7 @@ Str8 str8__fmt_ktl(AllocatorInfo ainfo, Slice_Byte* _buffer, KTL_Str8 table, Str
|
|||||||
buffer_remaining += potential_token_len;
|
buffer_remaining += potential_token_len;
|
||||||
}
|
}
|
||||||
assert((buffer_remaining - potential_token_len) > 0);
|
assert((buffer_remaining - potential_token_len) > 0);
|
||||||
memory_copy(cursor_buffer, value->ptr, value->len);
|
mem_copy(cursor_buffer, value->ptr, value->len);
|
||||||
// Sync cursor format to after the processed token
|
// Sync cursor format to after the processed token
|
||||||
cursor_buffer += value->len;
|
cursor_buffer += value->len;
|
||||||
buffer_remaining -= value->len;
|
buffer_remaining -= value->len;
|
||||||
@@ -1581,7 +1573,7 @@ Str8 str8__fmt_ktl(AllocatorInfo ainfo, Slice_Byte* _buffer, KTL_Str8 table, Str
|
|||||||
Str8 result = {buffer.ptr, buffer.len - buffer_remaining};
|
Str8 result = {buffer.ptr, buffer.len - buffer_remaining};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8* entries) {
|
Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8 fmt_template, Slice_A2_Str8* entries) {
|
||||||
KTL_Str8 kt; ktl_populate_slice_a2_str8(& kt, tbl_backing, *entries );
|
KTL_Str8 kt; ktl_populate_slice_a2_str8(& kt, tbl_backing, *entries );
|
||||||
SSIZE buf_size = kilo(64);
|
SSIZE buf_size = kilo(64);
|
||||||
@@ -1589,6 +1581,7 @@ Str8 str8__fmt_backed(AllocatorInfo tbl_backing, AllocatorInfo buf_backing, Str8
|
|||||||
Str8 result = str8__fmt_ktl(buf_backing, & buffer, kt, fmt_template);
|
Str8 result = str8__fmt_ktl(buf_backing, & buffer, kt, fmt_template);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8* entries) {
|
Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8* entries) {
|
||||||
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
||||||
local_persist Byte buf_mem[kilo(64)];
|
local_persist Byte buf_mem[kilo(64)];
|
||||||
@@ -1596,7 +1589,7 @@ Str8 str8__fmt(Str8 fmt_template, Slice_A2_Str8* entries) {
|
|||||||
Str8 result = str8__fmt_ktl((AllocatorInfo){0}, & slice_fmem(buf_mem), kt, fmt_template);
|
Str8 result = str8__fmt_ktl((AllocatorInfo){0}, & slice_fmem(buf_mem), kt, fmt_template);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts) {
|
void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts) {
|
||||||
assert(cache != nullptr);
|
assert(cache != nullptr);
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
@@ -1626,8 +1619,8 @@ void str8cache__init(Str8Cache* cache, Opts_str8cache_init* opts) {
|
|||||||
kt1cx_init(info, m, cast(KT1CX_Byte*, & cache->kt));
|
kt1cx_init(info, m, cast(KT1CX_Byte*, & cache->kt));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inline Str8Cache str8cache__make(Opts_str8cache_init* opts) { Str8Cache cache; str8cache__init(& cache, opts); return cache; }
|
internal inline Str8Cache str8cache__make(Opts_str8cache_init* opts) { Str8Cache cache; str8cache__init(& cache, opts); return cache; }
|
||||||
inline
|
internal inline
|
||||||
void str8cache_clear(KT1CX_Str8 kt) {
|
void str8cache_clear(KT1CX_Str8 kt) {
|
||||||
kt1cx_assert(kt);
|
kt1cx_assert(kt);
|
||||||
kt1cx_clear(kt1cx_byte(kt), (KT1CX_ByteMeta){
|
kt1cx_clear(kt1cx_byte(kt), (KT1CX_ByteMeta){
|
||||||
@@ -1640,7 +1633,7 @@ void str8cache_clear(KT1CX_Str8 kt) {
|
|||||||
.type_name = lit(stringify(Str8))
|
.type_name = lit(stringify(Str8))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Str8* str8cache_get(KT1CX_Str8 kt, U64 key) {
|
Str8* str8cache_get(KT1CX_Str8 kt, U64 key) {
|
||||||
kt1cx_assert(kt);
|
kt1cx_assert(kt);
|
||||||
Byte* result = kt1cx__get(kt1cx_byte(kt), key
|
Byte* result = kt1cx__get(kt1cx_byte(kt), key
|
||||||
@@ -1655,7 +1648,7 @@ Str8* str8cache_get(KT1CX_Str8 kt, U64 key) {
|
|||||||
});
|
});
|
||||||
return cast(Str8*, result);
|
return cast(Str8*, result);
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Str8* str8cache_set(KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells) {
|
Str8* str8cache_set(KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserve, AllocatorInfo backing_cells) {
|
||||||
kt1cx_assert(kt);
|
kt1cx_assert(kt);
|
||||||
slice_assert(value);
|
slice_assert(value);
|
||||||
@@ -1679,14 +1672,14 @@ Str8* str8cache_set(KT1CX_Str8 kt, U64 key, Str8 value, AllocatorInfo str_reserv
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
Str8 cache_str8(Str8Cache* cache, Str8 str) {
|
Str8 cache_str8(Str8Cache* cache, Str8 str) {
|
||||||
assert(cache != nullptr);
|
assert(cache != nullptr);
|
||||||
U64 key = 0; hash64_fnv1a(& key, slice_to_bytes(str));
|
U64 key = 0; hash64_fnv1a(& key, slice_to_bytes(str));
|
||||||
Str8* result = str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve);
|
Str8* result = str8cache_set(cache->kt, key, str, cache->str_reserve, cache->cell_reserve);
|
||||||
return * result;
|
return * result;
|
||||||
}
|
}
|
||||||
inline
|
internal inline
|
||||||
void str8gen_init(Str8Gen* gen, AllocatorInfo backing) {
|
void str8gen_init(Str8Gen* gen, AllocatorInfo backing) {
|
||||||
assert(gen != nullptr);
|
assert(gen != nullptr);
|
||||||
gen->backing = backing;
|
gen->backing = backing;
|
||||||
@@ -1695,8 +1688,8 @@ void str8gen_init(Str8Gen* gen, AllocatorInfo backing) {
|
|||||||
gen->len = 0;
|
gen->len = 0;
|
||||||
gen->cap = kilo(4);
|
gen->cap = kilo(4);
|
||||||
}
|
}
|
||||||
inline Str8Gen str8gen_make(AllocatorInfo backing) { Str8Gen gen; str8gen_init(& gen, backing); return gen; }
|
internal inline Str8Gen str8gen_make(AllocatorInfo backing) { Str8Gen gen; str8gen_init(& gen, backing); return gen; }
|
||||||
inline
|
internal inline
|
||||||
void str8gen_append_str8(Str8Gen* gen, Str8 str){
|
void str8gen_append_str8(Str8Gen* gen, Str8 str){
|
||||||
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), str.len + gen->len);
|
Slice_Byte result = mem_grow(gen->backing, str8gen_slice_byte(* gen), str.len + gen->len);
|
||||||
slice_assert(result);
|
slice_assert(result);
|
||||||
@@ -1706,6 +1699,7 @@ void str8gen_append_str8(Str8Gen* gen, Str8 str){
|
|||||||
gen->len += str.len;
|
gen->len += str.len;
|
||||||
gen->cap = result.len;
|
gen->cap = result.len;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries){
|
void str8gen__append_fmt(Str8Gen* gen, Str8 fmt_template, Slice_A2_Str8* entries){
|
||||||
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
local_persist Byte tbl_mem[kilo(32)]; FArena tbl_arena = farena_make(slice_fmem(tbl_mem));
|
||||||
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), *entries );
|
KTL_Str8 kt = {0}; ktl_populate_slice_a2_str8(& kt, ainfo_farena(tbl_arena), *entries );
|
||||||
@@ -1755,12 +1749,13 @@ _declspec(dllimport) MS_BOOL __stdcall WriteFile(
|
|||||||
__declspec(dllimport) MS_BOOL __stdcall GetFileSizeEx(MS_HANDLE hFile, MS_LARGE_INTEGER* lpFileSize);
|
__declspec(dllimport) MS_BOOL __stdcall GetFileSizeEx(MS_HANDLE hFile, MS_LARGE_INTEGER* lpFileSize);
|
||||||
__declspec(dllimport) MS_DWORD __stdcall GetLastError(void);
|
__declspec(dllimport) MS_DWORD __stdcall GetLastError(void);
|
||||||
|
|
||||||
inline
|
internal inline
|
||||||
FileOpInfo file__read_contents(Str8 path, Opts_file_read_contents* opts) {
|
FileOpInfo file__read_contents(Str8 path, Opts_file_read_contents* opts) {
|
||||||
assert(opts != nullptr);
|
assert(opts != nullptr);
|
||||||
FileOpInfo result = {0}; api_file_read_contents(& result, path, * opts);
|
FileOpInfo result = {0}; api_file_read_contents(& result, path, * opts);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
internal
|
||||||
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_contents opts)
|
void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_contents opts)
|
||||||
{
|
{
|
||||||
assert(result != nullptr);
|
assert(result != nullptr);
|
||||||
@@ -1820,6 +1815,7 @@ void api_file_read_contents(FileOpInfo* result, Str8 path, Opts_file_read_conten
|
|||||||
result->content.len = file_size.QuadPart;
|
result->content.len = file_size.QuadPart;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
void file_write_str8(Str8 path, Str8 content)
|
void file_write_str8(Str8 path, Str8 content)
|
||||||
{
|
{
|
||||||
slice_assert(path);
|
slice_assert(path);
|
||||||
@@ -1885,7 +1881,7 @@ int __cdecl __stdio_common_vfprintf_s(
|
|||||||
va_list _ArgList
|
va_list _ArgList
|
||||||
);
|
);
|
||||||
void __cdecl __va_start(va_list* , ...);
|
void __cdecl __va_start(va_list* , ...);
|
||||||
inline
|
internal inline
|
||||||
int printf_err(char const* fmt, ...) {
|
int printf_err(char const* fmt, ...) {
|
||||||
int result;
|
int result;
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -1894,6 +1890,7 @@ int printf_err(char const* fmt, ...) {
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
internal inline
|
||||||
void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... ) {
|
void assert_handler( char const* condition, char const* file, char const* function, S32 line, char const* msg, ... ) {
|
||||||
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
printf_err( "%s - %s:(%d): Assert Failure: ", file, function, line );
|
||||||
if ( condition )
|
if ( condition )
|
||||||
@@ -1910,6 +1907,7 @@ void assert_handler( char const* condition, char const* file, char const* functi
|
|||||||
#pragma endregion Debug
|
#pragma endregion Debug
|
||||||
|
|
||||||
#pragma region WATL
|
#pragma region WATL
|
||||||
|
internal
|
||||||
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
void api_watl_lex(WATL_LexInfo* info, Str8 source, Opts_watl_lex* opts)
|
||||||
{
|
{
|
||||||
if (source.len == 0) { return; }
|
if (source.len == 0) { return; }
|
||||||
@@ -1998,8 +1996,8 @@ slice_constraint_fail:
|
|||||||
assert(opts->failon_slice_constraint_fail == false);
|
assert(opts->failon_slice_constraint_fail == false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inline WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex* opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; }
|
internal inline WATL_LexInfo watl__lex(Str8 source, Opts_watl_lex* opts) { WATL_LexInfo info = {0}; api_watl_lex(& info, source, opts); return info; }
|
||||||
|
internal
|
||||||
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts)
|
void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse* opts)
|
||||||
{
|
{
|
||||||
if (tokens.len == 0) { return; }
|
if (tokens.len == 0) { return; }
|
||||||
@@ -2060,8 +2058,8 @@ void api_watl_parse(WATL_ParseInfo* info, Slice_WATL_Tok tokens, Opts_watl_parse
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inline WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse* opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; }
|
internal inline WATL_ParseInfo watl__parse(Slice_WATL_Tok tokens, Opts_watl_parse* opts) { WATL_ParseInfo info = {0}; api_watl_parse(& info, tokens, opts); return info; }
|
||||||
|
internal
|
||||||
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
||||||
{
|
{
|
||||||
local_persist Byte scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena);
|
local_persist Byte scratch[kilo(64)] = {0}; FArena sarena = farena_make(slice_fmem(scratch)); AllocatorInfo sinfo = ainfo_farena(sarena);
|
||||||
@@ -2081,8 +2079,7 @@ Str8 watl_dump_listing(AllocatorInfo buffer, Slice_WATL_Line lines)
|
|||||||
for slice_iter(* line, chunk)
|
for slice_iter(* line, chunk)
|
||||||
{
|
{
|
||||||
Str8 id;
|
Str8 id;
|
||||||
switch (* chunk->ptr)
|
switch (* chunk->ptr) {
|
||||||
{
|
|
||||||
case WATL_Tok_Space: id = lit("Space"); break;
|
case WATL_Tok_Space: id = lit("Space"); break;
|
||||||
case WATL_Tok_Tab: id = lit("Tab"); break;
|
case WATL_Tok_Tab: id = lit("Tab"); break;
|
||||||
default: id = lit("Visible"); break;
|
default: id = lit("Visible"); break;
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ $compiler_args += $flag_full_src_path
|
|||||||
# $compiler_args += $flag_optimize_speed_max
|
# $compiler_args += $flag_optimize_speed_max
|
||||||
# $compiler_args += $flag_optimize_fast
|
# $compiler_args += $flag_optimize_fast
|
||||||
# $compiler_args += $flag_optimize_size
|
# $compiler_args += $flag_optimize_size
|
||||||
# $compiler_args += $flag_optimize_intrinsics
|
$compiler_args += $flag_optimize_intrinsics
|
||||||
$compiler_args += $flag_no_optimization
|
# $compiler_args += $flag_no_optimization
|
||||||
|
|
||||||
# Debug setup
|
# Debug setup
|
||||||
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ $compiler_args += $flag_full_src_path
|
|||||||
# $compiler_args += $flag_optimize_speed_max
|
# $compiler_args += $flag_optimize_speed_max
|
||||||
# $compiler_args += $flag_optimize_fast
|
# $compiler_args += $flag_optimize_fast
|
||||||
# $compiler_args += $flag_optimize_size
|
# $compiler_args += $flag_optimize_size
|
||||||
# $compiler_args += $flag_optimize_intrinsics
|
$compiler_args += $flag_optimize_intrinsics
|
||||||
$compiler_args += $flag_no_optimization
|
# $compiler_args += $flag_no_optimization
|
||||||
|
|
||||||
# Debug setup
|
# Debug setup
|
||||||
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
||||||
|
|||||||
@@ -117,8 +117,8 @@ $compiler_args += $flag_full_src_path
|
|||||||
# $compiler_args += $flag_optimize_speed_max
|
# $compiler_args += $flag_optimize_speed_max
|
||||||
# $compiler_args += $flag_optimize_fast
|
# $compiler_args += $flag_optimize_fast
|
||||||
# $compiler_args += $flag_optimize_size
|
# $compiler_args += $flag_optimize_size
|
||||||
# $compiler_args += $flag_optimize_intrinsics
|
$compiler_args += $flag_optimize_intrinsics
|
||||||
$compiler_args += $flag_no_optimization
|
# $compiler_args += $flag_no_optimization
|
||||||
|
|
||||||
# Debug setup
|
# Debug setup
|
||||||
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
$compiler_args += ($flag_define + 'BUILD_DEBUG')
|
||||||
@@ -139,7 +139,10 @@ $compiler_args += $flag_compile, $unit
|
|||||||
$compiler_args | ForEach-Object { Write-Host $_ }
|
$compiler_args | ForEach-Object { Write-Host $_ }
|
||||||
|
|
||||||
# Compile the unit
|
# Compile the unit
|
||||||
|
$compilation_time = Measure-Command {
|
||||||
& $compiler $compiler_args
|
& $compiler $compiler_args
|
||||||
|
}
|
||||||
|
write-host "Compilation took $($compilation_time.TotalMilliseconds)ms"
|
||||||
write-host
|
write-host
|
||||||
|
|
||||||
$binary = join-path $path_build "$unit_name.exe"
|
$binary = join-path $path_build "$unit_name.exe"
|
||||||
@@ -168,8 +171,9 @@ if ($true) {
|
|||||||
# Diagnoistc print for the args
|
# Diagnoistc print for the args
|
||||||
$linker_args | ForEach-Object { Write-Host $_ }
|
$linker_args | ForEach-Object { Write-Host $_ }
|
||||||
|
|
||||||
& $linker $linker_args
|
$linking_time = Measure-Command { & $linker $linker_args }
|
||||||
# & $radlink $linker_args
|
# & $radlink $linker_args
|
||||||
|
write-host "Linking took $($linking_time.TotalMilliseconds)ms"
|
||||||
write-host
|
write-host
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user