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

Commit7e3aa03

Browse files
committed
Reduce size of common allocation header.
The new slab allocator needs different per-allocation information thanthe classical aset.c. The definition in58b25e9 wasn't sufficientlycareful on 32 platforms with 8 byte alignment, leading to buildfarmfailures. That's not entirely easy to fix by just adjusting thedefinition.As slab.c doesn't actually need the size part(s) of the common header,all chunks are equally sized after all, it seems better to insteadreduce the header to the part needed by all allocators, namely whichcontext an allocation belongs to. That has the advantage of reducingthe overhead of slab allocations, and also allows for more flexibilityin future allocators.To avoid spreading the logic about accessing a chunk's context around,centralize it in GetMemoryChunkContext(), which allows to delete agood number of lines.A followup commit will revise the mmgr/README portion aboutStandardChunkHeader, and more.Author: Andres FreundDiscussion:https://postgr.es/m/20170228074420.aazv4iw6k562mnxg@alap3.anarazel.de
1 parenteb75f4f commit7e3aa03

File tree

5 files changed

+97
-218
lines changed

5 files changed

+97
-218
lines changed

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

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -97,20 +97,7 @@
9797
*/
9898

9999
#defineALLOC_BLOCKHDRSZMAXALIGN(sizeof(AllocBlockData))
100-
#defineALLOC_CHUNKHDRSZMAXALIGN(sizeof(AllocChunkData))
101-
102-
/* Portion of ALLOC_CHUNKHDRSZ examined outside aset.c. */
103-
#defineALLOC_CHUNK_PUBLIC\
104-
(offsetof(AllocChunkData, size) + sizeof(Size))
105-
106-
/* Portion of ALLOC_CHUNKHDRSZ excluding trailing padding. */
107-
#ifdefMEMORY_CONTEXT_CHECKING
108-
#defineALLOC_CHUNK_USED\
109-
(offsetof(AllocChunkData, requested_size) + sizeof(Size))
110-
#else
111-
#defineALLOC_CHUNK_USED\
112-
(offsetof(AllocChunkData, size) + sizeof(Size))
113-
#endif
100+
#defineALLOC_CHUNKHDRSZsizeof(struct AllocChunkData)
114101

115102
typedefstructAllocBlockData*AllocBlock;/* forward reference */
116103
typedefstructAllocChunkData*AllocChunk;
@@ -169,20 +156,25 @@ typedef struct AllocBlockData
169156
/*
170157
* AllocChunk
171158
*The prefix of each piece of memory in an AllocBlock
172-
*
173-
* NB: this MUST match StandardChunkHeader as defined by utils/memutils.h.
174159
*/
175160
typedefstructAllocChunkData
176161
{
177-
/* aset is the owning aset if allocated, or the freelist link if free */
178-
void*aset;
179162
/* size is always the size of the usable space in the chunk */
180163
Sizesize;
181164
#ifdefMEMORY_CONTEXT_CHECKING
182165
/* when debugging memory usage, also store actual requested size */
183166
/* this is zero in a free chunk */
184167
Sizerequested_size;
168+
#ifMAXIMUM_ALIGNOF>4&&SIZEOF_VOID_P==4
169+
Sizepadding;
185170
#endif
171+
172+
#endif/* MEMORY_CONTEXT_CHECKING */
173+
174+
/* aset is the owning aset if allocated, or the freelist link if free */
175+
void*aset;
176+
177+
/* there must not be any padding to reach a MAXALIGN boundary here! */
186178
}AllocChunkData;
187179

188180
/*
@@ -334,6 +326,10 @@ AllocSetContextCreate(MemoryContext parent,
334326
{
335327
AllocSetset;
336328

329+
StaticAssertStmt(offsetof(AllocChunkData,aset)+sizeof(MemoryContext)==
330+
MAXALIGN(sizeof(AllocChunkData)),
331+
"padding calculation in AllocChunkData is wrong");
332+
337333
/*
338334
* First, validate allocation parameters. (If we're going to throw an
339335
* error, we should do so before the context is created, not after.) We
@@ -616,13 +612,13 @@ AllocSetAlloc(MemoryContext context, Size size)
616612
AllocAllocInfo(set,chunk);
617613

618614
/*
619-
* Chunk header publicfields remain DEFINED. The requested
620-
*allocationitself can be NOACCESS or UNDEFINED; our caller will
621-
*soon make itUNDEFINED. Make extra space at the end of the chunk,
622-
*if any,NOACCESS.
615+
* Chunk's metadatafields remain DEFINED. The requested allocation
616+
* itself can be NOACCESS or UNDEFINED; our caller will soon make it
617+
* UNDEFINED. Make extra space at the end of the chunk, if any,
618+
* NOACCESS.
623619
*/
624-
VALGRIND_MAKE_MEM_NOACCESS((char*)chunk+ALLOC_CHUNK_PUBLIC,
625-
chunk_size+ALLOC_CHUNKHDRSZ-ALLOC_CHUNK_PUBLIC);
620+
VALGRIND_MAKE_MEM_NOACCESS((char*)chunk+ALLOC_CHUNKHDRSZ,
621+
chunk_size-ALLOC_CHUNKHDRSZ);
626622

627623
returnAllocChunkGetPointer(chunk);
628624
}
@@ -709,7 +705,7 @@ AllocSetAlloc(MemoryContext context, Size size)
709705
chunk= (AllocChunk) (block->freeptr);
710706

711707
/* Prepare to initialize the chunk header. */
712-
VALGRIND_MAKE_MEM_UNDEFINED(chunk,ALLOC_CHUNK_USED);
708+
VALGRIND_MAKE_MEM_UNDEFINED(chunk,ALLOC_CHUNKHDRSZ);
713709

714710
block->freeptr+= (availchunk+ALLOC_CHUNKHDRSZ);
715711
availspace-= (availchunk+ALLOC_CHUNKHDRSZ);
@@ -799,7 +795,7 @@ AllocSetAlloc(MemoryContext context, Size size)
799795
chunk= (AllocChunk) (block->freeptr);
800796

801797
/* Prepare to initialize the chunk header. */
802-
VALGRIND_MAKE_MEM_UNDEFINED(chunk,ALLOC_CHUNK_USED);
798+
VALGRIND_MAKE_MEM_UNDEFINED(chunk,ALLOC_CHUNKHDRSZ);
803799

804800
block->freeptr+= (chunk_size+ALLOC_CHUNKHDRSZ);
805801
Assert(block->freeptr <=block->endptr);

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

Lines changed: 8 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -389,55 +389,10 @@ MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
389389
Size
390390
GetMemoryChunkSpace(void*pointer)
391391
{
392-
StandardChunkHeader*header;
392+
MemoryContextcontext=GetMemoryChunkContext(pointer);
393393

394-
/*
395-
* Try to detect bogus pointers handed to us, poorly though we can.
396-
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
397-
* allocated chunk.
398-
*/
399-
Assert(pointer!=NULL);
400-
Assert(pointer== (void*)MAXALIGN(pointer));
401-
402-
/*
403-
* OK, it's probably safe to look at the chunk header.
404-
*/
405-
header= (StandardChunkHeader*)
406-
((char*)pointer-STANDARDCHUNKHEADERSIZE);
407-
408-
AssertArg(MemoryContextIsValid(header->context));
409-
410-
return (*header->context->methods->get_chunk_space) (header->context,
411-
pointer);
412-
}
413-
414-
/*
415-
* GetMemoryChunkContext
416-
*Given a currently-allocated chunk, determine the context
417-
*it belongs to.
418-
*/
419-
MemoryContext
420-
GetMemoryChunkContext(void*pointer)
421-
{
422-
StandardChunkHeader*header;
423-
424-
/*
425-
* Try to detect bogus pointers handed to us, poorly though we can.
426-
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
427-
* allocated chunk.
428-
*/
429-
Assert(pointer!=NULL);
430-
Assert(pointer== (void*)MAXALIGN(pointer));
431-
432-
/*
433-
* OK, it's probably safe to look at the chunk header.
434-
*/
435-
header= (StandardChunkHeader*)
436-
((char*)pointer-STANDARDCHUNKHEADERSIZE);
437-
438-
AssertArg(MemoryContextIsValid(header->context));
439-
440-
returnheader->context;
394+
return (context->methods->get_chunk_space) (context,
395+
pointer);
441396
}
442397

443398
/*
@@ -611,23 +566,9 @@ MemoryContextCheck(MemoryContext context)
611566
bool
612567
MemoryContextContains(MemoryContextcontext,void*pointer)
613568
{
614-
StandardChunkHeader*header;
615-
616-
/*
617-
* Try to detect bogus pointers handed to us, poorly though we can.
618-
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
619-
* allocated chunk.
620-
*/
621-
if (pointer==NULL||pointer!= (void*)MAXALIGN(pointer))
622-
return false;
569+
MemoryContextptr_context=GetMemoryChunkContext(pointer);
623570

624-
/*
625-
* OK, it's probably safe to look at the chunk header.
626-
*/
627-
header= (StandardChunkHeader*)
628-
((char*)pointer-STANDARDCHUNKHEADERSIZE);
629-
630-
returnheader->context==context;
571+
returnptr_context==context;
631572
}
632573

633574
/*--------------------
@@ -991,23 +932,7 @@ palloc_extended(Size size, int flags)
991932
void
992933
pfree(void*pointer)
993934
{
994-
MemoryContextcontext;
995-
996-
/*
997-
* Try to detect bogus pointers handed to us, poorly though we can.
998-
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
999-
* allocated chunk.
1000-
*/
1001-
Assert(pointer!=NULL);
1002-
Assert(pointer== (void*)MAXALIGN(pointer));
1003-
1004-
/*
1005-
* OK, it's probably safe to look at the chunk header.
1006-
*/
1007-
context= ((StandardChunkHeader*)
1008-
((char*)pointer-STANDARDCHUNKHEADERSIZE))->context;
1009-
1010-
AssertArg(MemoryContextIsValid(context));
935+
MemoryContextcontext=GetMemoryChunkContext(pointer);
1011936

1012937
(*context->methods->free_p) (context,pointer);
1013938
VALGRIND_MEMPOOL_FREE(context,pointer);
@@ -1020,27 +945,12 @@ pfree(void *pointer)
1020945
void*
1021946
repalloc(void*pointer,Sizesize)
1022947
{
1023-
MemoryContextcontext;
948+
MemoryContextcontext=GetMemoryChunkContext(pointer);
1024949
void*ret;
1025950

1026951
if (!AllocSizeIsValid(size))
1027952
elog(ERROR,"invalid memory alloc request size %zu",size);
1028953

1029-
/*
1030-
* Try to detect bogus pointers handed to us, poorly though we can.
1031-
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
1032-
* allocated chunk.
1033-
*/
1034-
Assert(pointer!=NULL);
1035-
Assert(pointer== (void*)MAXALIGN(pointer));
1036-
1037-
/*
1038-
* OK, it's probably safe to look at the chunk header.
1039-
*/
1040-
context= ((StandardChunkHeader*)
1041-
((char*)pointer-STANDARDCHUNKHEADERSIZE))->context;
1042-
1043-
AssertArg(MemoryContextIsValid(context));
1044954
AssertNotInCriticalSection(context);
1045955

1046956
/* isReset must be false already */
@@ -1103,27 +1013,12 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
11031013
void*
11041014
repalloc_huge(void*pointer,Sizesize)
11051015
{
1106-
MemoryContextcontext;
1016+
MemoryContextcontext=GetMemoryChunkContext(pointer);
11071017
void*ret;
11081018

11091019
if (!AllocHugeSizeIsValid(size))
11101020
elog(ERROR,"invalid memory alloc request size %zu",size);
11111021

1112-
/*
1113-
* Try to detect bogus pointers handed to us, poorly though we can.
1114-
* Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
1115-
* allocated chunk.
1116-
*/
1117-
Assert(pointer!=NULL);
1118-
Assert(pointer== (void*)MAXALIGN(pointer));
1119-
1120-
/*
1121-
* OK, it's probably safe to look at the chunk header.
1122-
*/
1123-
context= ((StandardChunkHeader*)
1124-
((char*)pointer-STANDARDCHUNKHEADERSIZE))->context;
1125-
1126-
AssertArg(MemoryContextIsValid(context));
11271022
AssertNotInCriticalSection(context);
11281023

11291024
/* isReset must be false already */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp