| 
20 | 20 | 
 
  | 
21 | 21 | #include <string.h>  | 
22 | 22 | 
 
  | 
23 |  | -/* TODO: Alignment */  | 
24 |  | -#define NL_SIZE(nls) (sizeof(NestingLevel) + (nls)->userDataSize)  | 
 | 23 | +/* struct alignment trick, copied from GObject's gtype.c, which borrows  | 
 | 24 | + * 2*szieof(size_t) from glibc */  | 
 | 25 | +#define STRUCT_ALIGNMENT (2 * sizeof (size_t))  | 
 | 26 | +#define ALIGN_STRUCT(offset) ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)  | 
 | 27 | + | 
 | 28 | +/* account for the user data alignment if we have user data, otherwise allocate  | 
 | 29 | + * exactly what's needed not to waste memory for unneeded alignment */  | 
 | 30 | +#define NL_SIZE(nls) ((nls)->userDataSize ? (ALIGN_STRUCT (sizeof (NestingLevel)) + ALIGN_STRUCT ((nls)->userDataSize)) : sizeof (NestingLevel))  | 
 | 31 | +#define NL_USER_DATA(nl) ((void *)(((char *) nl) + ALIGN_STRUCT (sizeof (NestingLevel))))  | 
 | 32 | + | 
25 | 33 | #define NL_NTH(nls,n) (NestingLevel *)(((char *)((nls)->levels)) + ((n) * NL_SIZE (nls)))  | 
26 | 34 | 
 
  | 
27 | 35 | /*  | 
@@ -73,7 +81,7 @@ extern NestingLevel * nestingLevelsPush(NestingLevels *nls, int corkIndex)  | 
73 | 81 | 
 
  | 
74 | 82 | 	nl->corkIndex = corkIndex;  | 
75 | 83 | 	if (nls->userDataSize > 0)  | 
76 |  | -		memset (nl->userData, 0, nls->userDataSize);  | 
 | 84 | +		memset (NL_USER_DATA (nl), 0, ALIGN_STRUCT (nls->userDataSize));  | 
77 | 85 | 
 
  | 
78 | 86 | 	return nl;  | 
79 | 87 | }  | 
@@ -117,5 +125,5 @@ extern NestingLevel *nestingLevelsGetNthParent (const NestingLevels *nls, int n)  | 
117 | 125 | 
 
  | 
118 | 126 | extern void *nestingLevelGetUserData (const NestingLevel *nl)  | 
119 | 127 | {  | 
120 |  | -	return (void *)nl->userData;  | 
 | 128 | +	return NL_USER_DATA (nl);  | 
121 | 129 | }  | 
0 commit comments