[Gc] Re: Determining alignment constraints
hans.boehm at hp.com
Thu May 4 12:53:55 PDT 2006
> -----Original Message-----
> From: Ludovic Courtès
> "Boehm, Hans" <hans.boehm at hp.com> writes:
> >> > 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.
> Sorry, does "it" refer to "the `ALIGNMENT' macro"? After a
> quick grep through the 6.6 source, I couldn't find it
> anywhere but in `gcconfig.h'.
I was referring to ALIGN_DOUBLE. Sorry. ALIGNMENT should be defined everywhere, but reflects pointer, not object, alignment. It is almost always sizeof(void *).
> > 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.
> I had thought about this but is this behavior guaranteed or
> just "believed to be guaranteed"? ;-) That makes a
> significant difference.
I think this follows form the fact that all large objects are HBLKSIZE (typically 4K) aligned, and all small objects are consecutively allocated within a block. Thus the difference in the address of consecutive objects mod 2^n must be constant. However, this only applies if the build-time libgc is configured like the runtime one, and particularly if GC_all_interior_pointers is set consistently.
(Though I think this has an easy mathematical proof, it has not been thoroughly tested. And I'll be the first to admit that for real software, both can be very useful, and don't always yield the same conclusions.)
> Besides, given that the alignment information is already
> available as a macro, I still believe that exposing this
> macro would allow for easier and more accurate propagation of
> the information.
> However, since `gcconfig.h' does not get installed, we'd have
> to propagate the macro definition to another, installed
> header. I have various tricks in mind that could be used to
> do this. Would you like to add such a macro definition to
> future `libgc' versions? If so, I could probably help.
The problem is that in 6.X much of the information I think you want is dependent on GC_all_interior_pointers, which can be changed at startup. Thus I'm not sure what a macro could tell you. And I'm trying to avoid doing much more work on 6.X anyway.
In 7.0, everything is 2*sizeof(void *) aligned anyway. And objects between 9 and 15 bytes in size will be 16 byte aligned, everywhere. (The latter is somewhat of an accident, but sufficiently inherent to the allocation strategy that I wouldn't be afraid of documenting it.) Are there other properties that it would be useful to export as a macro?
> > 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.
> Right, thanks for the trick. However, in Guile, `GC_malloc
> ()' is going to be wrapped in a Guile-specific allocation
> function that may be used for various kinds of objects, not
> only cells. That would have been useful if
> `GC_all_interior_pointers' was actually passed as an argument
> to some variant of `GC_malloc ()': cells could have been
> allocated with this turned off, while other arbitrary objects
> would have been allocated with this turned on. Anyway,
> leaving it on should not be a major issue.
> > There is also currently a GC_memalign() call, which should
> always work, but will add some overhead.
> It seems that this call is not exported (at least not in 6.6).
I expect that's a consequence of how it was packaged, which is probably a consequence of the fact that it isn't really documented. Those are certainly fixable.
> > 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.
> This means that some autoconf or `#ifdef' check must still be
> done to know how the available `libgc' works (IOW, to know
> whether it's a "generic" build).
I guess my view is that you shouldn't install a nongeneric build someplace where autoconf can find it. On the other hand, the build-time options do seem to be useful for some applications that include the library, and do not install it separately (of which we currently probably have too many).
> Gc mailing list
> Gc at linux.hpl.hp.com
More information about the Gc