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