Re: GIST code doesn't build on strict 64-bit machines - Mailing list pgsql-hackers
| From | Teodor Sigaev | 
|---|---|
| Subject | Re: GIST code doesn't build on strict 64-bit machines | 
| Date | |
| Msg-id | 4068369D.9040201@sigaev.ru Whole thread Raw | 
| In response to | GIST code doesn't build on strict 64-bit machines (Tom Lane <tgl@sss.pgh.pa.us>) | 
| Responses | Re: GIST code doesn't build on strict 64-bit machines | 
| List | pgsql-hackers | 
Tom Lane wrote:
> I've just found out the hard way that Postgres doesn't even build on
> recent gcc releases for 64-bit HPPA.  The reason is that the compiler
> now notices and complains about alignment errors that will lead to
> core dump at runtime, and GIST has got some.  The particular code that
> fails to compile is in gist.c:
>                 gistentryinit(((GISTENTRY *) VARDATA(evec))[1],
>                     ((GISTENTRY *) VARDATA(evec))[0].key, r, NULL,
>                               (OffsetNumber) 0, ((GISTENTRY *) VARDATA(evec))[0].bytes, FALSE);
> 
> Since VARDATA() is at a 4-byte offset from the start of the datum, this
> is trying to overlay a GISTENTRY struct at a 4-byte boundary.  When
> compiling in 64-bit mode, Datum is 8 bytes, and so the GISTENTRY struct
> is not sufficiently well aligned.  Unlike Intel machines, the HP chips
> *require* 8-byte loads and stores to be 8-byte-aligned.
Hm.
evec is defined as
storage = (char *) palloc(n * sizeof(GISTENTRY) + MAXALIGN(VARHDRSZ));
evec = (bytea *) (storage + MAXALIGN(VARHDRSZ) - VARHDRSZ);
VARDATA is defined as:
#define VARDATA(__PTR)               VARATT_DATA(__PTR)
#define VARATT_DATA(PTR)     (((varattrib *)(PTR))->va_content.va_data)
and VARHDRSZ is
#define VARHDRSZ            ((int32) sizeof(int32))
Look follow:
VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
#define VARATT_SIZEP(_PTR)   (((varattrib *)(_PTR))->va_header)
So, if  ((varattrib *)evec)->va_content.va_data - (char*)evec == 4 then
((GISTENTRY *) VARDATA(evec))[i] is 8-byte aligned, but evec - no.
But if ((varattrib *)evec)->va_content.va_data - (char*)evec == 8 then
both evec and ((GISTENTRY *) VARDATA(evec))[i] isn't 8-byte aligned.
I don't afraid to say some rubbish :)
I wrote simple test:
#include <stdio.h>
#include "c.h"
typedef struct {        int32   len;        char    data[1];
} TST;
int main(int argn, char *argv[]) {        TST t;        TST *ptr = &t;        printf("%d\n", (ptr->data - (char*)ptr));
      return 0;
 
}
It prints 4 for my Intel systems and for Alpha system, but I havn't access to 
HPUX. If result is equal to 8 on HPUX, then I suppose that replacing to
evec = (bytea *) storage
will resolve our problem (but VARHDRSZ has inconsistent definition).
But if result is 4 then we should use
evec = (bytea *) storage
and replace all VARDATA macro to something like
#define MY_VARDATA(PTR)    ( ((char*)PTR) + MAXALIGN(VARHDRSZ) )
But all of this is strage for me, because we already faced to problem with 
8-bytes strict aliasing in GiST code, and we had resolved problem on Sun and 
Alpha boxes. What was it changed?
> I suppose that a correct fix involves doing MAXALIGN(VARDATA(evec)),
> but I do not know what places need to change to support this.
Its only union and picksplit user-defined methods in contrib modules.
-- 
Teodor Sigaev                                  E-mail: teodor@sigaev.ru
		
	pgsql-hackers by date: