diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-01-27 09:59:09 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-27 09:59:09 +0000 |
| commit | 2e64cf7ef5495055757cd736d9dd461bccde73bc (patch) | |
| tree | b6bc9dc493db98ad6492dc106f1bbbc8c4f4a9b6 | |
| parent | 6572a52a84016ad9c8d0a7906ca06686a76ce5f7 (diff) | |
| parent | 98b3a9eacd9b95a5db75fb001da0bfb0c7a18645 (diff) | |
Merge pull request #4751 from Barinzaya/arena-grow-in-place
Grow-in-place for some arenas
| -rw-r--r-- | base/runtime/default_temp_allocator_arena.odin | 22 | ||||
| -rw-r--r-- | core/mem/virtual/arena.odin | 22 |
2 files changed, 36 insertions, 8 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 diff --git a/core/mem/virtual/arena.odin b/core/mem/virtual/arena.odin index 675558ec8..5191505cf 100644 --- a/core/mem/virtual/arena.odin +++ b/core/mem/virtual/arena.odin @@ -328,10 +328,24 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.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.reserved { + // grow data in-place, adjusting next allocation + _ = alloc_from_memory_block(block, new_end - old_end, 1, default_commit_size=arena.default_commit_size) or_return + data = block.base[start:new_end] + return + } + } } new_memory := arena_alloc(arena, size, alignment, location) or_return |