// Just an idea I had so that we can start with a small arena and increase on an as-needed basis, // this way allocations are always extremely fast. // The full structure is 80B, and because we use bootstrapping, we only need a little extra memory for storing // the `next_arenas` pointers // DO NOT MERGE WITH `Arena`, we need fixed size arenas so that we can back // `ArenaArray`s. struct ExpandableArena { u8* current_point = nullptr; u8* memory_base = nullptr; u8* first_uncommitted_page = nullptr; u16 alignment = CPU_REGISTER_WIDTH_BYTES; Arena_Reserve reserve_size = Arena_Reserve::Size_64K; Arena_Flags flags = Arena_Flags::None; u32 initial_commit_page_count = ARENA_DEFAULT_COMMIT_PAGE_COUNT; // Note that this downcasts to Arena*, so can be initialized in the same way. Arena* current; Array next_arenas; #if BUILD_DEBUG string info; string file_path; string function_name; s32 line_number; #endif }; #if BUILD_DEBUG #define bootstrap_expandable_arena(_reserve_) \ bootstrap_expandable_arena_internal((_reserve_), (s32)ARENA_DEFAULT_COMMIT_PAGE_COUNT, __FILE__, __FUNCTION__, __LINE__) #else #define bootstrap_expandable_arena(_reserve_) \ bootstrap_expandable_arena_internal((_reserve_), (s32)ARENA_DEFAULT_COMMIT_PAGE_COUNT) #endif ExpandableArena* bootstrap_expandable_arena_internal (Arena_Reserve new_reserve=Arena_Reserve::Size_64K, s32 commit_page_count=ARENA_DEFAULT_COMMIT_PAGE_COUNT, string file_path="", string function_name="", s32 line_number=0); // ExpandableArena* bootstrap_expandable_arena_internal (Arena_Reserve starting_reserve=Arena_Reserve::Size_64K, s32 commit_page_count=8); void* expandable_arena_allocator_proc (Allocator_Mode mode, s64 requested_size, s64 old_size, void* old_memory, void* allocator_data); bool is_valid (ExpandableArena* arena); void* expandable_arena_alloc (ExpandableArena* arena_ex, s64 byte_count); u8* expandable_arena_start (ExpandableArena* arena_ex); Allocator allocator (ExpandableArena* arena_ex); void arena_reset_to (ExpandableArena* arena_ex, Arena* last_arena, u8* starting_point); void arena_reset (ExpandableArena* arena_ex, bool free_extra_pages); force_inline void arena_delete (ExpandableArena* arena_ex);