std.mem.Allocator interface doen't allow for zero-copy resizing using mremap

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.

see: zig/lib/libc/musl/src/malloc/mallocng/realloc.c at b56a667ecdb9f34dbd60d247d4237bc008755979 · ziglang/zig · GitHub

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.

Here’s an example of using std.heap.page_allocator as the backing allocator for an arena, which shows that resize-in-place does indeed occur.

Also see the ArrayList implementation, which takes advantage of resize:

For your actual question, the most relevant issue is probably Improve Allocator interface so client can avoid needless copying · Issue #4431 · ziglang/zig · GitHub. This is the only MREMAP_MAYMOVE mention, though:

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.