diff options
| author | Barinzaya <barinzaya@gmail.com> | 2025-01-24 09:42:10 -0500 |
|---|---|---|
| committer | Barinzaya <barinzaya@gmail.com> | 2025-01-24 10:13:46 -0500 |
| commit | 98b3a9eacd9b95a5db75fb001da0bfb0c7a18645 (patch) | |
| tree | be2371d06686194dee971955b8fe87791282aad9 /base/runtime | |
| parent | 3a13c598e2efb46f12121bb532f8f3616d2cf482 (diff) | |
Added support for growing in place to some arenas.
This affects `runtime.Arena` and `virtual.Arena`, but not currently
`mem.Arena`. These changes allow the last allocation that has been
made to be resized to a larger size by just extending their
allocation in-place, when there's sufficient room in the memory block to
do so.
Shrinking in place and re-using the rest of the allocation can be
supported using almost the same logic, but would require the memory to
be zeroed. Since this would add a additional cost that isn't currently
present, shrinking has not been changed.
Diffstat (limited to 'base/runtime')
| -rw-r--r-- | base/runtime/default_temp_allocator_arena.odin | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/base/runtime/default_temp_allocator_arena.odin b/base/runtime/default_temp_allocator_arena.odin index 878a2d070..6e2900411 100644 --- a/base/runtime/default_temp_allocator_arena.odin +++ b/base/runtime/default_temp_allocator_arena.odin @@ -210,10 +210,24 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode, case size == 0: err = .Mode_Not_Implemented return - case (uintptr(old_data) & uintptr(alignment-1) == 0) && size < old_size: - // shrink data in-place - data = old_data[:size] - return + case uintptr(old_data) & uintptr(alignment-1) == 0: + if size < old_size { + // shrink data in-place + data = old_data[:size] + return + } + + if block := arena.curr_block; block != nil { + start := uint(uintptr(old_memory)) - uint(uintptr(block.base)) + old_end := start + old_size + new_end := start + size + if start < old_end && old_end == block.used && new_end <= block.capacity { + // grow data in-place, adjusting next allocation + block.used = uint(new_end) + data = block.base[start:new_end] + return + } + } } new_memory := arena_alloc(arena, size, alignment, location) or_return |