On Jul 30, 2018, at 10:42 AM, Andrew Lutomirski <luto@mit.edu> wrote:


On Jul 27, 2018, at 9:58 AM, Owen Taylor <otaylor@redhat.com> wrote:

On Fri, Jul 27, 2018 at 9:44 AM, Florian Weimer <fweimer@redhat.com> wrote:
On 07/27/2018 03:33 PM, John Reiser wrote:The key principle is that sizeof(foo) must be the stride of an array of foo,

and the array must guarantee alignment of each element in the array.

Why do you think that?  If some documentation claims this is the case for individual objects, we need to fix it.

struct sizes *do* have this property - they are rounded up so that arrays have the correct alignment.
But that certainly doesn't imply that malloc(7) is allowed to give you unaligned memory.



As an x86 person but only occasionally a standardese person, I find the idea that malloc(8) should return a 16-byte-aligned pointer on x86 to be nuts. I can only think of one non-UB way to notice the difference between an 8-byte and 16-byte aligned result, and that way would be to literally cast to (u)intptr_t and look at the low bits.  This is plausibly relevant to certain VMs and tag bit users, but is totally irrelevant to basically anything else.  And 16-byte alignment for small allocations is a giant waste of memory.

So I think that glibc should change its behavior here to match everyone else, and get the ABI document changed if needed.

Frankly, I find it a bit odd that C stack frames on x86_64 want 16 byte alignment, and it took until gcc 4.8 (IIRC) to get proper support to opt out.

I did some research. Windows (via the VS runtime) gives the largest alignment of a non-overaligned object *that could fit in the allocated space*. See:

https://docs.microsoft.com/en-us/cpp/build/malloc-alignment

OpenBSD’s manual is unclear.

musl appears to give 4*sizeof(size_t) alignment no matter what.  This makes no sense to me.

FreeBSD’s manpage is the same as OpenBSD’s, but its malloc *is* jemalloc AFAICT.

POSIX.1-2008 says “The pointer returned if the allocation succeeds shall be suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object in the space allocated (until the space is explicitly freed or reallocated).”  As far as I can tell, they mean any type of object whose size matches the argument to malloc.  This definition, taken literally, is odd: if you define a type with size 1 and alignment 8192, it’s not going to work. So either POSIX intends to restrict itself to types that don’t involve truly wacky compiler extensions or to types that can exist as array members, such that alignment divides the size. In that case, glibc’s malloc is more strictly aligned than POSIX requires.

Here's an article about Firefox's experience: http://www.erahm.org/2016/03/24/minimum-alignment-of-allocation-across-platforms/

ISTM glibc is going a bit overboard here.  I can see some very minor benefits to forcing 16-byte alignment for small allocations, but it comes at the obvious cost of 2x memory overhead for 8-byte allocations and 4x for 4-byte allocations.