>>>> "OG" == Olivier Galibert
<galibert(a)pobox.com> writes:
OG> [Martin, I bounced you original message to xemacs-beta, I hope you
OG> don't mind]
OG> On Mon, Jan 22, 2001 at 06:53:36PM +0900, Martin Buchholz wrote:
> I've been doing too much alignment hacking lately. But I
still have
> trouble understanding how pdump alignment works.
OG> I'm using these facts of life:
OG> 1- Alignments are powers of two
OG> 2- sizeof() is required to return a properly-aligned size (that's in
OG> ANSI)
OG> By properly aligned size I mean if p is aligned for the type, p_size
OG> is aligned too.
OG> This means that you can get an upper-bound for the alignement of a
OG> given structure from its size by finding the higher power of two that
OG> is a divisor of the size. That's the point of the pdump_align_table
OG> array. The table goes all the way to 2^8 which is overkill though.
OG> We should stop at 2^3 or maybe 2^4 (and use a 8 or 16 elements table).
We should stop at ALIGNOF (max_align_t).
OG> The other trick I use is to dump the data ordered by decreasing
OG> alignment constraint. After all, if something is aligned for 8 bytes,
OG> it is aligned for 4, 2 and 1 too. And by (2) we know that if we're
OG> aligned for 8 bytes, and we write an 8-bytes aligned structure, we
OG> will still be 8-bytes aligned afterwards.
OG> So writing the data by decreasing alignment constraints ensures the
OG> alignment at zero cost in padding.
OG> This "scaning by decreasing alignment constraint" thingy is done by
OG> pdump_scan_by_alignment btw.
OG> That would be nice and cool, except that there is one exception. Some
OG> lrecords are lying a little. Well, to be more precise, they give
OG> sizes that are not the result of a sizeof, and don't necessarily
OG> respect (2). In particular, the opaques do that. If that case, the
OG> minimal alignment is sizeof(lrecord_header) (i.e. 4, but it should
OG> have been written as a sizeof).
Excellent explanation. Thanks. Need to dream about this some.
Actually a Lisp_Opaque has a lcrecord_header at the front, not an
lrecord_header. And the alignment of an lrecord_header is much less
than that of an lcrecord_header. But almost all lisp objects which
are lrecords have the same alignment requirements as lcrecords, since
they typically contain pointers. So we're not losing much here.
> Please comment. I would like to further nuke some of the
current
> alignment code, like this cruft at the end of pdump_dump_data():
>
> write (pdump_fd, desc ? pdump_buf : elmt->obj, size*count);
> if (elmt->is_lrecord && ((size*count) & 3)
> write (pdump_fd, "\0\0\0", 4-((size*count) & 3));
OG> This is the management of the exception. The other half is in
OG> pdump_allocate_offset.
> (This is partially fixed by my other patch with
PDUMP_ALIGN_STREAM, but...)
OG> Which aligns too hard though...
Yes. I have just changed it to align to ALIGNOF (struct
lcrecord_header) from ALIGNOF (max_align_t) which is a win on those
many platforms where double is aligned to 8, while pointers are
aligned to 4.