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

Commit743112a

Browse files
committed
Adjust memory allocation functions to allow sibling calls
Many modern compilers are able to optimize function calls to functionswhere the parameters of the called function match a leading subset ofthe calling function's parameters. If there are no instructions in thecalling function after the function is called, then the compiler is freeto avoid any stack frame setup and implement the function call as a"jmp" rather than a "call". This is called sibling call optimization.Here we adjust the memory allocation functions in mcxt.c to allow thisoptimization. This requires moving some responsibility into the memorycontext implementations themselves. It's now the responsibility of theMemoryContext to check for malloc failures. This is good as it bothallows the sibling call optimization, but also because most small andmedium allocations won't call malloc and just allocate memory to anexisting block. That can't fail, so checking for NULLs in that caseisn't required.Also, traditionally it's been the responsibility of palloc and the otherallocation functions in mcxt.c to check for invalid allocation sizerequests. Here we also move the responsibility of checking that into theMemoryContext. This isn't to allow the sibling call optimization, butmore because most of our allocators handle large allocations separatelyand we can just add the size check when doing large allocations. We nolonger check this for non-large allocations at all.To make checking the allocation request sizes and ERROR handling easier,add some helper functions to mcxt.c for the allocators to use.Author: Andres FreundReviewed-by: David RowleyDiscussion:https://postgr.es/m/20210719195950.gavgs6ujzmjfaiig@alap3.anarazel.de
1 parent17a3f79 commit743112a

File tree

7 files changed

+196
-166
lines changed

7 files changed

+196
-166
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ AlignedAllocFree(void *pointer)
5757
*memory will be uninitialized.
5858
*/
5959
void*
60-
AlignedAllocRealloc(void*pointer,Sizesize)
60+
AlignedAllocRealloc(void*pointer,Sizesize,intflags)
6161
{
6262
MemoryChunk*redirchunk=PointerGetMemoryChunk(pointer);
6363
Sizealignto;
@@ -97,14 +97,17 @@ AlignedAllocRealloc(void *pointer, Size size)
9797
#endif
9898

9999
ctx=GetMemoryChunkContext(unaligned);
100-
newptr=MemoryContextAllocAligned(ctx,size,alignto,0);
100+
newptr=MemoryContextAllocAligned(ctx,size,alignto,flags);
101101

102102
/*
103103
* We may memcpy beyond the end of the original allocation request size,
104104
* so we must mark the entire allocation as defined.
105105
*/
106-
VALGRIND_MAKE_MEM_DEFINED(pointer,old_size);
107-
memcpy(newptr,pointer,Min(size,old_size));
106+
if (likely(newptr!=NULL))
107+
{
108+
VALGRIND_MAKE_MEM_DEFINED(pointer,old_size);
109+
memcpy(newptr,pointer,Min(size,old_size));
110+
}
108111
pfree(unaligned);
109112

110113
returnnewptr;

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ AllocSetDelete(MemoryContext context)
700700
* return space that is marked NOACCESS - AllocSetRealloc has to beware!
701701
*/
702702
void*
703-
AllocSetAlloc(MemoryContextcontext,Sizesize)
703+
AllocSetAlloc(MemoryContextcontext,Sizesize,intflags)
704704
{
705705
AllocSetset= (AllocSet)context;
706706
AllocBlockblock;
@@ -717,6 +717,9 @@ AllocSetAlloc(MemoryContext context, Size size)
717717
*/
718718
if (size>set->allocChunkLimit)
719719
{
720+
/* only check size in paths where the limits could be hit */
721+
MemoryContextCheckSize(context,size,flags);
722+
720723
#ifdefMEMORY_CONTEXT_CHECKING
721724
/* ensure there's always space for the sentinel byte */
722725
chunk_size=MAXALIGN(size+1);
@@ -727,7 +730,7 @@ AllocSetAlloc(MemoryContext context, Size size)
727730
blksize=chunk_size+ALLOC_BLOCKHDRSZ+ALLOC_CHUNKHDRSZ;
728731
block= (AllocBlock)malloc(blksize);
729732
if (block==NULL)
730-
returnNULL;
733+
returnMemoryContextAllocationFailure(context,size,flags);
731734

732735
context->mem_allocated+=blksize;
733736

@@ -940,7 +943,7 @@ AllocSetAlloc(MemoryContext context, Size size)
940943
}
941944

942945
if (block==NULL)
943-
returnNULL;
946+
returnMemoryContextAllocationFailure(context,size,flags);
944947

945948
context->mem_allocated+=blksize;
946949

@@ -1106,7 +1109,7 @@ AllocSetFree(void *pointer)
11061109
* request size.)
11071110
*/
11081111
void*
1109-
AllocSetRealloc(void*pointer,Sizesize)
1112+
AllocSetRealloc(void*pointer,Sizesize,intflags)
11101113
{
11111114
AllocBlockblock;
11121115
AllocSetset;
@@ -1139,6 +1142,9 @@ AllocSetRealloc(void *pointer, Size size)
11391142

11401143
set=block->aset;
11411144

1145+
/* only check size in paths where the limits could be hit */
1146+
MemoryContextCheckSize((MemoryContext)set,size,flags);
1147+
11421148
oldchksize=block->endptr- (char*)pointer;
11431149

11441150
#ifdefMEMORY_CONTEXT_CHECKING
@@ -1165,7 +1171,7 @@ AllocSetRealloc(void *pointer, Size size)
11651171
{
11661172
/* Disallow access to the chunk header. */
11671173
VALGRIND_MAKE_MEM_NOACCESS(chunk,ALLOC_CHUNKHDRSZ);
1168-
returnNULL;
1174+
returnMemoryContextAllocationFailure(&set->header,size,flags);
11691175
}
11701176

11711177
/* updated separately, not to underflow when (oldblksize > blksize) */
@@ -1325,15 +1331,15 @@ AllocSetRealloc(void *pointer, Size size)
13251331
AllocPointernewPointer;
13261332
Sizeoldsize;
13271333

1328-
/* allocate new chunk */
1329-
newPointer=AllocSetAlloc((MemoryContext)set,size);
1334+
/* allocate new chunk(this also checks size is valid)*/
1335+
newPointer=AllocSetAlloc((MemoryContext)set,size,flags);
13301336

13311337
/* leave immediately if request was not completed */
13321338
if (newPointer==NULL)
13331339
{
13341340
/* Disallow access to the chunk header. */
13351341
VALGRIND_MAKE_MEM_NOACCESS(chunk,ALLOC_CHUNKHDRSZ);
1336-
returnNULL;
1342+
returnMemoryContextAllocationFailure((MemoryContext)set,size,flags);
13371343
}
13381344

13391345
/*

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ GenerationDelete(MemoryContext context)
344344
* return space that is marked NOACCESS - GenerationRealloc has to beware!
345345
*/
346346
void*
347-
GenerationAlloc(MemoryContextcontext,Sizesize)
347+
GenerationAlloc(MemoryContextcontext,Sizesize,intflags)
348348
{
349349
GenerationContext*set= (GenerationContext*)context;
350350
GenerationBlock*block;
@@ -367,9 +367,12 @@ GenerationAlloc(MemoryContext context, Size size)
367367
{
368368
Sizeblksize=required_size+Generation_BLOCKHDRSZ;
369369

370+
/* only check size in paths where the limits could be hit */
371+
MemoryContextCheckSize((MemoryContext)set,size,flags);
372+
370373
block= (GenerationBlock*)malloc(blksize);
371374
if (block==NULL)
372-
returnNULL;
375+
returnMemoryContextAllocationFailure(context,size,flags);
373376

374377
context->mem_allocated+=blksize;
375378

@@ -472,7 +475,7 @@ GenerationAlloc(MemoryContext context, Size size)
472475
block= (GenerationBlock*)malloc(blksize);
473476

474477
if (block==NULL)
475-
returnNULL;
478+
returnMemoryContextAllocationFailure(context,size,flags);
476479

477480
context->mem_allocated+=blksize;
478481

@@ -737,7 +740,7 @@ GenerationFree(void *pointer)
737740
*into the old chunk - in that case we just update chunk header.
738741
*/
739742
void*
740-
GenerationRealloc(void*pointer,Sizesize)
743+
GenerationRealloc(void*pointer,Sizesize,intflags)
741744
{
742745
MemoryChunk*chunk=PointerGetMemoryChunk(pointer);
743746
GenerationContext*set;
@@ -839,15 +842,15 @@ GenerationRealloc(void *pointer, Size size)
839842
returnpointer;
840843
}
841844

842-
/* allocate new chunk */
843-
newPointer=GenerationAlloc((MemoryContext)set,size);
845+
/* allocate new chunk(this also checks size is valid)*/
846+
newPointer=GenerationAlloc((MemoryContext)set,size,flags);
844847

845848
/* leave immediately if request was not completed */
846849
if (newPointer==NULL)
847850
{
848851
/* Disallow access to the chunk header. */
849852
VALGRIND_MAKE_MEM_NOACCESS(chunk,Generation_CHUNKHDRSZ);
850-
returnNULL;
853+
returnMemoryContextAllocationFailure((MemoryContext)set,size,flags);
851854
}
852855

853856
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp