Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf65d21b

Browse files
committed
Mostly-cosmetic improvements in memory chunk header alignment coding.
Add commentary about what we're doing and why. Apply the method used forpadding in GenerationChunk to AllocChunkData, replacing the rather ad-hocsolution used in commit7e3aa03. Reorder fields in GenerationChunk sothat the padding calculation will work even if sizeof(size_t) is differentfrom sizeof(void *) --- likely that will never happen, but we don't needthe assumption if we do it like this. Improve static assertions aboutalignment.In passing, fix a couple of oversights in the "large chunk" path inGenerationAlloc().Discussion:https://postgr.es/m/E1eHa4J-0006hI-Q8@gemulon.postgresql.org
1 parentcc3c4af commitf65d21b

File tree

3 files changed

+62
-42
lines changed

3 files changed

+62
-42
lines changed

‎src/backend/utils/mmgr/aset.c

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ typedef struct AllocBlockData
157157
/*
158158
* AllocChunk
159159
*The prefix of each piece of memory in an AllocBlock
160+
*
161+
* Note: to meet the memory context APIs, the payload area of the chunk must
162+
* be maxaligned, and the "aset" link must be immediately adjacent to the
163+
* payload area (cf. GetMemoryChunkContext). We simplify matters for this
164+
* module by requiring sizeof(AllocChunkData) to be maxaligned, and then
165+
* we can ensure things work by adding any required alignment padding before
166+
* the "aset" field. There is a static assertion below that the alignment
167+
* is done correctly.
160168
*/
161169
typedefstructAllocChunkData
162170
{
@@ -166,15 +174,19 @@ typedef struct AllocChunkData
166174
/* when debugging memory usage, also store actual requested size */
167175
/* this is zero in a free chunk */
168176
Sizerequested_size;
169-
#ifMAXIMUM_ALIGNOF>4&&SIZEOF_VOID_P==4
170-
Sizepadding;
171-
#endif
172177

178+
#defineALLOCCHUNK_RAWSIZE (SIZEOF_SIZE_T * 2 + SIZEOF_VOID_P)
179+
#else
180+
#defineALLOCCHUNK_RAWSIZE (SIZEOF_SIZE_T + SIZEOF_VOID_P)
173181
#endif/* MEMORY_CONTEXT_CHECKING */
174182

183+
/* ensure proper alignment by adding padding if needed */
184+
#if (ALLOCCHUNK_RAWSIZE %MAXIMUM_ALIGNOF)!=0
185+
charpadding[MAXIMUM_ALIGNOF-ALLOCCHUNK_RAWSIZE %MAXIMUM_ALIGNOF];
186+
#endif
187+
175188
/* aset is the owning aset if allocated, or the freelist link if free */
176189
void*aset;
177-
178190
/* there must not be any padding to reach a MAXALIGN boundary here! */
179191
}AllocChunkData;
180192

@@ -327,8 +339,11 @@ AllocSetContextCreate(MemoryContext parent,
327339
{
328340
AllocSetset;
329341

342+
/* Assert we padded AllocChunkData properly */
343+
StaticAssertStmt(ALLOC_CHUNKHDRSZ==MAXALIGN(ALLOC_CHUNKHDRSZ),
344+
"sizeof(AllocChunkData) is not maxaligned");
330345
StaticAssertStmt(offsetof(AllocChunkData,aset)+sizeof(MemoryContext)==
331-
MAXALIGN(sizeof(AllocChunkData)),
346+
ALLOC_CHUNKHDRSZ,
332347
"padding calculation in AllocChunkData is wrong");
333348

334349
/*

‎src/backend/utils/mmgr/generation.c

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,6 @@
4646
#defineGeneration_BLOCKHDRSZMAXALIGN(sizeof(GenerationBlock))
4747
#defineGeneration_CHUNKHDRSZsizeof(GenerationChunk)
4848

49-
/* Portion of Generation_CHUNKHDRSZ examined outside generation.c. */
50-
#defineGeneration_CHUNK_PUBLIC\
51-
(offsetof(GenerationChunk, size) + sizeof(Size))
52-
53-
/* Portion of Generation_CHUNKHDRSZ excluding trailing padding. */
54-
#ifdefMEMORY_CONTEXT_CHECKING
55-
#defineGeneration_CHUNK_USED\
56-
(offsetof(GenerationChunk, requested_size) + sizeof(Size))
57-
#else
58-
#defineGeneration_CHUNK_USED\
59-
(offsetof(GenerationChunk, size) + sizeof(Size))
60-
#endif
61-
6249
typedefstructGenerationBlockGenerationBlock;/* forward reference */
6350
typedefstructGenerationChunkGenerationChunk;
6451

@@ -103,28 +90,35 @@ struct GenerationBlock
10390
/*
10491
* GenerationChunk
10592
*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.
106101
*/
107102
structGenerationChunk
108103
{
109-
/* block owning this chunk */
110-
void*block;
111-
112104
/* size is always the size of the usable space in the chunk */
113105
Sizesize;
114106
#ifdefMEMORY_CONTEXT_CHECKING
115107
/* when debugging memory usage, also store actual requested size */
116108
/* this is zero in a free chunk */
117109
Sizerequested_size;
118-
#defineGENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T * 2)
110+
111+
#defineGENERATIONCHUNK_RAWSIZE (SIZEOF_SIZE_T * 2 + SIZEOF_VOID_P * 2)
119112
#else
120-
#defineGENERATIONCHUNK_RAWSIZE (SIZEOF_VOID_P * 2 + SIZEOF_SIZE_T)
113+
#defineGENERATIONCHUNK_RAWSIZE (SIZEOF_SIZE_T +SIZEOF_VOID_P * 2)
121114
#endif/* MEMORY_CONTEXT_CHECKING */
122115

123116
/* ensure proper alignment by adding padding if needed */
124117
#if (GENERATIONCHUNK_RAWSIZE %MAXIMUM_ALIGNOF)!=0
125-
charpadding[MAXIMUM_ALIGNOF-(GENERATIONCHUNK_RAWSIZE %MAXIMUM_ALIGNOF)];
118+
charpadding[MAXIMUM_ALIGNOF-GENERATIONCHUNK_RAWSIZE %MAXIMUM_ALIGNOF];
126119
#endif
127120

121+
GenerationBlock*block;/* block owning this chunk */
128122
GenerationContext*context;/* owning context */
129123
/* there must not be any padding to reach a MAXALIGN boundary here! */
130124
};
@@ -210,8 +204,11 @@ GenerationContextCreate(MemoryContext parent,
210204
{
211205
GenerationContext*set;
212206

207+
/* Assert we padded GenerationChunk properly */
208+
StaticAssertStmt(Generation_CHUNKHDRSZ==MAXALIGN(Generation_CHUNKHDRSZ),
209+
"sizeof(GenerationChunk) is not maxaligned");
213210
StaticAssertStmt(offsetof(GenerationChunk,context)+sizeof(MemoryContext)==
214-
MAXALIGN(sizeof(GenerationChunk)),
211+
Generation_CHUNKHDRSZ,
215212
"padding calculation in GenerationChunk is wrong");
216213

217214
/*
@@ -318,7 +315,6 @@ GenerationAlloc(MemoryContext context, Size size)
318315
GenerationContext*set= (GenerationContext*)context;
319316
GenerationBlock*block;
320317
GenerationChunk*chunk;
321-
322318
Sizechunk_size=MAXALIGN(size);
323319

324320
/* is it an over-sized chunk? if yes, allocate special block */
@@ -338,6 +334,7 @@ GenerationAlloc(MemoryContext context, Size size)
338334
block->freeptr=block->endptr= ((char*)block)+blksize;
339335

340336
chunk= (GenerationChunk*) (((char*)block)+Generation_BLOCKHDRSZ);
337+
chunk->block=block;
341338
chunk->context=set;
342339
chunk->size=chunk_size;
343340

@@ -356,17 +353,16 @@ GenerationAlloc(MemoryContext context, Size size)
356353
/* add the block to the list of allocated blocks */
357354
dlist_push_head(&set->blocks,&block->node);
358355

359-
GenerationAllocInfo(set,chunk);
360-
361356
/*
362-
* Chunk headerpublicfields remain DEFINED. The requested
363-
*allocationitself can be NOACCESS or UNDEFINED; our caller will
364-
*soon make itUNDEFINED. 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.
366361
*/
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);
369364

365+
GenerationAllocInfo(set,chunk);
370366
returnGenerationChunkGetPointer(chunk);
371367
}
372368

@@ -442,8 +438,8 @@ GenerationAlloc(MemoryContext context, Size size)
442438

443439
/*
444440
* GenerationFree
445-
*Update number of chunkson the block, and if all chunkson the block
446-
*arefreeed then discard the block.
441+
*Update number of chunksin the block, and if all chunksin the block
442+
*arenow free then discard the block.
447443
*/
448444
staticvoid
449445
GenerationFree(MemoryContextcontext,void*pointer)

‎src/backend/utils/mmgr/slab.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,18 @@ typedef struct SlabBlock
9191

9292
/*
9393
* SlabChunk
94-
*The prefix of each piece of memory in an SlabBlock
94+
*The prefix of each piece of memory in a SlabBlock
95+
*
96+
* Note: to meet the memory context APIs, the payload area of the chunk must
97+
* be maxaligned, and the "slab" link must be immediately adjacent to the
98+
* payload area (cf. GetMemoryChunkContext). Since we support no machines on
99+
* which MAXALIGN is more than twice sizeof(void *), this happens without any
100+
* special hacking in this struct declaration. But there is a static
101+
* assertion below that the alignment is done correctly.
95102
*/
96103
typedefstructSlabChunk
97104
{
98-
/* block owning this chunk */
99-
void*block;
105+
SlabBlock*block;/* block owning this chunk */
100106
SlabContext*slab;/* owning context */
101107
/* there must not be any padding to reach a MAXALIGN boundary here! */
102108
}SlabChunk;
@@ -190,16 +196,19 @@ SlabContextCreate(MemoryContext parent,
190196
SizefreelistSize;
191197
SlabContext*slab;
192198

199+
/* Assert we padded SlabChunk properly */
200+
StaticAssertStmt(sizeof(SlabChunk)==MAXALIGN(sizeof(SlabChunk)),
201+
"sizeof(SlabChunk) is not maxaligned");
193202
StaticAssertStmt(offsetof(SlabChunk,slab)+sizeof(MemoryContext)==
194-
MAXALIGN(sizeof(SlabChunk)),
203+
sizeof(SlabChunk),
195204
"padding calculation in SlabChunk is wrong");
196205

197206
/* Make sure the linked list node fits inside a freed chunk */
198207
if (chunkSize<sizeof(int))
199208
chunkSize=sizeof(int);
200209

201210
/* chunk, including SLAB header (both addresses nicely aligned) */
202-
fullChunkSize=MAXALIGN(sizeof(SlabChunk)+MAXALIGN(chunkSize));
211+
fullChunkSize=sizeof(SlabChunk)+MAXALIGN(chunkSize);
203212

204213
/* Make sure the block can store at least one chunk. */
205214
if (blockSize-sizeof(SlabBlock)<fullChunkSize)
@@ -443,7 +452,7 @@ SlabAlloc(MemoryContext context, Size size)
443452
/* Prepare to initialize the chunk header. */
444453
VALGRIND_MAKE_MEM_UNDEFINED(chunk,sizeof(SlabChunk));
445454

446-
chunk->block=(void*)block;
455+
chunk->block=block;
447456
chunk->slab=slab;
448457

449458
#ifdefMEMORY_CONTEXT_CHECKING

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp