[Gc] Re: Determining alignment constraints
hans.boehm at hp.com
Wed May 3 11:03:49 PDT 2006
> -----Original Message-----
> From: gc-bounces at napali.hpl.hp.com
> [mailto:gc-bounces at napali.hpl.hp.com] On Behalf Of Ludovic Courtès
> Sent: Wednesday, May 03, 2006 1:40 AM
> To: gc at napali.hpl.hp.com
> Subject: [Gc] Re: Determining alignment constraints
> "Boehm, Hans" <hans.boehm at hp.com> writes:
> > In the 6.X versions, this is unfortunately a bit platform dependent.
> > ALIGN_DOUBLE should be defined on all platforms which might need 2
> > word alignment for standard C types. If that's not the
> case, let me
> > know (ideally by sending a patch to gcconfig.h).
> Actually, I don't mind if it's platform-specific. What I
> want is to be able to know for sure at compilation-time of my
> user program what the alignment constraints of the available
> `libgc' are.
> Ideally, the `ALIGNMENT' macro would be exported and
> documented, for instance under the name
> `GC_MALLOC_ALIGNMENT'. That would be very useful for
> programs that need this piece of information.
> To give an example, Guile's type mechanism requires that some
> objects (namely cells) be 8-octet aligned. So it needs to
> know whether `GC_malloc ()' will honor this alignment
> constraint, or whether it needs to over-allocate memory and
> return an adequately aligned pointer.
> > For 6.X, in some common configurations, GC_malloc(4)
> returns an object
> > that's only word aligned, even with ALIGN_DOUBLE set.
> According to `gcconfig.h', that is currently limited to m68k,
> PPC with MacOS, and CRIS.
In the 6.7 version (and I think 6.6), it seems to be defined elsewhere as well, in particular for "normal" X86 configurations.
Probably the easiest best way to work around the problem for 6.X is to build an autoconf test. I believe it's sufficient to allocate two objects of the desired size in a row; if they are sufficiently aligned, all of them will be.
The major difficulty with all of this is that the details depend on the setting of GC_all_interior_pointers, which I worked hard, perhaps unwisely, to make a runtime option to avoid multiple copies of the library. If you are using the collector for C/C++ code, you want this turned on, and you want objects to be overallocated by at least one byte in order to deal with one-past-the-end pointers. If you are allocating Guile cells, you probably want this turned off.
With one-byte-overallocation turned off, you get some other nice alignment properties. In particular small power of 2 sized allocations will be aligned to that power of 2. With the one-byte-overallocation, the extra byte implies that such allocations will actually be a word or two words larger, destroying the alignment.
This, if you know that GC_all_interior_pointers is turned off, you are guaranteed that GC_malloc(2*sizeof(void *)) will return something that is 2*sizeof(void *) aligned, and that should be true everywhere.
There is also currently a GC_memalign() call, which should always work, but will add some overhead.
Realistically, none of this will change in 6.X.
> > In 7.0alpha, all allocation is performed in units of
> granules, which
> > are normally 2 words, but could be adjusted at GC build time.
> > Everything is at least granule aligned.
> On a single machine, there may be several programs using the
> same `libgc'. Thus, they should preferably be able to adapt
> to the configuration of the available `libgc', rather than
> relying on some particular compile-time configuration of `libgc'.
The intent was that this configuration not be changed for "generic" builds of the library. I added a comment to that effect to the appropriate header. Thus in 7.0, you should be able to count on 2*sizeof(void *) alignment everywhere, unless you include and build your own version of the library.
> Gc mailing list
> Gc at linux.hpl.hp.com
More information about the Gc