in C, when using realloc() it is sometimes possible to grow the allocation and avoid the memcopy by only changing the virtual addresses and keeping the data in physical memory in place.
The current allocator interface doesn’t seem to allow for this case and I wasn’t able to find an issue documenting the rationale for this choice?
Maybe one reason could be that it is not so useful in practice:
I did a cursory check by adding some logs to MultiArrayList.setCapacity() and ArrayList.ensureTotalCapacityPrecise()
and while something like for (0..123456789) |v| try array.append(v); would benefit a lot,
running zig itself doesn’t triggers the case that much.
EDIT: I missed the “only changing the virtual addresses and keeping the data in physical memory in place” part (Zig’s Allocator.resize stipulates that the memory address must stay the same). Expand below for a probably-irrelevant response.
Unless I’m missing something, the Allocator interface does support this use-case:
PageAllocator (which is commonly used as a backing allocator for other allocator implementations) has a resize implementation with a // TODO: call mremap, but note that since it always allocates at least a full page for any requested size, resize is guaranteed to succeed when growing an allocation from < page size to <= page size.
From an allocator implementation standpoint, the only case I’ve heard of for implementing realloc as anything more than reallocInPlace + memcpy on failure is to be able to use MREMAP_MAYMOVE on large allocations. Some allocators (e.g. jemalloc) try to avoid MREMAP_MAYMOVE anyway for fragmentation reasons.