Out-of-memory handling in alloc customarily passes Layout to functions like handle_alloc_error. Layout is also embedded in TryReserveError's internals.
At the first glance it seems quite sensible, because Layout is given to allocators, so OOM handlers get exactly the same information as the allocator.
However, Layout is just size + align, and I don't see any serious use-case for having align.
-
It's not possible to use the
alignfield to report an invalid alignment. It has to be valid by the contract ofLayout. Invalidalignvalues will never reach the memory allocator or the OOM handling machinery. Invalid alignment goes through different paths, and causespanic!("capacity overflow")or aTryReserveErrorwith (not yet stabilized)CapacityOverflowkind. When capacity overflow happens, you don't get any details at all. -
The
AllocatorAPI takes aLayout, so any direct users of allocators already know what layout they're using. The allocator has no need to report it back, and couldn't even if it wanted, becauseAllocErroris a unit struct (which I think is good, because it keepsResultof allocators as small as possible). -
As far as I can tell, all current valid values of the alignment are pretty boring and predictable. Collections always use
mem::align_of::<T>.Rc/Arconly pad it to the alignment ofusize. Users can easily replicate thealignvalue if they really wanted to. I can imagine some more advanced collections could try to align data to cache lines or page size, but even then, what's the use-case for reporting that to the OOM handler in particular?
Users may want to track how much memory is wasted due to alignment and other reasons, but the OOM handler is unsuitable for that. It only gets a singular data point, only in exceptional circumstances. In practice, all metadata about memory usage and efficiency is better collected by wrapping the allocator, which knows the Layout and its own internals, and can expose a custom interface for reporting as much info as desired (which jemalloc and cap already do).
There's an open question whether custom allocators should be returning custom errors, but Layout.align certainly isn't it. Layout is stable, not parametrized by an allocator, and extra info would go into its own separate type.
Hashbrown's TryReserveError exposes the Layout. I've searched github for uses of it, and couldn't find any uses of align. It's common to just map it to application's own Error::OOM.
There's unstable set_alloc_error_hook. I've searched github for its uses. One printed {layout:?}, and all more specific uses only looked at the layout.size() or didn't even touch the layout. Gecko's OOM handler only takes size. The hook is scheduled for removal to be replaced by oom=panic.
Therefore, I suggest reporting just the size on allocation failures in try_reserve and OOM hook/panic. I think even size isn't strictly necessary, but it can be useful to know whether an allocation failure happened on an unrealistically-huge bigger-than-ram allocation, which suggests it's a bug in the program (e.g. a negative size) not an actual OOM situation.
This would allow TryReserveError to be half the size. It can internally be a NonZeroUsize (or a custom usize niche) with values > isize::MAX meaning capacity overflow. It'd be cheap to construct (from saturating arithmetic), and it'd be small in Result<(), TryReserveError>. Currently it's an opaque type, so its internals can be changed. There's proposed AllocErrorPanicPayload that exposes Layout, but that could be easily changed to return only size.