[PATCH] libstdc++: Add allocate_at_least (P0401) [PR118030]

Jonathan Wakely jwakely.gcc@gmail.com
Tue Mar 10 17:43:30 GMT 2026


On Tue, 10 Mar 2026 at 17:35, Nathan Myers <ncm@cantrip.org> wrote:
>
> First, there is no Standard expectation that any of
>
>    ::operator delete(std::malloc(n))
>    std::free(::operator new(n))
>    ::operator delete(std::allocator<char>::allocate(n))
>    [etc.]
>
> works, although some users may have written programs that
> rely on it for their target platform.

Yes, obviously. Nobody is suggesting that should work. Valgrind and
Asan will both diagnose such bugs.


>
> However it is obviously necessary (given "using A =
> std::allocator<T>;") for
>
>    A::deallocate(A::allocate(n)), n)
>    A::deallocate(A::allocate_at_least(n), n)
>
> both to work, and practical reasons why mixing allocations of
> T and deallocations via char should, too.
>
> > Yes, so both allocate and allocate_at_least would need to reserve
> > extra memory in order to store a cookie before the return value,
> > which would say which function was used to allocate the memory.
> > Then deallocate would inspect the cookie to decide how to do the
> > deallocation. This adds overhead and uses extra memory, and can't
> > be done in the templated functions in the allocator class template,
> > because otherwise it becomes part of the ABI forever.
>  >
>  > And the extra space and time overhead would affect all uses of
>  > std::allocator, not only the ones that are opting in to the
>  > new API by calling allocate_at_least.
>
> There is no need for a cookie. Trivially, implementing
>
>    A::allocate(n) { return A::allocate_at_least(n).ptr; }
>
> is allowed.

That's what I've been saying all along, you're the one who raised the
topic of storing a cookie (or other side channel) for allocate(n) to
communicate with deallocate(p, n).


> > And what would the new logic for allocate_at_least even do? Are we
> > going to reimplement an entire malloc, just to be able to return a few
> > more bytes? Using mmap doesn't give you a high performance allocator,
> > you still need to implement a malloc-like thing on top of raw mmap.
> > Using jemalloc isn't an option unless we bundle [it].
> >
> > I'm not persuaded that this is worth doing.
> >
> > P0901 would have meant the additional logic happens in the right
> > place, in an operator new which is replaceable. I don't think doing it
> > in std::allocator is a good idea.
>
> The gains available from using a better-designed allocator,
> whether one coded from scratch or by importation, are very
> substantial, with or without substantive allocate_at_least
> support, although such gains would vary radically from one
> program to another. I saw three orders of magnitude difference
> in performance between different allocators, during the Unix
> wars. (SGI was slowest, DEC fastest, but still 10x slower
> than mine and with 1.5x total footprint; that last mattered
> a lot, then.)

Why would we want to do that in libstdc++ instead of doing it in
glibc, so it benefits all out customers?

>
> The amount of extra storage deliverable to allocate_at_least()
> with a bespoke design could be (often) much larger than what we
> get from rounding up to an alignment boundary. (Arguably, the
> only case where that last is worth doing is when sizeof(T) is 1.)

The goal is P0401 is not to maximize the amount of additional storage
it makes available, just to let the application use the additional
storage that the allocator naturally makes available without needing
to do any extra work.

(and rounding up to max_align_t seems worthwhile for int-sized types,
not just for bytes).


> Whether those gains are worth the investment is a business
> decision, which depends heavily on how much work is invested.
> Providing a way (whether proprietary or eventually Standard) to
> plug in a third-party allocator could be much less work than
> implementing a new allocator engine from scratch, and then
> different third-party libraries could be tried for different
> programs.

Then we should consider a design more like P0901, not invent new side
channels in the existing API.

I still don't think we should make any such changes to std::allocator
or operator new at this time.


More information about the Libstdc++ mailing list