46
46
#define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock))
47
47
#define Generation_CHUNKHDRSZ sizeof(GenerationChunk)
48
48
49
- /* Portion of Generation_CHUNKHDRSZ examined outside generation.c. */
50
- #define Generation_CHUNK_PUBLIC \
51
- (offsetof(GenerationChunk, size) + sizeof(Size))
52
-
53
- /* Portion of Generation_CHUNKHDRSZ excluding trailing padding. */
54
- #ifdef MEMORY_CONTEXT_CHECKING
55
- #define Generation_CHUNK_USED \
56
- (offsetof(GenerationChunk, requested_size) + sizeof(Size))
57
- #else
58
- #define Generation_CHUNK_USED \
59
- (offsetof(GenerationChunk, size) + sizeof(Size))
60
- #endif
61
-
62
49
typedef struct GenerationBlock GenerationBlock ; /* forward reference */
63
50
typedef struct GenerationChunk GenerationChunk ;
64
51
@@ -103,28 +90,35 @@ struct GenerationBlock
103
90
/*
104
91
* GenerationChunk
105
92
* The prefix of each piece of memory in a GenerationBlock
93
+ *
94
+ * Note: to meet the memory context APIs, the payload area of the chunk must
95
+ * be maxaligned, and the "context" link must be immediately adjacent to the
96
+ * payload area (cf. GetMemoryChunkContext). We simplify matters for this
97
+ * module by requiring sizeof(GenerationChunk) to be maxaligned, and then
98
+ * we can ensure things work by adding any required alignment padding before
99
+ * the pointer fields. There is a static assertion below that the alignment
100
+ * is done correctly.
106
101
*/
107
102
struct GenerationChunk
108
103
{
109
- /* block owning this chunk */
110
- void * block ;
111
-
112
104
/* size is always the size of the usable space in the chunk */
113
105
Size size ;
114
106
#ifdef MEMORY_CONTEXT_CHECKING
115
107
/* when debugging memory usage, also store actual requested size */
116
108
/* this is zero in a free chunk */
117
109
Size requested_size ;
118
- #define GENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T * 2)
110
+
111
+ #define GENERATIONCHUNK_RAWSIZE (SIZEOF_SIZE_T * 2 + SIZEOF_VOID_P * 2)
119
112
#else
120
- #define GENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T )
113
+ #define GENERATIONCHUNK_RAWSIZE (SIZEOF_SIZE_T + SIZEOF_VOID_P * 2)
121
114
#endif /* MEMORY_CONTEXT_CHECKING */
122
115
123
116
/* ensure proper alignment by adding padding if needed */
124
117
#if (GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF ) != 0
125
- char padding [MAXIMUM_ALIGNOF - ( GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF ) ];
118
+ char padding [MAXIMUM_ALIGNOF - GENERATIONCHUNK_RAWSIZE % MAXIMUM_ALIGNOF ];
126
119
#endif
127
120
121
+ GenerationBlock * block ; /* block owning this chunk */
128
122
GenerationContext * context ; /* owning context */
129
123
/* there must not be any padding to reach a MAXALIGN boundary here! */
130
124
};
@@ -210,8 +204,11 @@ GenerationContextCreate(MemoryContext parent,
210
204
{
211
205
GenerationContext * set ;
212
206
207
+ /* Assert we padded GenerationChunk properly */
208
+ StaticAssertStmt (Generation_CHUNKHDRSZ == MAXALIGN (Generation_CHUNKHDRSZ ),
209
+ "sizeof(GenerationChunk) is not maxaligned" );
213
210
StaticAssertStmt (offsetof(GenerationChunk , context ) + sizeof (MemoryContext ) ==
214
- MAXALIGN ( sizeof ( GenerationChunk )) ,
211
+ Generation_CHUNKHDRSZ ,
215
212
"padding calculation in GenerationChunk is wrong" );
216
213
217
214
/*
@@ -318,7 +315,6 @@ GenerationAlloc(MemoryContext context, Size size)
318
315
GenerationContext * set = (GenerationContext * ) context ;
319
316
GenerationBlock * block ;
320
317
GenerationChunk * chunk ;
321
-
322
318
Size chunk_size = MAXALIGN (size );
323
319
324
320
/* is it an over-sized chunk? if yes, allocate special block */
@@ -338,6 +334,7 @@ GenerationAlloc(MemoryContext context, Size size)
338
334
block -> freeptr = block -> endptr = ((char * ) block ) + blksize ;
339
335
340
336
chunk = (GenerationChunk * ) (((char * ) block ) + Generation_BLOCKHDRSZ );
337
+ chunk -> block = block ;
341
338
chunk -> context = set ;
342
339
chunk -> size = chunk_size ;
343
340
@@ -356,17 +353,16 @@ GenerationAlloc(MemoryContext context, Size size)
356
353
/* add the block to the list of allocated blocks */
357
354
dlist_push_head (& set -> blocks , & block -> node );
358
355
359
- GenerationAllocInfo (set , chunk );
360
-
361
356
/*
362
- * Chunk header public fields remain DEFINED. The requested
363
- * allocation itself can be NOACCESS or UNDEFINED; our caller will
364
- * soon make it UNDEFINED. Make extra space at the end of the chunk,
365
- * if any, NOACCESS.
357
+ * Chunk header fields remain DEFINED. The requested allocation
358
+ * itself can be NOACCESS or UNDEFINED; our caller will soon make it
359
+ * UNDEFINED. Make extra space at the end of the chunk, if any ,
360
+ * NOACCESS.
366
361
*/
367
- VALGRIND_MAKE_MEM_NOACCESS ((char * ) chunk + Generation_CHUNK_PUBLIC ,
368
- chunk_size + Generation_CHUNKHDRSZ - Generation_CHUNK_PUBLIC );
362
+ VALGRIND_MAKE_MEM_NOACCESS ((char * ) chunk + Generation_CHUNKHDRSZ + size ,
363
+ chunk_size - size );
369
364
365
+ GenerationAllocInfo (set , chunk );
370
366
return GenerationChunkGetPointer (chunk );
371
367
}
372
368
@@ -442,8 +438,8 @@ GenerationAlloc(MemoryContext context, Size size)
442
438
443
439
/*
444
440
* GenerationFree
445
- * Update number of chunks on the block, and if all chunks on the block
446
- * are freeed then discard the block.
441
+ * Update number of chunks in the block, and if all chunks in the block
442
+ * are now free then discard the block.
447
443
*/
448
444
static void
449
445
GenerationFree (MemoryContext context , void * pointer )
0 commit comments