aboutsummaryrefslogtreecommitdiff
path: root/base/runtime
diff options
context:
space:
mode:
authorBarinzaya <barinzaya@gmail.com>2025-01-24 09:42:10 -0500
committerBarinzaya <barinzaya@gmail.com>2025-01-24 10:13:46 -0500
commit98b3a9eacd9b95a5db75fb001da0bfb0c7a18645 (patch)
treebe2371d06686194dee971955b8fe87791282aad9 /base/runtime
parent3a13c598e2efb46f12121bb532f8f3616d2cf482 (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.odin22
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