|
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