PostgreSQL Source Code git master
Loading...
Searching...
No Matches
memutils.h File Reference
#include "nodes/memnodes.h"
Include dependency graph for memutils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define MaxAllocSize   ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
 
#define AllocSizeIsValid(size)   ((Size) (size) <= MaxAllocSize)
 
#define MaxAllocHugeSize   (SIZE_MAX / 2)
 
#define InvalidAllocSize   SIZE_MAX
 
#define AllocHugeSizeIsValid(size)   ((Size) (size) <= MaxAllocHugeSize)
 
#define MemoryContextCopyAndSetIdentifier(cxt, id)    MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
 
#define AllocSetContextCreate    AllocSetContextCreateInternal
 
#define ALLOCSET_DEFAULT_MINSIZE   0
 
#define ALLOCSET_DEFAULT_INITSIZE   (8 * 1024)
 
#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)
 
#define ALLOCSET_DEFAULT_SIZES    ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
 
#define ALLOCSET_SMALL_MINSIZE   0
 
#define ALLOCSET_SMALL_INITSIZE   (1 * 1024)
 
#define ALLOCSET_SMALL_MAXSIZE   (8 * 1024)
 
#define ALLOCSET_SMALL_SIZES    ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
 
#define ALLOCSET_START_SMALL_SIZES    ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
 
#define ALLOCSET_SEPARATE_THRESHOLD   8192
 
#define SLAB_DEFAULT_BLOCK_SIZE   (8 * 1024)
 
#define SLAB_LARGE_BLOCK_SIZE   (8 * 1024 * 1024)
 

Functions

void MemoryContextInit (void)
 
void MemoryContextReset (MemoryContext context)
 
void MemoryContextDelete (MemoryContext context)
 
void MemoryContextResetOnly (MemoryContext context)
 
void MemoryContextResetChildren (MemoryContext context)
 
void MemoryContextDeleteChildren (MemoryContext context)
 
void MemoryContextSetIdentifier (MemoryContext context, const char *id)
 
void MemoryContextSetParent (MemoryContext context, MemoryContext new_parent)
 
MemoryContext GetMemoryChunkContext (void *pointer)
 
Size GetMemoryChunkSpace (void *pointer)
 
MemoryContext MemoryContextGetParent (MemoryContext context)
 
bool MemoryContextIsEmpty (MemoryContext context)
 
Size MemoryContextMemAllocated (MemoryContext context, bool recurse)
 
void MemoryContextMemConsumed (MemoryContext context, MemoryContextCounters *consumed)
 
void MemoryContextStats (MemoryContext context)
 
void MemoryContextStatsDetail (MemoryContext context, int max_level, int max_children, bool print_to_stderr)
 
void MemoryContextAllowInCriticalSection (MemoryContext context, bool allow)
 
void HandleLogMemoryContextInterrupt (void)
 
void ProcessLogMemoryContextInterrupt (void)
 
MemoryContext AllocSetContextCreateInternal (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
MemoryContext SlabContextCreate (MemoryContext parent, const char *name, Size blockSize, Size chunkSize)
 
MemoryContext GenerationContextCreate (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
MemoryContext BumpContextCreate (MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
 
static bool pg_memory_is_all_zeros (const void *ptr, size_t len)
 

Variables

PGDLLIMPORT MemoryContext TopMemoryContext
 
PGDLLIMPORT MemoryContext ErrorContext
 
PGDLLIMPORT MemoryContext PostmasterContext
 
PGDLLIMPORT MemoryContext CacheMemoryContext
 
PGDLLIMPORT MemoryContext MessageContext
 
PGDLLIMPORT MemoryContext TopTransactionContext
 
PGDLLIMPORT MemoryContext CurTransactionContext
 
PGDLLIMPORT MemoryContext PortalContext
 

Macro Definition Documentation

◆ AllocHugeSizeIsValid

#define AllocHugeSizeIsValid (   size)    ((Size) (size) <= MaxAllocHugeSize)

Definition at line 49 of file memutils.h.

◆ ALLOCSET_DEFAULT_INITSIZE

#define ALLOCSET_DEFAULT_INITSIZE   (8 * 1024)

Definition at line 158 of file memutils.h.

◆ ALLOCSET_DEFAULT_MAXSIZE

#define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)

Definition at line 159 of file memutils.h.

◆ ALLOCSET_DEFAULT_MINSIZE

#define ALLOCSET_DEFAULT_MINSIZE   0

Definition at line 157 of file memutils.h.

◆ ALLOCSET_DEFAULT_SIZES

Definition at line 160 of file memutils.h.

219{
220 const unsigned char *p = (const unsigned char *) ptr;
221 const unsigned char *end = &p[len];
222 const unsigned char *aligned_end = (const unsigned char *)
223 ((uintptr_t) end & (~(sizeof(size_t) - 1)));
224
225 if (len < sizeof(size_t))
226 {
227 while (p < end)
228 {
229 if (*p++ != 0)
230 return false;
231 }
232 return true;
233 }
234
235 /* "len" in the [sizeof(size_t), sizeof(size_t) * 8 - 1] range */
236 if (len < sizeof(size_t) * 8)
237 {
238 /* Compare bytes until the pointer "p" is aligned */
239 while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
240 {
241 if (p == end)
242 return true;
243 if (*p++ != 0)
244 return false;
245 }
246
247 /*
248 * Compare remaining size_t-aligned chunks.
249 *
250 * There is no risk to read beyond the memory area, as "aligned_end"
251 * cannot be higher than "end".
252 */
253 for (; p < aligned_end; p += sizeof(size_t))
254 {
255 if (*(size_t *) p != 0)
256 return false;
257 }
258
259 /* Compare remaining bytes until the end */
260 while (p < end)
261 {
262 if (*p++ != 0)
263 return false;
264 }
265 return true;
266 }
267
268 /* "len" in the [sizeof(size_t) * 8, inf) range */
269
270 /* Compare bytes until the pointer "p" is aligned */
271 while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
272 {
273 if (p == end)
274 return true;
275
276 if (*p++ != 0)
277 return false;
278 }
279
280 /*
281 * Compare 8 * sizeof(size_t) chunks at once.
282 *
283 * For performance reasons, we manually unroll this loop and purposefully
284 * use bitwise-ORs to combine each comparison. This prevents boolean
285 * short-circuiting and lets the compiler know that it's safe to access
286 * all 8 elements regardless of the result of the other comparisons. This
287 * seems to be enough to coax a few compilers into using SIMD
288 * instructions.
289 */
290 for (; p < aligned_end - (sizeof(size_t) * 7); p += sizeof(size_t) * 8)
291 {
292 if ((((size_t *) p)[0] != 0) | (((size_t *) p)[1] != 0) |
293 (((size_t *) p)[2] != 0) | (((size_t *) p)[3] != 0) |
294 (((size_t *) p)[4] != 0) | (((size_t *) p)[5] != 0) |
295 (((size_t *) p)[6] != 0) | (((size_t *) p)[7] != 0))
296 return false;
297 }
298
299 /*
300 * Compare remaining size_t-aligned chunks.
301 *
302 * There is no risk to read beyond the memory area, as "aligned_end"
303 * cannot be higher than "end".
304 */
305 for (; p < aligned_end; p += sizeof(size_t))
306 {
307 if (*(size_t *) p != 0)
308 return false;
309 }
310
311 /* Compare remaining bytes until the end */
312 while (p < end)
313 {
314 if (*p++ != 0)
315 return false;
316 }
317
318 return true;
319}
320
321#endif /* MEMUTILS_H */
const void size_t len
static int fb(int x)

◆ ALLOCSET_SEPARATE_THRESHOLD

#define ALLOCSET_SEPARATE_THRESHOLD   8192

Definition at line 187 of file memutils.h.

◆ ALLOCSET_SMALL_INITSIZE

#define ALLOCSET_SMALL_INITSIZE   (1 * 1024)

Definition at line 168 of file memutils.h.

◆ ALLOCSET_SMALL_MAXSIZE

#define ALLOCSET_SMALL_MAXSIZE   (8 * 1024)

Definition at line 169 of file memutils.h.

◆ ALLOCSET_SMALL_MINSIZE

#define ALLOCSET_SMALL_MINSIZE   0

Definition at line 167 of file memutils.h.

◆ ALLOCSET_SMALL_SIZES

Definition at line 170 of file memutils.h.

◆ ALLOCSET_START_SMALL_SIZES

Definition at line 177 of file memutils.h.

◆ AllocSetContextCreate

#define AllocSetContextCreate    AllocSetContextCreateInternal

Definition at line 129 of file memutils.h.

◆ AllocSizeIsValid

#define AllocSizeIsValid (   size)    ((Size) (size) <= MaxAllocSize)

Definition at line 42 of file memutils.h.

◆ InvalidAllocSize

#define InvalidAllocSize   SIZE_MAX

Definition at line 47 of file memutils.h.

◆ MaxAllocHugeSize

#define MaxAllocHugeSize   (SIZE_MAX / 2)

Definition at line 45 of file memutils.h.

◆ MaxAllocSize

#define MaxAllocSize   ((Size) 0x3fffffff) /* 1 gigabyte - 1 */

Definition at line 40 of file memutils.h.

◆ MemoryContextCopyAndSetIdentifier

#define MemoryContextCopyAndSetIdentifier (   cxt,
  id 
)     MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))

Definition at line 101 of file memutils.h.

◆ SLAB_DEFAULT_BLOCK_SIZE

#define SLAB_DEFAULT_BLOCK_SIZE   (8 * 1024)

Definition at line 189 of file memutils.h.

◆ SLAB_LARGE_BLOCK_SIZE

#define SLAB_LARGE_BLOCK_SIZE   (8 * 1024 * 1024)

Definition at line 190 of file memutils.h.

Function Documentation

◆ AllocSetContextCreateInternal()

MemoryContext AllocSetContextCreateInternal ( MemoryContext  parent,
const char name,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)
extern

Definition at line 343 of file aset.c.

348{
349 int freeListIndex;
351 AllocSet set;
352 AllocBlock block;
353
354 /* ensure MemoryChunk's size is properly maxaligned */
356 "sizeof(MemoryChunk) is not maxaligned");
357 /* check we have enough space to store the freelist link */
359 "sizeof(AllocFreeListLink) larger than minimum allocation size");
360
361 /*
362 * First, validate allocation parameters. Once these were regular runtime
363 * tests and elog's, but in practice Asserts seem sufficient because
364 * nobody varies their parameters at runtime. We somewhat arbitrarily
365 * enforce a minimum 1K block size. We restrict the maximum block size to
366 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
367 * regards to addressing the offset between the chunk and the block that
368 * the chunk is stored on. We would be unable to store the offset between
369 * the chunk and block for any chunks that were beyond
370 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
371 * larger than this.
372 */
373 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
374 initBlockSize >= 1024);
375 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
376 maxBlockSize >= initBlockSize &&
377 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
378 Assert(minContextSize == 0 ||
380 minContextSize >= 1024 &&
381 minContextSize <= maxBlockSize));
382 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
383
384 /*
385 * Check whether the parameters match either available freelist. We do
386 * not need to demand a match of maxBlockSize.
387 */
389 initBlockSize == ALLOCSET_DEFAULT_INITSIZE)
390 freeListIndex = 0;
392 initBlockSize == ALLOCSET_SMALL_INITSIZE)
393 freeListIndex = 1;
394 else
395 freeListIndex = -1;
396
397 /*
398 * If a suitable freelist entry exists, just recycle that context.
399 */
400 if (freeListIndex >= 0)
401 {
402 AllocSetFreeList *freelist = &context_freelists[freeListIndex];
403
404 if (freelist->first_free != NULL)
405 {
406 /* Remove entry from freelist */
407 set = freelist->first_free;
408 freelist->first_free = (AllocSet) set->header.nextchild;
409 freelist->num_free--;
410
411 /* Update its maxBlockSize; everything else should be OK */
412 set->maxBlockSize = maxBlockSize;
413
414 /* Reinitialize its header, installing correct name and parent */
418 parent,
419 name);
420
421 ((MemoryContext) set)->mem_allocated =
422 KeeperBlock(set)->endptr - ((char *) set);
423
424 return (MemoryContext) set;
425 }
426 }
427
428 /* Determine size of initial block */
431 if (minContextSize != 0)
433 else
434 firstBlockSize = Max(firstBlockSize, initBlockSize);
435
436 /*
437 * Allocate the initial block. Unlike other aset.c blocks, it starts with
438 * the context header and its block header follows that.
439 */
441 if (set == NULL)
442 {
447 errmsg("out of memory"),
448 errdetail("Failed while creating memory context \"%s\".",
449 name)));
450 }
451
452 /*
453 * Avoid writing code that can fail between here and MemoryContextCreate;
454 * we'd leak the header/initial block if we ereport in this stretch.
455 */
456
457 /* Create a vpool associated with the context */
458 VALGRIND_CREATE_MEMPOOL(set, 0, false);
459
460 /*
461 * Create a vchunk covering both the AllocSetContext struct and the keeper
462 * block's header. (Perhaps it would be more sensible for these to be two
463 * separate vchunks, but doing that seems to tickle bugs in some versions
464 * of Valgrind.) We must have these vchunks, and also a vchunk for each
465 * subsequently-added block header, so that Valgrind considers the
466 * pointers within them while checking for leaked memory. Note that
467 * Valgrind doesn't distinguish between these vchunks and those created by
468 * mcxt.c for the user-accessible-data chunks we allocate.
469 */
471
472 /* Fill in the initial block's block header */
473 block = KeeperBlock(set);
474 block->aset = set;
475 block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
476 block->endptr = ((char *) set) + firstBlockSize;
477 block->prev = NULL;
478 block->next = NULL;
479
480 /* Mark unallocated space NOACCESS; leave the block header alone. */
481 VALGRIND_MAKE_MEM_NOACCESS(block->freeptr, block->endptr - block->freeptr);
482
483 /* Remember block as part of block list */
484 set->blocks = block;
485
486 /* Finish filling in aset-specific parts of the context header */
487 MemSetAligned(set->freelist, 0, sizeof(set->freelist));
488
489 set->initBlockSize = (uint32) initBlockSize;
490 set->maxBlockSize = (uint32) maxBlockSize;
491 set->nextBlockSize = (uint32) initBlockSize;
492 set->freeListIndex = freeListIndex;
493
494 /*
495 * Compute the allocation chunk size limit for this context. It can't be
496 * more than ALLOC_CHUNK_LIMIT because of the fixed number of freelists.
497 * If maxBlockSize is small then requests exceeding the maxBlockSize, or
498 * even a significant fraction of it, should be treated as large chunks
499 * too. For the typical case of maxBlockSize a power of 2, the chunk size
500 * limit will be at most 1/8th maxBlockSize, so that given a stream of
501 * requests that are all the maximum chunk size we will waste at most
502 * 1/8th of the allocated space.
503 *
504 * Also, allocChunkLimit must not exceed ALLOCSET_SEPARATE_THRESHOLD.
505 */
507 "ALLOC_CHUNK_LIMIT != ALLOCSET_SEPARATE_THRESHOLD");
508
509 /*
510 * Determine the maximum size that a chunk can be before we allocate an
511 * entire AllocBlock dedicated for that chunk. We set the absolute limit
512 * of that size as ALLOC_CHUNK_LIMIT but we reduce it further so that we
513 * can fit about ALLOC_CHUNK_FRACTION chunks this size on a maximally
514 * sized block. (We opt to keep allocChunkLimit a power-of-2 value
515 * primarily for legacy reasons rather than calculating it so that exactly
516 * ALLOC_CHUNK_FRACTION chunks fit on a maximally sized block.)
517 */
519 while ((Size) (set->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
520 (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
521 set->allocChunkLimit >>= 1;
522
523 /* Finally, do the type-independent part of context creation */
527 parent,
528 name);
529
530 ((MemoryContext) set)->mem_allocated = firstBlockSize;
531
532 return (MemoryContext) set;
533}
#define ALLOC_CHUNKHDRSZ
Definition aset.c:105
#define KeeperBlock(set)
Definition aset.c:240
#define ALLOC_MINBITS
Definition aset.c:83
#define ALLOC_BLOCKHDRSZ
Definition aset.c:104
#define ALLOC_CHUNK_FRACTION
Definition aset.c:87
#define FIRST_BLOCKHDRSZ
Definition aset.c:106
#define ALLOC_CHUNK_LIMIT
Definition aset.c:85
static AllocSetFreeList context_freelists[2]
Definition aset.c:253
AllocSetContext * AllocSet
Definition aset.c:169
#define MAXALIGN(LEN)
Definition c.h:836
#define Max(x, y)
Definition c.h:1001
#define Assert(condition)
Definition c.h:883
#define MemSetAligned(start, val, len)
Definition c.h:1053
uint32_t uint32
Definition c.h:556
#define StaticAssertDecl(condition, errmessage)
Definition c.h:952
#define StaticAssertStmt(condition, errmessage)
Definition c.h:954
size_t Size
Definition c.h:629
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
Definition mcxt.c:1149
MemoryContext TopMemoryContext
Definition mcxt.c:166
void MemoryContextStats(MemoryContext context)
Definition mcxt.c:863
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
Definition memdebug.h:24
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
Definition memdebug.h:29
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition memdebug.h:27
#define ALLOCSET_SMALL_MINSIZE
Definition memutils.h:167
#define ALLOCSET_DEFAULT_MINSIZE
Definition memutils.h:157
#define AllocHugeSizeIsValid(size)
Definition memutils.h:49
#define ALLOCSET_SEPARATE_THRESHOLD
Definition memutils.h:187
#define ALLOCSET_SMALL_INITSIZE
Definition memutils.h:168
#define ALLOCSET_DEFAULT_INITSIZE
Definition memutils.h:158
@ MCTX_ASET_ID
#define MEMORYCHUNK_MAX_BLOCKOFFSET
struct MemoryContextData * MemoryContext
Definition palloc.h:36
#define malloc(a)
AllocBlock prev
Definition aset.c:186
AllocSet aset
Definition aset.c:185
char * freeptr
Definition aset.c:188
AllocBlock next
Definition aset.c:187
char * endptr
Definition aset.c:189
uint32 initBlockSize
Definition aset.c:161
uint32 maxBlockSize
Definition aset.c:162
uint32 allocChunkLimit
Definition aset.c:164
MemoryContextData header
Definition aset.c:156
int freeListIndex
Definition aset.c:166
AllocBlock blocks
Definition aset.c:158
uint32 nextBlockSize
Definition aset.c:163
MemoryChunk * freelist[ALLOCSET_NUM_FREELISTS]
Definition aset.c:159
AllocSetContext * first_free
Definition aset.c:249
MemoryContext nextchild
Definition memnodes.h:130
const char * name

References ALLOC_BLOCKHDRSZ, ALLOC_CHUNK_FRACTION, ALLOC_CHUNK_LIMIT, ALLOC_CHUNKHDRSZ, ALLOC_MINBITS, AllocSetContext::allocChunkLimit, AllocHugeSizeIsValid, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_SEPARATE_THRESHOLD, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MINSIZE, AllocBlockData::aset, Assert, AllocSetContext::blocks, context_freelists, AllocBlockData::endptr, ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), FIRST_BLOCKHDRSZ, AllocSetFreeList::first_free, AllocSetContext::freelist, AllocSetContext::freeListIndex, AllocBlockData::freeptr, AllocSetContext::header, AllocSetContext::initBlockSize, KeeperBlock, malloc, Max, MAXALIGN, AllocSetContext::maxBlockSize, MCTX_ASET_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MemoryContextCreate(), MemoryContextStats(), MemSetAligned, name, AllocBlockData::next, AllocSetContext::nextBlockSize, MemoryContextData::nextchild, AllocSetFreeList::num_free, AllocBlockData::prev, StaticAssertDecl, StaticAssertStmt, TopMemoryContext, VALGRIND_CREATE_MEMPOOL, VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MEMPOOL_ALLOC.

◆ BumpContextCreate()

MemoryContext BumpContextCreate ( MemoryContext  parent,
const char name,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)
extern

Definition at line 133 of file bump.c.

135{
138 BumpContext *set;
139 BumpBlock *block;
140
141 /* ensure MemoryChunk's size is properly maxaligned */
143 "sizeof(MemoryChunk) is not maxaligned");
144
145 /*
146 * First, validate allocation parameters. Asserts seem sufficient because
147 * nobody varies their parameters at runtime. We somewhat arbitrarily
148 * enforce a minimum 1K block size. We restrict the maximum block size to
149 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
150 * regards to addressing the offset between the chunk and the block that
151 * the chunk is stored on. We would be unable to store the offset between
152 * the chunk and block for any chunks that were beyond
153 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
154 * larger than this.
155 */
156 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
157 initBlockSize >= 1024);
158 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
159 maxBlockSize >= initBlockSize &&
160 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
161 Assert(minContextSize == 0 ||
163 minContextSize >= 1024 &&
164 minContextSize <= maxBlockSize));
165 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
166
167 /* Determine size of initial block */
170 if (minContextSize != 0)
172 else
173 allocSize = Max(allocSize, initBlockSize);
174
175 /*
176 * Allocate the initial block. Unlike other bump.c blocks, it starts with
177 * the context header and its block header follows that.
178 */
179 set = (BumpContext *) malloc(allocSize);
180 if (set == NULL)
181 {
185 errmsg("out of memory"),
186 errdetail("Failed while creating memory context \"%s\".",
187 name)));
188 }
189
190 /*
191 * Avoid writing code that can fail between here and MemoryContextCreate;
192 * we'd leak the header and initial block if we ereport in this stretch.
193 */
194
195 /* See comments about Valgrind interactions in aset.c */
196 VALGRIND_CREATE_MEMPOOL(set, 0, false);
197 /* This vchunk covers the BumpContext and the keeper block header */
199
200 dlist_init(&set->blocks);
201
202 /* Fill in the initial block's block header */
203 block = KeeperBlock(set);
204 /* determine the block size and initialize it */
206 BumpBlockInit(set, block, firstBlockSize);
207
208 /* add it to the doubly-linked list of blocks */
209 dlist_push_head(&set->blocks, &block->node);
210
211 /*
212 * Fill in BumpContext-specific header fields. The Asserts above should
213 * ensure that these all fit inside a uint32.
214 */
215 set->initBlockSize = (uint32) initBlockSize;
216 set->maxBlockSize = (uint32) maxBlockSize;
217 set->nextBlockSize = (uint32) initBlockSize;
218
219 /*
220 * Compute the allocation chunk size limit for this context.
221 *
222 * Limit the maximum size a non-dedicated chunk can be so that we can fit
223 * at least Bump_CHUNK_FRACTION of chunks this big onto the maximum sized
224 * block. We must further limit this value so that it's no more than
225 * MEMORYCHUNK_MAX_VALUE. We're unable to have non-external chunks larger
226 * than that value as we store the chunk size in the MemoryChunk 'value'
227 * field in the call to MemoryChunkSetHdrMask().
228 */
229 set->allocChunkLimit = Min(maxBlockSize, MEMORYCHUNK_MAX_VALUE);
230 while ((Size) (set->allocChunkLimit + Bump_CHUNKHDRSZ) >
231 (Size) ((Size) (maxBlockSize - Bump_BLOCKHDRSZ) / Bump_CHUNK_FRACTION))
232 set->allocChunkLimit >>= 1;
233
234 /* Finally, do the type-independent part of context creation */
236 parent, name);
237
238 ((MemoryContext) set)->mem_allocated = allocSize;
239
240 return (MemoryContext) set;
241}
#define Bump_CHUNK_FRACTION
Definition bump.c:59
#define KeeperBlock(set)
Definition bump.c:62
#define Bump_CHUNKHDRSZ
Definition bump.c:56
static void BumpBlockInit(BumpContext *context, BumpBlock *block, Size blksize)
Definition bump.c:561
#define Bump_BLOCKHDRSZ
Definition bump.c:48
#define FIRST_BLOCKHDRSZ
Definition bump.c:49
#define Min(x, y)
Definition c.h:1007
static void dlist_init(dlist_head *head)
Definition ilist.h:314
static void dlist_push_head(dlist_head *head, dlist_node *node)
Definition ilist.h:347
@ MCTX_BUMP_ID
#define MEMORYCHUNK_MAX_VALUE
dlist_node node
Definition bump.c:90
dlist_head blocks
Definition bump.c:78
uint32 initBlockSize
Definition bump.c:73
uint32 maxBlockSize
Definition bump.c:74
uint32 nextBlockSize
Definition bump.c:75
uint32 allocChunkLimit
Definition bump.c:76

References BumpContext::allocChunkLimit, AllocHugeSizeIsValid, Assert, BumpContext::blocks, Bump_BLOCKHDRSZ, Bump_CHUNK_FRACTION, Bump_CHUNKHDRSZ, BumpBlockInit(), dlist_init(), dlist_push_head(), ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), FIRST_BLOCKHDRSZ, BumpContext::initBlockSize, KeeperBlock, malloc, Max, MAXALIGN, BumpContext::maxBlockSize, MCTX_BUMP_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), Min, name, BumpContext::nextBlockSize, BumpBlock::node, StaticAssertDecl, TopMemoryContext, VALGRIND_CREATE_MEMPOOL, and VALGRIND_MEMPOOL_ALLOC.

Referenced by ExecInitRecursiveUnion(), ExecInitSetOp(), ExecInitSubPlan(), hash_create_memory(), TidStoreCreateLocal(), and tuplesort_begin_batch().

◆ GenerationContextCreate()

MemoryContext GenerationContextCreate ( MemoryContext  parent,
const char name,
Size  minContextSize,
Size  initBlockSize,
Size  maxBlockSize 
)
extern

Definition at line 162 of file generation.c.

167{
171 GenerationBlock *block;
172
173 /* ensure MemoryChunk's size is properly maxaligned */
175 "sizeof(MemoryChunk) is not maxaligned");
176
177 /*
178 * First, validate allocation parameters. Asserts seem sufficient because
179 * nobody varies their parameters at runtime. We somewhat arbitrarily
180 * enforce a minimum 1K block size. We restrict the maximum block size to
181 * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
182 * regards to addressing the offset between the chunk and the block that
183 * the chunk is stored on. We would be unable to store the offset between
184 * the chunk and block for any chunks that were beyond
185 * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
186 * larger than this.
187 */
188 Assert(initBlockSize == MAXALIGN(initBlockSize) &&
189 initBlockSize >= 1024);
190 Assert(maxBlockSize == MAXALIGN(maxBlockSize) &&
191 maxBlockSize >= initBlockSize &&
192 AllocHugeSizeIsValid(maxBlockSize)); /* must be safe to double */
193 Assert(minContextSize == 0 ||
195 minContextSize >= 1024 &&
196 minContextSize <= maxBlockSize));
197 Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
198
199 /* Determine size of initial block */
202 if (minContextSize != 0)
204 else
205 allocSize = Max(allocSize, initBlockSize);
206
207 /*
208 * Allocate the initial block. Unlike other generation.c blocks, it
209 * starts with the context header and its block header follows that.
210 */
212 if (set == NULL)
213 {
217 errmsg("out of memory"),
218 errdetail("Failed while creating memory context \"%s\".",
219 name)));
220 }
221
222 /*
223 * Avoid writing code that can fail between here and MemoryContextCreate;
224 * we'd leak the header if we ereport in this stretch.
225 */
226
227 /* See comments about Valgrind interactions in aset.c */
228 VALGRIND_CREATE_MEMPOOL(set, 0, false);
229 /* This vchunk covers the GenerationContext and the keeper block header */
231
232 dlist_init(&set->blocks);
233
234 /* Fill in the initial block's block header */
235 block = KeeperBlock(set);
236 /* determine the block size and initialize it */
239
240 /* add it to the doubly-linked list of blocks */
241 dlist_push_head(&set->blocks, &block->node);
242
243 /* use it as the current allocation block */
244 set->block = block;
245
246 /* No free block, yet */
247 set->freeblock = NULL;
248
249 /* Fill in GenerationContext-specific header fields */
250 set->initBlockSize = (uint32) initBlockSize;
251 set->maxBlockSize = (uint32) maxBlockSize;
252 set->nextBlockSize = (uint32) initBlockSize;
253
254 /*
255 * Compute the allocation chunk size limit for this context.
256 *
257 * Limit the maximum size a non-dedicated chunk can be so that we can fit
258 * at least Generation_CHUNK_FRACTION of chunks this big onto the maximum
259 * sized block. We must further limit this value so that it's no more
260 * than MEMORYCHUNK_MAX_VALUE. We're unable to have non-external chunks
261 * larger than that value as we store the chunk size in the MemoryChunk
262 * 'value' field in the call to MemoryChunkSetHdrMask().
263 */
264 set->allocChunkLimit = Min(maxBlockSize, MEMORYCHUNK_MAX_VALUE);
265 while ((Size) (set->allocChunkLimit + Generation_CHUNKHDRSZ) >
267 set->allocChunkLimit >>= 1;
268
269 /* Finally, do the type-independent part of context creation */
273 parent,
274 name);
275
276 ((MemoryContext) set)->mem_allocated = firstBlockSize;
277
278 return (MemoryContext) set;
279}
static void GenerationBlockInit(GenerationContext *context, GenerationBlock *block, Size blksize)
Definition generation.c:635
#define Generation_CHUNK_FRACTION
Definition generation.c:51
#define KeeperBlock(set)
Definition generation.c:129
#define Generation_CHUNKHDRSZ
Definition generation.c:47
#define FIRST_BLOCKHDRSZ
Definition generation.c:48
#define Generation_BLOCKHDRSZ
Definition generation.c:46
@ MCTX_GENERATION_ID
dlist_node node
Definition generation.c:91
GenerationBlock * freeblock
Definition generation.c:72
dlist_head blocks
Definition generation.c:74
GenerationBlock * block
Definition generation.c:71
uint32 allocChunkLimit
Definition generation.c:69

References GenerationContext::allocChunkLimit, AllocHugeSizeIsValid, Assert, GenerationContext::block, GenerationContext::blocks, dlist_init(), dlist_push_head(), ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), FIRST_BLOCKHDRSZ, GenerationContext::freeblock, Generation_BLOCKHDRSZ, Generation_CHUNK_FRACTION, Generation_CHUNKHDRSZ, GenerationBlockInit(), GenerationContext::initBlockSize, KeeperBlock, malloc, Max, MAXALIGN, GenerationContext::maxBlockSize, MCTX_GENERATION_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), Min, name, GenerationContext::nextBlockSize, GenerationBlock::node, StaticAssertDecl, TopMemoryContext, VALGRIND_CREATE_MEMPOOL, and VALGRIND_MEMPOOL_ALLOC.

Referenced by gistvacuumscan(), ReorderBufferAllocate(), and tuplestore_begin_common().

◆ GetMemoryChunkContext()

◆ GetMemoryChunkSpace()

◆ HandleLogMemoryContextInterrupt()

void HandleLogMemoryContextInterrupt ( void  )
extern

Definition at line 1323 of file mcxt.c.

1324{
1325 InterruptPending = true;
1327 /* latch will be set by procsignal_sigusr1_handler */
1328}
volatile sig_atomic_t LogMemoryContextPending
Definition globals.c:41
volatile sig_atomic_t InterruptPending
Definition globals.c:32

References InterruptPending, and LogMemoryContextPending.

Referenced by procsignal_sigusr1_handler().

◆ MemoryContextAllowInCriticalSection()

void MemoryContextAllowInCriticalSection ( MemoryContext  context,
bool  allow 
)
extern

Definition at line 743 of file mcxt.c.

744{
746
747 context->allowInCritSection = allow;
748}
#define MemoryContextIsValid(context)
Definition memnodes.h:145
bool allowInCritSection
Definition memnodes.h:124

References MemoryContextData::allowInCritSection, Assert, fb(), and MemoryContextIsValid.

Referenced by InitSync(), MemoryContextInit(), and XLOGShmemInit().

◆ MemoryContextDelete()

void MemoryContextDelete ( MemoryContext  context)
extern

Definition at line 472 of file mcxt.c.

473{
475
477
478 /*
479 * Delete subcontexts from the bottom up.
480 *
481 * Note: Do not use recursion here. A "stack depth limit exceeded" error
482 * would be unpleasant if we're already in the process of cleaning up from
483 * transaction abort. We also cannot use MemoryContextTraverseNext() here
484 * because we modify the tree as we go.
485 */
486 curr = context;
487 for (;;)
488 {
489 MemoryContext parent;
490
491 /* Descend down until we find a leaf context with no children */
492 while (curr->firstchild != NULL)
494
495 /*
496 * We're now at a leaf with no children. Free it and continue from the
497 * parent. Or if this was the original node, we're all done.
498 */
499 parent = curr->parent;
501
502 if (curr == context)
503 break;
504 curr = parent;
505 }
506}
static void MemoryContextDeleteOnly(MemoryContext context)
Definition mcxt.c:514
MemoryContext firstchild
Definition memnodes.h:128
MemoryContext parent
Definition memnodes.h:127

References Assert, fb(), MemoryContextData::firstchild, MemoryContextDeleteOnly(), MemoryContextIsValid, and MemoryContextData::parent.

Referenced by _brin_parallel_merge(), AfterTriggerEndXact(), afterTriggerInvokeEvents(), ApplyLauncherMain(), AtEOSubXact_SPI(), AtEOXact_LargeObject(), AtSubCleanup_Memory(), AtSubCommit_Memory(), AttachPartitionEnsureIndexes(), AutoVacLauncherMain(), autovacuum_do_vac_analyze(), AutoVacWorkerMain(), AuxiliaryProcessMainCommon(), BackgroundWorkerMain(), blbuild(), blinsert(), brin_free_desc(), brin_minmax_multi_union(), bringetbitmap(), brininsert(), bt_check_every_level(), btendscan(), btree_xlog_cleanup(), btvacuumscan(), BuildParamLogString(), BuildRelationExtStatistics(), CloneRowTriggersToPartition(), cluster(), compactify_ranges(), compile_plperl_function(), compile_pltcl_function(), compute_expr_stats(), compute_index_stats(), ComputeExtStatisticsRows(), createTrgmNFA(), CreateTriggerFiringOn(), daitch_mokotoff(), decr_dcc_refcount(), DeleteExpandedObject(), DiscreteKnapsack(), do_analyze_rel(), do_start_worker(), DoCopyTo(), DropCachedPlan(), each_worker(), each_worker_jsonb(), elements_worker(), elements_worker_jsonb(), end_heap_rewrite(), EndCopy(), EndCopyFrom(), ensure_free_space_in_buffer(), EventTriggerEndCompleteQuery(), EventTriggerInvoke(), exec_simple_query(), ExecEndAgg(), ExecEndMemoize(), ExecEndRecursiveUnion(), ExecEndSetOp(), ExecEndWindowAgg(), ExecHashTableDestroy(), execute_sql_string(), ExecVacuum(), file_acquire_sample_rows(), fill_hba_view(), fill_ident_view(), free_auth_file(), free_plperl_function(), FreeCachedExpression(), FreeDecodingContext(), FreeExecutorState(), FreeExprContext(), freeGISTstate(), FreeSnapshotBuilder(), geqo_eval(), get_actual_variable_range(), get_rel_sync_entry(), GetWALRecordsInfo(), GetXLogSummaryStats(), gin_check_parent_keys_consistency(), gin_check_posting_tree_parent_keys_consistency(), gin_xlog_cleanup(), ginbuild(), ginbulkdelete(), ginendscan(), gininsert(), ginInsertCleanup(), ginPlaceToPage(), gist_xlog_cleanup(), gistbuild(), gistvacuumscan(), hash_destroy(), inline_function(), inline_function_in_from(), libpqrcv_processTuples(), load_hba(), load_ident(), load_tzoffsets(), makeArrayResultArr(), makeMdArrayResult(), materializeQueryResult(), MemoryContextDeleteChildren(), NIFinishBuild(), pg_backup_stop(), pg_decode_shutdown(), pg_get_wal_block_info(), pgstat_clear_backend_activity_snapshot(), pgstat_clear_snapshot(), plperl_spi_freeplan(), plperl_spi_prepare(), plpgsql_free_function_memory(), pltcl_handler(), pltcl_SPI_prepare(), PLy_cursor_dealloc(), PLy_cursor_plan(), PLy_plan_dealloc(), PLy_pop_execution_context(), PLy_procedure_delete(), PLy_spi_execute_fetch_result(), PLy_spi_execute_plan(), PortalDrop(), PostgresMain(), postquel_end(), prepare_next_query(), printtup_shutdown(), ProcessConfigFile(), publicationListToArray(), RE_compile_and_cache(), rebuild_database_list(), ReindexMultipleTables(), ReindexPartitions(), ReindexRelationConcurrently(), RelationBuildDesc(), RelationBuildRuleLock(), RelationDestroyRelation(), ReleaseCachedPlan(), ReorderBufferFree(), ResetUnloggedRelations(), RevalidateCachedQuery(), serializeAnalyzeShutdown(), shdepReassignOwned(), shutdown_MultiFuncCall(), spg_xlog_cleanup(), spgbuild(), spgendscan(), spginsert(), SPI_finish(), SPI_freeplan(), SPI_freetuptable(), sql_delete_callback(), statext_dependencies_build(), strlist_to_textarray(), SysLoggerMain(), test_pattern(), TidStoreDestroy(), tokenize_auth_file(), tuplesort_end(), tuplestore_end(), union_tuples(), UploadManifest(), and validateForeignKeyConstraint().

◆ MemoryContextDeleteChildren()

void MemoryContextDeleteChildren ( MemoryContext  context)
extern

Definition at line 555 of file mcxt.c.

556{
558
559 /*
560 * MemoryContextDelete will delink the child from me, so just iterate as
561 * long as there is a child.
562 */
563 while (context->firstchild != NULL)
565}
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472

References Assert, fb(), MemoryContextData::firstchild, MemoryContextDelete(), and MemoryContextIsValid.

Referenced by AtAbort_Portals(), AtSubAbort_Portals(), exec_stmt_block(), MemoryContextReset(), PersistHoldablePortal(), PortalRunMulti(), and RelationCloseCleanup().

◆ MemoryContextGetParent()

MemoryContext MemoryContextGetParent ( MemoryContext  context)
extern

◆ MemoryContextInit()

void MemoryContextInit ( void  )
extern

Definition at line 359 of file mcxt.c.

360{
362
363 /*
364 * First, initialize TopMemoryContext, which is the parent of all others.
365 */
367 "TopMemoryContext",
369
370 /*
371 * Not having any other place to point CurrentMemoryContext, make it point
372 * to TopMemoryContext. Caller should change this soon!
373 */
375
376 /*
377 * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
378 * we don't really expect much to be allocated in it. More to the point,
379 * require it to contain at least 8K at all times. This is the only case
380 * where retained memory in a context is *essential* --- we want to be
381 * sure ErrorContext still has some memory even if we've run out
382 * elsewhere! Also, allow allocations in ErrorContext within a critical
383 * section. Otherwise a PANIC will cause an assertion failure in the error
384 * reporting code, before printing out the real cause of the failure.
385 *
386 * This should be the last step in this function, as elog.c assumes memory
387 * management works once ErrorContext is non-null.
388 */
390 "ErrorContext",
391 8 * 1024,
392 8 * 1024,
393 8 * 1024);
395}
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
MemoryContext ErrorContext
Definition mcxt.c:167
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition mcxt.c:743
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, ErrorContext, fb(), MemoryContextAllowInCriticalSection(), and TopMemoryContext.

Referenced by main().

◆ MemoryContextIsEmpty()

bool MemoryContextIsEmpty ( MemoryContext  context)
extern

Definition at line 792 of file mcxt.c.

793{
795
796 /*
797 * For now, we consider a memory context nonempty if it has any children;
798 * perhaps this should be changed later.
799 */
800 if (context->firstchild != NULL)
801 return false;
802 /* Otherwise use the type-specific inquiry */
803 return context->methods->is_empty(context);
804}
const MemoryContextMethods * methods
Definition memnodes.h:126
bool(* is_empty)(MemoryContext context)
Definition memnodes.h:101

References Assert, fb(), MemoryContextData::firstchild, MemoryContextMethods::is_empty, MemoryContextIsValid, and MemoryContextData::methods.

Referenced by AtSubCommit_Memory().

◆ MemoryContextMemAllocated()

Size MemoryContextMemAllocated ( MemoryContext  context,
bool  recurse 
)
extern

Definition at line 811 of file mcxt.c.

812{
813 Size total = context->mem_allocated;
814
816
817 if (recurse)
818 {
819 for (MemoryContext curr = context->firstchild;
820 curr != NULL;
822 {
823 total += curr->mem_allocated;
824 }
825 }
826
827 return total;
828}
static MemoryContext MemoryContextTraverseNext(MemoryContext curr, MemoryContext top)
Definition mcxt.c:277

References Assert, fb(), MemoryContextData::firstchild, MemoryContextData::mem_allocated, MemoryContextIsValid, and MemoryContextTraverseNext().

Referenced by hash_agg_check_limits(), hash_agg_update_metrics(), and RT_MEMORY_USAGE().

◆ MemoryContextMemConsumed()

void MemoryContextMemConsumed ( MemoryContext  context,
MemoryContextCounters consumed 
)
extern

Definition at line 835 of file mcxt.c.

837{
839
840 memset(consumed, 0, sizeof(*consumed));
841
842 /* Examine the context itself */
843 context->methods->stats(context, NULL, NULL, consumed, false);
844
845 /* Examine children, using iteration not recursion */
846 for (MemoryContext curr = context->firstchild;
847 curr != NULL;
849 {
850 curr->methods->stats(curr, NULL, NULL, consumed, false);
851 }
852}
void(* stats)(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
Definition memnodes.h:102

References Assert, fb(), MemoryContextData::firstchild, MemoryContextIsValid, MemoryContextTraverseNext(), MemoryContextData::methods, and MemoryContextMethods::stats.

Referenced by ExplainExecuteQuery(), and standard_ExplainOneQuery().

◆ MemoryContextReset()

void MemoryContextReset ( MemoryContext  context)
extern

Definition at line 403 of file mcxt.c.

404{
406
407 /* save a function call in common case where there are no children */
408 if (context->firstchild != NULL)
410
411 /* save a function call if no pallocs since startup or last reset */
412 if (!context->isReset)
413 MemoryContextResetOnly(context);
414}
void MemoryContextDeleteChildren(MemoryContext context)
Definition mcxt.c:555
void MemoryContextResetOnly(MemoryContext context)
Definition mcxt.c:422

References Assert, fb(), MemoryContextData::firstchild, MemoryContextData::isReset, MemoryContextDeleteChildren(), MemoryContextIsValid, and MemoryContextResetOnly().

Referenced by _brin_parallel_merge(), _bt_preprocess_array_keys(), _gin_parallel_merge(), _SPI_end_call(), AfterTriggerExecute(), apply_spooled_messages(), AtCleanup_Memory(), AtCommit_Memory(), AtEOSubXact_SPI(), AtSubCleanup_Memory(), AutoVacLauncherMain(), BackgroundWriterMain(), bloomBuildCallback(), brin_memtuple_initialize(), bringetbitmap(), brininsert(), bt_check_level_from_leftmost(), btree_redo(), btvacuumpage(), BuildEventTriggerCache(), BuildRelationExtStatistics(), cache_purge_all(), check_domain_for_new_field(), check_domain_for_new_tuple(), CheckpointerMain(), CloneRowTriggersToPartition(), compute_expr_stats(), compute_index_stats(), CopyOneRowTo(), CreateTriggerFiringOn(), do_analyze_rel(), do_autovacuum(), dumptuples(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), elements_worker_jsonb(), errfinish(), errstart(), eval_windowaggregates(), EventTriggerInvoke(), exec_dynquery_with_params(), exec_replication_command(), exec_stmt_block(), exec_stmt_dynexecute(), exec_stmt_forc(), exec_stmt_foreach_a(), exec_stmt_open(), exec_stmt_raise(), exec_stmt_return_query(), ExecFindMatchingSubPlans(), ExecHashTableReset(), ExecMakeTableFunctionResult(), ExecProjectSet(), ExecQualAndReset(), ExecRecursiveUnion(), execTuplesUnequal(), execute_foreign_modify(), expanded_record_set_field_internal(), expanded_record_set_tuple(), fetch_more_data(), file_acquire_sample_rows(), FlushErrorState(), get_rel_sync_entry(), get_short_term_cxt(), GetWALRecordsInfo(), GetXLogSummaryStats(), gin_redo(), ginBuildCallback(), ginFlushBuildState(), ginFreeScanKeys(), ginHeapTupleBulkInsert(), ginInsertCleanup(), ginVacuumPostingTreeLeaves(), gist_indexsortbuild(), gist_redo(), gistBuildCallback(), gistgetbitmap(), gistgettuple(), gistinsert(), gistProcessEmptyingQueue(), gistrescan(), gistScanPage(), gistSortedBuildCallback(), heapam_index_build_range_scan(), heapam_index_validate_scan(), IndexCheckExclusion(), init_execution_state(), initialize_windowaggregate(), InvalidateEventCacheCallback(), keyGetItem(), libpqrcv_processTuples(), LogicalParallelApplyLoop(), LogicalRepApplyLoop(), lookup_ts_dictionary_cache(), make_tuple_from_result_row(), perform_work_item(), pg_backup_start(), pg_decode_change(), pg_decode_truncate(), pg_get_wal_block_info(), pgarch_archiveXlog(), pgoutput_change(), pgoutput_truncate(), plperl_return_next_internal(), PLy_input_convert(), PLy_input_from_tuple(), PostgresMain(), printtup(), process_ordered_aggregate_single(), ProcessParallelApplyMessages(), ProcessParallelMessages(), release_partition(), ReScanExprContext(), resetSpGistScanOpaque(), ResetTupleHashTable(), RT_FREE(), scanPendingInsert(), sepgsql_avc_reset(), serializeAnalyzeReceive(), spcache_init(), spg_redo(), spginsert(), spgistBuildCallback(), spgWalk(), startScanKey(), statext_dependencies_build(), storeRow(), stream_stop_internal(), tfuncFetchRows(), tfuncLoadRows(), tuplesort_free(), tuplestore_clear(), validateForeignKeyConstraint(), WalSummarizerMain(), and WalWriterMain().

◆ MemoryContextResetChildren()

void MemoryContextResetChildren ( MemoryContext  context)
extern

Definition at line 451 of file mcxt.c.

452{
454
455 for (MemoryContext curr = context->firstchild;
456 curr != NULL;
458 {
460 }
461}

References Assert, fb(), MemoryContextData::firstchild, MemoryContextIsValid, MemoryContextResetOnly(), and MemoryContextTraverseNext().

◆ MemoryContextResetOnly()

void MemoryContextResetOnly ( MemoryContext  context)
extern

Definition at line 422 of file mcxt.c.

423{
425
426 /* Nothing to do if no pallocs since startup or last reset */
427 if (!context->isReset)
428 {
430
431 /*
432 * If context->ident points into the context's memory, it will become
433 * a dangling pointer. We could prevent that by setting it to NULL
434 * here, but that would break valid coding patterns that keep the
435 * ident elsewhere, e.g. in a parent context. So for now we assume
436 * the programmer got it right.
437 */
438
439 context->methods->reset(context);
440 context->isReset = true;
441 }
442}
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition mcxt.c:634
void(* reset)(MemoryContext context)
Definition memnodes.h:83

References Assert, MemoryContextData::isReset, MemoryContextCallResetCallbacks(), MemoryContextIsValid, MemoryContextData::methods, and MemoryContextMethods::reset.

Referenced by AllocSetDelete(), JsonTableResetRowPattern(), MemoryContextReset(), MemoryContextResetChildren(), and mergeruns().

◆ MemoryContextSetIdentifier()

◆ MemoryContextSetParent()

void MemoryContextSetParent ( MemoryContext  context,
MemoryContext  new_parent 
)
extern

Definition at line 686 of file mcxt.c.

687{
689 Assert(context != new_parent);
690
691 /* Fast path if it's got correct parent already */
692 if (new_parent == context->parent)
693 return;
694
695 /* Delink from existing parent, if any */
696 if (context->parent)
697 {
698 MemoryContext parent = context->parent;
699
700 if (context->prevchild != NULL)
701 context->prevchild->nextchild = context->nextchild;
702 else
703 {
704 Assert(parent->firstchild == context);
705 parent->firstchild = context->nextchild;
706 }
707
708 if (context->nextchild != NULL)
709 context->nextchild->prevchild = context->prevchild;
710 }
711
712 /* And relink */
713 if (new_parent)
714 {
716 context->parent = new_parent;
717 context->prevchild = NULL;
718 context->nextchild = new_parent->firstchild;
719 if (new_parent->firstchild != NULL)
720 new_parent->firstchild->prevchild = context;
721 new_parent->firstchild = context;
722 }
723 else
724 {
725 context->parent = NULL;
726 context->prevchild = NULL;
727 context->nextchild = NULL;
728 }
729}
MemoryContext prevchild
Definition memnodes.h:129

References Assert, fb(), MemoryContextData::firstchild, MemoryContextIsValid, MemoryContextData::nextchild, MemoryContextData::parent, and MemoryContextData::prevchild.

Referenced by _SPI_save_plan(), CachedPlanSetParentContext(), CompleteCachedPlan(), exec_parse_message(), GetCachedExpression(), GetCachedPlan(), load_domaintype_info(), MemoryContextDeleteOnly(), plpgsql_compile_callback(), RE_compile_and_cache(), RelationBuildPartitionDesc(), RelationBuildPartitionKey(), RelationBuildRowSecurity(), RelationRebuildRelation(), RevalidateCachedQuery(), SaveCachedPlan(), SPI_keepplan(), sql_compile_callback(), TransferExpandedObject(), and UploadManifest().

◆ MemoryContextStats()

void MemoryContextStats ( MemoryContext  context)
extern

Definition at line 863 of file mcxt.c.

864{
865 /* Hard-wired limits are usually good enough */
866 MemoryContextStatsDetail(context, 100, 100, true);
867}
void MemoryContextStatsDetail(MemoryContext context, int max_level, int max_children, bool print_to_stderr)
Definition mcxt.c:878

References MemoryContextStatsDetail().

Referenced by AllocSetContextCreateInternal(), BumpContextCreate(), finish_xact_command(), GenerationContextCreate(), MemoryContextAllocationFailure(), SlabContextCreate(), and test_pattern().

◆ MemoryContextStatsDetail()

void MemoryContextStatsDetail ( MemoryContext  context,
int  max_level,
int  max_children,
bool  print_to_stderr 
)
extern

Definition at line 878 of file mcxt.c.

881{
883
884 memset(&grand_totals, 0, sizeof(grand_totals));
885
888
889 if (print_to_stderr)
891 "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
892 grand_totals.totalspace, grand_totals.nblocks,
893 grand_totals.freespace, grand_totals.freechunks,
894 grand_totals.totalspace - grand_totals.freespace);
895 else
896 {
897 /*
898 * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
899 * to the connected client.
900 *
901 * We don't buffer the information about all memory contexts in a
902 * backend into StringInfo and log it as one message. That would
903 * require the buffer to be enlarged, risking an OOM as there could be
904 * a large number of memory contexts in a backend. Instead, we log
905 * one message per memory context.
906 */
908 (errhidestmt(true),
909 errhidecontext(true),
910 errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
911 grand_totals.totalspace, grand_totals.nblocks,
912 grand_totals.freespace, grand_totals.freechunks,
913 grand_totals.totalspace - grand_totals.freespace)));
914 }
915}
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
int errmsg_internal(const char *fmt,...)
Definition elog.c:1170
int errhidestmt(bool hide_stmt)
Definition elog.c:1445
int errhidecontext(bool hide_ctx)
Definition elog.c:1464
#define LOG_SERVER_ONLY
Definition elog.h:32
static void MemoryContextStatsInternal(MemoryContext context, int level, int max_level, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
Definition mcxt.c:925

References ereport, errhidecontext(), errhidestmt(), errmsg_internal(), fb(), fprintf, LOG_SERVER_ONLY, and MemoryContextStatsInternal().

Referenced by MemoryContextStats(), and ProcessLogMemoryContextInterrupt().

◆ pg_memory_is_all_zeros()

static bool pg_memory_is_all_zeros ( const void ptr,
size_t  len 
)
inlinestatic

Definition at line 219 of file memutils.h.

220{
221 const unsigned char *p = (const unsigned char *) ptr;
222 const unsigned char *end = &p[len];
223 const unsigned char *aligned_end = (const unsigned char *)
224 ((uintptr_t) end & (~(sizeof(size_t) - 1)));
225
226 if (len < sizeof(size_t))
227 {
228 while (p < end)
229 {
230 if (*p++ != 0)
231 return false;
232 }
233 return true;
234 }
235
236 /* "len" in the [sizeof(size_t), sizeof(size_t) * 8 - 1] range */
237 if (len < sizeof(size_t) * 8)
238 {
239 /* Compare bytes until the pointer "p" is aligned */
240 while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
241 {
242 if (p == end)
243 return true;
244 if (*p++ != 0)
245 return false;
246 }
247
248 /*
249 * Compare remaining size_t-aligned chunks.
250 *
251 * There is no risk to read beyond the memory area, as "aligned_end"
252 * cannot be higher than "end".
253 */
254 for (; p < aligned_end; p += sizeof(size_t))
255 {
256 if (*(size_t *) p != 0)
257 return false;
258 }
259
260 /* Compare remaining bytes until the end */
261 while (p < end)
262 {
263 if (*p++ != 0)
264 return false;
265 }
266 return true;
267 }
268
269 /* "len" in the [sizeof(size_t) * 8, inf) range */
270
271 /* Compare bytes until the pointer "p" is aligned */
272 while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
273 {
274 if (p == end)
275 return true;
276
277 if (*p++ != 0)
278 return false;
279 }
280
281 /*
282 * Compare 8 * sizeof(size_t) chunks at once.
283 *
284 * For performance reasons, we manually unroll this loop and purposefully
285 * use bitwise-ORs to combine each comparison. This prevents boolean
286 * short-circuiting and lets the compiler know that it's safe to access
287 * all 8 elements regardless of the result of the other comparisons. This
288 * seems to be enough to coax a few compilers into using SIMD
289 * instructions.
290 */
291 for (; p < aligned_end - (sizeof(size_t) * 7); p += sizeof(size_t) * 8)
292 {
293 if ((((size_t *) p)[0] != 0) | (((size_t *) p)[1] != 0) |
294 (((size_t *) p)[2] != 0) | (((size_t *) p)[3] != 0) |
295 (((size_t *) p)[4] != 0) | (((size_t *) p)[5] != 0) |
296 (((size_t *) p)[6] != 0) | (((size_t *) p)[7] != 0))
297 return false;
298 }
299
300 /*
301 * Compare remaining size_t-aligned chunks.
302 *
303 * There is no risk to read beyond the memory area, as "aligned_end"
304 * cannot be higher than "end".
305 */
306 for (; p < aligned_end; p += sizeof(size_t))
307 {
308 if (*(size_t *) p != 0)
309 return false;
310 }
311
312 /* Compare remaining bytes until the end */
313 while (p < end)
314 {
315 if (*p++ != 0)
316 return false;
317 }
318
319 return true;
320}

References fb(), and len.

Referenced by PageIsVerified(), pg_stat_get_activity(), pg_stat_get_backend_client_addr(), pg_stat_get_backend_client_port(), pgstat_relation_flush_cb(), pgstat_report_bgwriter(), and pgstat_report_checkpointer().

◆ ProcessLogMemoryContextInterrupt()

void ProcessLogMemoryContextInterrupt ( void  )
extern

Definition at line 1340 of file mcxt.c.

1341{
1343
1344 /*
1345 * Exit immediately if memory context logging is already in progress. This
1346 * prevents recursive calls, which could occur if logging is requested
1347 * repeatedly and rapidly, potentially leading to infinite recursion and a
1348 * crash.
1349 */
1351 return;
1353
1354 PG_TRY();
1355 {
1356 /*
1357 * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1358 * connected client.
1359 */
1361 (errhidestmt(true),
1362 errhidecontext(true),
1363 errmsg("logging memory contexts of PID %d", MyProcPid)));
1364
1365 /*
1366 * When a backend process is consuming huge memory, logging all its
1367 * memory contexts might overrun available disk space. To prevent
1368 * this, we limit the depth of the hierarchy, as well as the number of
1369 * child contexts to log per parent to 100.
1370 *
1371 * As with MemoryContextStats(), we suppose that practical cases where
1372 * the dump gets long will typically be huge numbers of siblings under
1373 * the same parent context; while the additional debugging value from
1374 * seeing details about individual siblings beyond 100 will not be
1375 * large.
1376 */
1378 }
1379 PG_FINALLY();
1380 {
1382 }
1383 PG_END_TRY();
1384}
#define PG_TRY(...)
Definition elog.h:372
#define PG_END_TRY(...)
Definition elog.h:397
#define PG_FINALLY(...)
Definition elog.h:389
int MyProcPid
Definition globals.c:47
static bool LogMemoryContextInProgress
Definition mcxt.c:178

References ereport, errhidecontext(), errhidestmt(), errmsg(), LOG_SERVER_ONLY, LogMemoryContextInProgress, LogMemoryContextPending, MemoryContextStatsDetail(), MyProcPid, PG_END_TRY, PG_FINALLY, PG_TRY, and TopMemoryContext.

Referenced by ProcessAutoVacLauncherInterrupts(), ProcessCheckpointerInterrupts(), ProcessInterrupts(), ProcessMainLoopInterrupts(), ProcessPgArchInterrupts(), ProcessStartupProcInterrupts(), and ProcessWalSummarizerInterrupts().

◆ SlabContextCreate()

MemoryContext SlabContextCreate ( MemoryContext  parent,
const char name,
Size  blockSize,
Size  chunkSize 
)
extern

Definition at line 322 of file slab.c.

326{
327 int chunksPerBlock;
328 Size fullChunkSize;
329 SlabContext *slab;
330 int i;
331
332 /* ensure MemoryChunk's size is properly maxaligned */
334 "sizeof(MemoryChunk) is not maxaligned");
336
337 /*
338 * Ensure there's enough space to store the pointer to the next free chunk
339 * in the memory of the (otherwise) unused allocation.
340 */
341 if (chunkSize < sizeof(MemoryChunk *))
342 chunkSize = sizeof(MemoryChunk *);
343
344 /* length of the maxaligned chunk including the chunk header */
345#ifdef MEMORY_CONTEXT_CHECKING
346 /* ensure there's always space for the sentinel byte */
347 fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize + 1);
348#else
349 fullChunkSize = Slab_CHUNKHDRSZ + MAXALIGN(chunkSize);
350#endif
351
352 Assert(fullChunkSize <= MEMORYCHUNK_MAX_VALUE);
353
354 /* compute the number of chunks that will fit on each block */
355 chunksPerBlock = (blockSize - Slab_BLOCKHDRSZ) / fullChunkSize;
356
357 /* Make sure the block can store at least one chunk. */
358 if (chunksPerBlock == 0)
359 elog(ERROR, "block size %zu for slab is too small for %zu-byte chunks",
360 blockSize, chunkSize);
361
362
363
364 slab = (SlabContext *) malloc(Slab_CONTEXT_HDRSZ(chunksPerBlock));
365 if (slab == NULL)
366 {
370 errmsg("out of memory"),
371 errdetail("Failed while creating memory context \"%s\".",
372 name)));
373 }
374
375 /*
376 * Avoid writing code that can fail between here and MemoryContextCreate;
377 * we'd leak the header if we ereport in this stretch.
378 */
379
380 /* See comments about Valgrind interactions in aset.c */
381 VALGRIND_CREATE_MEMPOOL(slab, 0, false);
382 /* This vchunk covers the SlabContext only */
383 VALGRIND_MEMPOOL_ALLOC(slab, slab, sizeof(SlabContext));
384
385 /* Fill in SlabContext-specific header fields */
386 slab->chunkSize = (uint32) chunkSize;
387 slab->fullChunkSize = (uint32) fullChunkSize;
388 slab->blockSize = (uint32) blockSize;
389 slab->chunksPerBlock = chunksPerBlock;
390 slab->curBlocklistIndex = 0;
391
392 /*
393 * Compute a shift that guarantees that shifting chunksPerBlock with it is
394 * < SLAB_BLOCKLIST_COUNT - 1. The reason that we subtract 1 from
395 * SLAB_BLOCKLIST_COUNT in this calculation is that we reserve the 0th
396 * blocklist element for blocks which have no free chunks.
397 *
398 * We calculate the number of bits to shift by rather than a divisor to
399 * divide by as performing division each time we need to find the
400 * blocklist index would be much slower.
401 */
402 slab->blocklist_shift = 0;
403 while ((slab->chunksPerBlock >> slab->blocklist_shift) >= (SLAB_BLOCKLIST_COUNT - 1))
404 slab->blocklist_shift++;
405
406 /* initialize the list to store empty blocks to be reused */
407 dclist_init(&slab->emptyblocks);
408
409 /* initialize each blocklist slot */
410 for (i = 0; i < SLAB_BLOCKLIST_COUNT; i++)
411 dlist_init(&slab->blocklist[i]);
412
413#ifdef MEMORY_CONTEXT_CHECKING
414 /* set the isChunkFree pointer right after the end of the context */
415 slab->isChunkFree = (bool *) ((char *) slab + sizeof(SlabContext));
416#endif
417
418 /* Finally, do the type-independent part of context creation */
422 parent,
423 name);
424
425 return (MemoryContext) slab;
426}
#define elog(elevel,...)
Definition elog.h:226
static void dclist_init(dclist_head *head)
Definition ilist.h:671
int i
Definition isn.c:77
@ MCTX_SLAB_ID
#define Slab_BLOCKHDRSZ
Definition slab.c:77
#define Slab_CHUNKHDRSZ
Definition slab.c:157
#define Slab_CONTEXT_HDRSZ(chunksPerBlock)
Definition slab.c:88
#define SLAB_BLOCKLIST_COUNT
Definition slab.c:95
dlist_head blocklist[SLAB_BLOCKLIST_COUNT]
Definition slab.c:129
int32 chunksPerBlock
Definition slab.c:110
uint32 fullChunkSize
Definition slab.c:108
uint32 blockSize
Definition slab.c:109
int32 curBlocklistIndex
Definition slab.c:111
int32 blocklist_shift
Definition slab.c:118
uint32 chunkSize
Definition slab.c:107
dclist_head emptyblocks
Definition slab.c:120

References Assert, SlabContext::blocklist, SlabContext::blocklist_shift, SlabContext::blockSize, SlabContext::chunkSize, SlabContext::chunksPerBlock, SlabContext::curBlocklistIndex, dclist_init(), dlist_init(), elog, SlabContext::emptyblocks, ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), SlabContext::fullChunkSize, i, malloc, MAXALIGN, MCTX_SLAB_ID, MEMORYCHUNK_MAX_BLOCKOFFSET, MEMORYCHUNK_MAX_VALUE, MemoryContextCreate(), MemoryContextStats(), name, Slab_BLOCKHDRSZ, SLAB_BLOCKLIST_COUNT, Slab_CHUNKHDRSZ, Slab_CONTEXT_HDRSZ, StaticAssertDecl, TopMemoryContext, VALGRIND_CREATE_MEMPOOL, and VALGRIND_MEMPOOL_ALLOC.

Referenced by for(), ReorderBufferAllocate(), and test_random().

Variable Documentation

◆ CacheMemoryContext

PGDLLIMPORT MemoryContext CacheMemoryContext
extern

Definition at line 169 of file mcxt.c.

Referenced by _SPI_save_plan(), AllocateRelationDesc(), assign_record_type_typmod(), AttrDefaultFetch(), BuildEventTriggerCache(), BuildHardcodedDescriptor(), CatalogCacheCreateEntry(), CatalogCacheInitializeCache(), CheckNNConstraintFetch(), CreateCacheMemoryContext(), ensure_record_cache_typmod_slot_exists(), FetchRelationStates(), generate_partition_qual(), get_attribute_options(), get_tablespace(), GetCachedExpression(), GetCachedPlan(), GetFdwRoutineForRelation(), init_ts_config_cache(), InitCatCache(), InitializeAttoptCache(), InitializeRelfilenumberMap(), InitializeTableSpaceCache(), load_domaintype_info(), load_enum_cache_data(), load_rangetype_info(), load_relcache_init_file(), logicalrep_partmap_init(), logicalrep_relmap_init(), lookup_ts_config_cache(), lookup_ts_dictionary_cache(), lookup_ts_parser_cache(), lookup_type_cache(), LookupOpclassInfo(), pgoutput_startup(), plpgsql_compile_callback(), register_on_commit_action(), RehashCatCache(), RehashCatCacheLists(), RelationBuildLocalRelation(), RelationBuildPartitionDesc(), RelationBuildPartitionKey(), RelationBuildPublicationDesc(), RelationBuildRowSecurity(), RelationBuildRuleLock(), RelationBuildTriggers(), RelationBuildTupleDesc(), RelationCacheInitialize(), RelationCacheInitializePhase2(), RelationCacheInitializePhase3(), RelationGetFKeyList(), RelationGetIdentityKeyBitmap(), RelationGetIndexAttrBitmap(), RelationGetIndexList(), RelationGetStatExtList(), RelationInitIndexAccessInfo(), RelationParseRelOptions(), RememberToFreeTupleDescAtEOX(), SaveCachedPlan(), SearchCatCacheList(), set_schema_sent_in_streamed_txn(), SPI_keepplan(), sql_compile_callback(), and UploadManifest().

◆ CurTransactionContext

◆ ErrorContext

◆ MessageContext

◆ PortalContext

◆ PostmasterContext

◆ TopMemoryContext

PGDLLIMPORT MemoryContext TopMemoryContext
extern

Definition at line 166 of file mcxt.c.

Referenced by _PG_init(), AbortOutOfAnyTransaction(), add_reloption(), allocate_reloption(), AllocateAttribute(), AllocSetContextCreateInternal(), ApplyLauncherMain(), AtAbort_Memory(), AtStart_Memory(), AttachSession(), AutoVacLauncherMain(), BackendInitialize(), BackendMain(), BackgroundWorkerMain(), BackgroundWriterMain(), BaseBackupAddTarget(), be_tls_open_server(), build_guc_variables(), BumpContextCreate(), cache_single_string(), cached_function_compile(), cfunc_hashtable_insert(), check_foreign_key(), check_primary_key(), CheckpointerMain(), ClientAuthentication(), compile_plperl_function(), compile_pltcl_function(), CreateCacheMemoryContext(), CreateWaitEventSet(), dblink_init(), DCH_cache_getnew(), do_autovacuum(), dsm_create_descriptor(), dsm_impl_sysv(), EnablePortalManager(), EventTriggerBeginCompleteQuery(), exec_replication_command(), executeDateTimeMethod(), find_plan(), finish_xact_command(), GenerationContextCreate(), GetExplainExtensionId(), GetLocalBufferStorage(), GetLockConflicts(), getmissingattr(), GetNamedDSA(), GetNamedDSHash(), GetNamedDSMSegment(), GetPlannerExtensionId(), GetSessionDsmHandle(), hash_create(), init_database_collation(), init_missing_cache(), init_string_reloption(), InitDeadLockChecking(), initGlobalChannelTable(), initialize_reloptions(), initialize_target_list(), InitializeClientEncoding(), InitializeLogRepWorker(), InitializeParallelDSM(), InitializeSearchPath(), InitializeSession(), InitializeSystemUser(), InitPgFdwOptions(), InitSync(), InitWalSender(), InitXLogInsert(), injection_points_attach(), injection_points_detach(), llvm_compile_module(), llvm_create_context(), llvm_session_initialize(), LockAcquireExtended(), logicalrep_launcher_attach_dshmem(), LogicalRepApplyLoop(), mdinit(), MemoryContextAllocationFailure(), MemoryContextDeleteOnly(), MemoryContextInit(), mxid_to_string(), newLOfd(), NUM_cache_getnew(), on_dsm_detach(), PageSetChecksumCopy(), ParallelWorkerMain(), PerformAuthentication(), pg_backup_start(), pg_get_backend_memory_contexts(), pg_get_dsm_registry_allocations(), pg_newlocale_from_collation(), PgArchiverMain(), pgstat_attach_shmem(), pgstat_init_snapshot_fixed(), pgstat_prep_pending_entry(), pgstat_prep_snapshot(), pgstat_register_kind(), pgstat_setup_backend_status_context(), pgstat_setup_memcxt(), plperl_spi_prepare(), plpython3_inline_handler(), plsample_func_handler(), pltcl_SPI_prepare(), PLy_cursor_plan(), PLy_cursor_query(), PLy_procedure_create(), PLy_spi_execute_fetch_result(), PLy_spi_prepare(), populate_typ_list(), PostgresMain(), postmaster_child_launch(), PostmasterMain(), pq_init(), PreCommit_Notify(), PrepareClientEncoding(), ProcessLogMemoryContextInterrupt(), ProcessParallelApplyMessages(), ProcessParallelMessages(), ProcessStartupPacket(), px_find_cipher(), px_find_digest(), RE_compile_and_cache(), recomputeNamespacePath(), register_label_provider(), RegisterExtensionExplainOption(), RegisterResourceReleaseCallback(), RegisterSubXactCallback(), RegisterXactCallback(), RelationCreateStorage(), RelationDropStorage(), RequestNamedLWLockTranche(), ResourceOwnerCreate(), ResourceOwnerEnlarge(), RestoreClientConnectionInfo(), RestoreReindexState(), ri_HashCompareOp(), roles_is_member_of(), secure_open_gssapi(), sepgsql_avc_init(), sepgsql_xact_callback(), set_authn_id(), SetDatabasePath(), SharedRecordTypmodRegistryAttach(), SharedRecordTypmodRegistryInit(), SlabContextCreate(), spcache_init(), SPI_connect_ext(), test_create(), WalSummarizerMain(), WalWriterMain(), and XLOGShmemInit().

◆ TopTransactionContext