PostgreSQL Source Code  git master
mcxt.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * mcxt.c
4  * POSTGRES memory context management code.
5  *
6  * This module handles context management operations that are independent
7  * of the particular kind of context being operated on. It calls
8  * context-type-specific operations via the function pointers in a
9  * context's MemoryContextMethods struct.
10  *
11  *
12  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  * src/backend/utils/mmgr/mcxt.c
18  *
19  *-------------------------------------------------------------------------
20  */
21 
22 #include "postgres.h"
23 
24 #include "mb/pg_wchar.h"
25 #include "miscadmin.h"
26 #include "utils/memdebug.h"
27 #include "utils/memutils.h"
30 
31 
32 static void BogusFree(void *pointer);
33 static void *BogusRealloc(void *pointer, Size size, int flags);
34 static MemoryContext BogusGetChunkContext(void *pointer);
35 static Size BogusGetChunkSpace(void *pointer);
36 
37 /*****************************************************************************
38  * GLOBAL MEMORY *
39  *****************************************************************************/
40 
42  /* aset.c */
44  [MCTX_ASET_ID].free_p = AllocSetFree,
45  [MCTX_ASET_ID].realloc = AllocSetRealloc,
46  [MCTX_ASET_ID].reset = AllocSetReset,
47  [MCTX_ASET_ID].delete_context = AllocSetDelete,
48  [MCTX_ASET_ID].get_chunk_context = AllocSetGetChunkContext,
49  [MCTX_ASET_ID].get_chunk_space = AllocSetGetChunkSpace,
50  [MCTX_ASET_ID].is_empty = AllocSetIsEmpty,
51  [MCTX_ASET_ID].stats = AllocSetStats,
52 #ifdef MEMORY_CONTEXT_CHECKING
53  [MCTX_ASET_ID].check = AllocSetCheck,
54 #endif
55 
56  /* generation.c */
61  [MCTX_GENERATION_ID].delete_context = GenerationDelete,
62  [MCTX_GENERATION_ID].get_chunk_context = GenerationGetChunkContext,
63  [MCTX_GENERATION_ID].get_chunk_space = GenerationGetChunkSpace,
66 #ifdef MEMORY_CONTEXT_CHECKING
67  [MCTX_GENERATION_ID].check = GenerationCheck,
68 #endif
69 
70  /* slab.c */
71  [MCTX_SLAB_ID].alloc = SlabAlloc,
72  [MCTX_SLAB_ID].free_p = SlabFree,
73  [MCTX_SLAB_ID].realloc = SlabRealloc,
74  [MCTX_SLAB_ID].reset = SlabReset,
75  [MCTX_SLAB_ID].delete_context = SlabDelete,
76  [MCTX_SLAB_ID].get_chunk_context = SlabGetChunkContext,
77  [MCTX_SLAB_ID].get_chunk_space = SlabGetChunkSpace,
78  [MCTX_SLAB_ID].is_empty = SlabIsEmpty,
79  [MCTX_SLAB_ID].stats = SlabStats,
80 #ifdef MEMORY_CONTEXT_CHECKING
81  [MCTX_SLAB_ID].check = SlabCheck,
82 #endif
83 
84  /* alignedalloc.c */
85  [MCTX_ALIGNED_REDIRECT_ID].alloc = NULL, /* not required */
88  [MCTX_ALIGNED_REDIRECT_ID].reset = NULL, /* not required */
89  [MCTX_ALIGNED_REDIRECT_ID].delete_context = NULL, /* not required */
92  [MCTX_ALIGNED_REDIRECT_ID].is_empty = NULL, /* not required */
93  [MCTX_ALIGNED_REDIRECT_ID].stats = NULL, /* not required */
94 #ifdef MEMORY_CONTEXT_CHECKING
95  [MCTX_ALIGNED_REDIRECT_ID].check = NULL, /* not required */
96 #endif
97 
98 
99  /*
100  * Unused (as yet) IDs should have dummy entries here. This allows us to
101  * fail cleanly if a bogus pointer is passed to pfree or the like. It
102  * seems sufficient to provide routines for the methods that might get
103  * invoked from inspection of a chunk (see MCXT_METHOD calls below).
104  */
105 
106  [MCTX_UNUSED1_ID].free_p = BogusFree,
107  [MCTX_UNUSED1_ID].realloc = BogusRealloc,
108  [MCTX_UNUSED1_ID].get_chunk_context = BogusGetChunkContext,
109  [MCTX_UNUSED1_ID].get_chunk_space = BogusGetChunkSpace,
110 
111  [MCTX_UNUSED2_ID].free_p = BogusFree,
112  [MCTX_UNUSED2_ID].realloc = BogusRealloc,
113  [MCTX_UNUSED2_ID].get_chunk_context = BogusGetChunkContext,
114  [MCTX_UNUSED2_ID].get_chunk_space = BogusGetChunkSpace,
115 
116  [MCTX_UNUSED3_ID].free_p = BogusFree,
117  [MCTX_UNUSED3_ID].realloc = BogusRealloc,
118  [MCTX_UNUSED3_ID].get_chunk_context = BogusGetChunkContext,
119  [MCTX_UNUSED3_ID].get_chunk_space = BogusGetChunkSpace,
120 
121  [MCTX_UNUSED4_ID].free_p = BogusFree,
122  [MCTX_UNUSED4_ID].realloc = BogusRealloc,
123  [MCTX_UNUSED4_ID].get_chunk_context = BogusGetChunkContext,
124  [MCTX_UNUSED4_ID].get_chunk_space = BogusGetChunkSpace,
125 };
126 
127 /*
128  * CurrentMemoryContext
129  * Default memory context for allocations.
130  */
132 
133 /*
134  * Standard top-level contexts. For a description of the purpose of each
135  * of these contexts, refer to src/backend/utils/mmgr/README
136  */
144 
145 /* This is a transient link to the active portal's memory context: */
147 
148 static void MemoryContextDeleteOnly(MemoryContext context);
150 static void MemoryContextStatsInternal(MemoryContext context, int level,
151  int max_level, int max_children,
152  MemoryContextCounters *totals,
153  bool print_to_stderr);
154 static void MemoryContextStatsPrint(MemoryContext context, void *passthru,
155  const char *stats_string,
156  bool print_to_stderr);
157 
158 /*
159  * You should not do memory allocations within a critical section, because
160  * an out-of-memory error will be escalated to a PANIC. To enforce that
161  * rule, the allocation functions Assert that.
162  */
163 #define AssertNotInCriticalSection(context) \
164  Assert(CritSectionCount == 0 || (context)->allowInCritSection)
165 
166 /*
167  * Call the given function in the MemoryContextMethods for the memory context
168  * type that 'pointer' belongs to.
169  */
170 #define MCXT_METHOD(pointer, method) \
171  mcxt_methods[GetMemoryChunkMethodID(pointer)].method
172 
173 /*
174  * GetMemoryChunkMethodID
175  * Return the MemoryContextMethodID from the uint64 chunk header which
176  * directly precedes 'pointer'.
177  */
178 static inline MemoryContextMethodID
179 GetMemoryChunkMethodID(const void *pointer)
180 {
181  uint64 header;
182 
183  /*
184  * Try to detect bogus pointers handed to us, poorly though we can.
185  * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
186  * allocated chunk.
187  */
188  Assert(pointer == (const void *) MAXALIGN(pointer));
189 
190  /* Allow access to the uint64 header */
191  VALGRIND_MAKE_MEM_DEFINED((char *) pointer - sizeof(uint64), sizeof(uint64));
192 
193  header = *((const uint64 *) ((const char *) pointer - sizeof(uint64)));
194 
195  /* Disallow access to the uint64 header */
196  VALGRIND_MAKE_MEM_NOACCESS((char *) pointer - sizeof(uint64), sizeof(uint64));
197 
199 }
200 
201 /*
202  * GetMemoryChunkHeader
203  * Return the uint64 chunk header which directly precedes 'pointer'.
204  *
205  * This is only used after GetMemoryChunkMethodID, so no need for error checks.
206  */
207 static inline uint64
208 GetMemoryChunkHeader(const void *pointer)
209 {
210  uint64 header;
211 
212  /* Allow access to the uint64 header */
213  VALGRIND_MAKE_MEM_DEFINED((char *) pointer - sizeof(uint64), sizeof(uint64));
214 
215  header = *((const uint64 *) ((const char *) pointer - sizeof(uint64)));
216 
217  /* Disallow access to the uint64 header */
218  VALGRIND_MAKE_MEM_NOACCESS((char *) pointer - sizeof(uint64), sizeof(uint64));
219 
220  return header;
221 }
222 
223 /*
224  * MemoryContextTraverseNext
225  * Helper function to traverse all descendants of a memory context
226  * without recursion.
227  *
228  * Recursion could lead to out-of-stack errors with deep context hierarchies,
229  * which would be unpleasant in error cleanup code paths.
230  *
231  * To process 'context' and all its descendants, use a loop like this:
232  *
233  * <process 'context'>
234  * for (MemoryContext curr = context->firstchild;
235  * curr != NULL;
236  * curr = MemoryContextTraverseNext(curr, context))
237  * {
238  * <process 'curr'>
239  * }
240  *
241  * This visits all the contexts in pre-order, that is a node is visited
242  * before its children.
243  */
244 static MemoryContext
246 {
247  /* After processing a node, traverse to its first child if any */
248  if (curr->firstchild != NULL)
249  return curr->firstchild;
250 
251  /*
252  * After processing a childless node, traverse to its next sibling if
253  * there is one. If there isn't, traverse back up to the parent (which
254  * has already been visited, and now so have all its descendants). We're
255  * done if that is "top", otherwise traverse to its next sibling if any,
256  * otherwise repeat moving up.
257  */
258  while (curr->nextchild == NULL)
259  {
260  curr = curr->parent;
261  if (curr == top)
262  return NULL;
263  }
264  return curr->nextchild;
265 }
266 
267 /*
268  * Support routines to trap use of invalid memory context method IDs
269  * (from calling pfree or the like on a bogus pointer). As a possible
270  * aid in debugging, we report the header word along with the pointer
271  * address (if we got here, there must be an accessible header word).
272  */
273 static void
274 BogusFree(void *pointer)
275 {
276  elog(ERROR, "pfree called with invalid pointer %p (header 0x%016llx)",
277  pointer, (unsigned long long) GetMemoryChunkHeader(pointer));
278 }
279 
280 static void *
281 BogusRealloc(void *pointer, Size size, int flags)
282 {
283  elog(ERROR, "repalloc called with invalid pointer %p (header 0x%016llx)",
284  pointer, (unsigned long long) GetMemoryChunkHeader(pointer));
285  return NULL; /* keep compiler quiet */
286 }
287 
288 static MemoryContext
289 BogusGetChunkContext(void *pointer)
290 {
291  elog(ERROR, "GetMemoryChunkContext called with invalid pointer %p (header 0x%016llx)",
292  pointer, (unsigned long long) GetMemoryChunkHeader(pointer));
293  return NULL; /* keep compiler quiet */
294 }
295 
296 static Size
297 BogusGetChunkSpace(void *pointer)
298 {
299  elog(ERROR, "GetMemoryChunkSpace called with invalid pointer %p (header 0x%016llx)",
300  pointer, (unsigned long long) GetMemoryChunkHeader(pointer));
301  return 0; /* keep compiler quiet */
302 }
303 
304 
305 /*****************************************************************************
306  * EXPORTED ROUTINES *
307  *****************************************************************************/
308 
309 
310 /*
311  * MemoryContextInit
312  * Start up the memory-context subsystem.
313  *
314  * This must be called before creating contexts or allocating memory in
315  * contexts. TopMemoryContext and ErrorContext are initialized here;
316  * other contexts must be created afterwards.
317  *
318  * In normal multi-backend operation, this is called once during
319  * postmaster startup, and not at all by individual backend startup
320  * (since the backends inherit an already-initialized context subsystem
321  * by virtue of being forked off the postmaster). But in an EXEC_BACKEND
322  * build, each process must do this for itself.
323  *
324  * In a standalone backend this must be called during backend startup.
325  */
326 void
328 {
329  Assert(TopMemoryContext == NULL);
330 
331  /*
332  * First, initialize TopMemoryContext, which is the parent of all others.
333  */
335  "TopMemoryContext",
337 
338  /*
339  * Not having any other place to point CurrentMemoryContext, make it point
340  * to TopMemoryContext. Caller should change this soon!
341  */
343 
344  /*
345  * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
346  * we don't really expect much to be allocated in it. More to the point,
347  * require it to contain at least 8K at all times. This is the only case
348  * where retained memory in a context is *essential* --- we want to be
349  * sure ErrorContext still has some memory even if we've run out
350  * elsewhere! Also, allow allocations in ErrorContext within a critical
351  * section. Otherwise a PANIC will cause an assertion failure in the error
352  * reporting code, before printing out the real cause of the failure.
353  *
354  * This should be the last step in this function, as elog.c assumes memory
355  * management works once ErrorContext is non-null.
356  */
358  "ErrorContext",
359  8 * 1024,
360  8 * 1024,
361  8 * 1024);
363 }
364 
365 /*
366  * MemoryContextReset
367  * Release all space allocated within a context and delete all its
368  * descendant contexts (but not the named context itself).
369  */
370 void
372 {
373  Assert(MemoryContextIsValid(context));
374 
375  /* save a function call in common case where there are no children */
376  if (context->firstchild != NULL)
378 
379  /* save a function call if no pallocs since startup or last reset */
380  if (!context->isReset)
381  MemoryContextResetOnly(context);
382 }
383 
384 /*
385  * MemoryContextResetOnly
386  * Release all space allocated within a context.
387  * Nothing is done to the context's descendant contexts.
388  */
389 void
391 {
392  Assert(MemoryContextIsValid(context));
393 
394  /* Nothing to do if no pallocs since startup or last reset */
395  if (!context->isReset)
396  {
398 
399  /*
400  * If context->ident points into the context's memory, it will become
401  * a dangling pointer. We could prevent that by setting it to NULL
402  * here, but that would break valid coding patterns that keep the
403  * ident elsewhere, e.g. in a parent context. So for now we assume
404  * the programmer got it right.
405  */
406 
407  context->methods->reset(context);
408  context->isReset = true;
409  VALGRIND_DESTROY_MEMPOOL(context);
410  VALGRIND_CREATE_MEMPOOL(context, 0, false);
411  }
412 }
413 
414 /*
415  * MemoryContextResetChildren
416  * Release all space allocated within a context's descendants,
417  * but don't delete the contexts themselves. The named context
418  * itself is not touched.
419  */
420 void
422 {
423  Assert(MemoryContextIsValid(context));
424 
425  for (MemoryContext curr = context->firstchild;
426  curr != NULL;
427  curr = MemoryContextTraverseNext(curr, context))
428  {
430  }
431 }
432 
433 /*
434  * MemoryContextDelete
435  * Delete a context and its descendants, and release all space
436  * allocated therein.
437  *
438  * The type-specific delete routine removes all storage for the context,
439  * but we have to deal with descendant nodes here.
440  */
441 void
443 {
444  MemoryContext curr;
445 
446  Assert(MemoryContextIsValid(context));
447 
448  /*
449  * Delete subcontexts from the bottom up.
450  *
451  * Note: Do not use recursion here. A "stack depth limit exceeded" error
452  * would be unpleasant if we're already in the process of cleaning up from
453  * transaction abort. We also cannot use MemoryContextTraverseNext() here
454  * because we modify the tree as we go.
455  */
456  curr = context;
457  for (;;)
458  {
459  MemoryContext parent;
460 
461  /* Descend down until we find a leaf context with no children */
462  while (curr->firstchild != NULL)
463  curr = curr->firstchild;
464 
465  /*
466  * We're now at a leaf with no children. Free it and continue from the
467  * parent. Or if this was the original node, we're all done.
468  */
469  parent = curr->parent;
471 
472  if (curr == context)
473  break;
474  curr = parent;
475  }
476 }
477 
478 /*
479  * Subroutine of MemoryContextDelete,
480  * to delete a context that has no children.
481  * We must also delink the context from its parent, if it has one.
482  */
483 static void
485 {
486  Assert(MemoryContextIsValid(context));
487  /* We had better not be deleting TopMemoryContext ... */
488  Assert(context != TopMemoryContext);
489  /* And not CurrentMemoryContext, either */
490  Assert(context != CurrentMemoryContext);
491  /* All the children should've been deleted already */
492  Assert(context->firstchild == NULL);
493 
494  /*
495  * It's not entirely clear whether 'tis better to do this before or after
496  * delinking the context; but an error in a callback will likely result in
497  * leaking the whole context (if it's not a root context) if we do it
498  * after, so let's do it before.
499  */
501 
502  /*
503  * We delink the context from its parent before deleting it, so that if
504  * there's an error we won't have deleted/busted contexts still attached
505  * to the context tree. Better a leak than a crash.
506  */
507  MemoryContextSetParent(context, NULL);
508 
509  /*
510  * Also reset the context's ident pointer, in case it points into the
511  * context. This would only matter if someone tries to get stats on the
512  * (already unlinked) context, which is unlikely, but let's be safe.
513  */
514  context->ident = NULL;
515 
516  context->methods->delete_context(context);
517 
518  VALGRIND_DESTROY_MEMPOOL(context);
519 }
520 
521 /*
522  * MemoryContextDeleteChildren
523  * Delete all the descendants of the named context and release all
524  * space allocated therein. The named context itself is not touched.
525  */
526 void
528 {
529  Assert(MemoryContextIsValid(context));
530 
531  /*
532  * MemoryContextDelete will delink the child from me, so just iterate as
533  * long as there is a child.
534  */
535  while (context->firstchild != NULL)
537 }
538 
539 /*
540  * MemoryContextRegisterResetCallback
541  * Register a function to be called before next context reset/delete.
542  * Such callbacks will be called in reverse order of registration.
543  *
544  * The caller is responsible for allocating a MemoryContextCallback struct
545  * to hold the info about this callback request, and for filling in the
546  * "func" and "arg" fields in the struct to show what function to call with
547  * what argument. Typically the callback struct should be allocated within
548  * the specified context, since that means it will automatically be freed
549  * when no longer needed.
550  *
551  * There is no API for deregistering a callback once registered. If you
552  * want it to not do anything anymore, adjust the state pointed to by its
553  * "arg" to indicate that.
554  */
555 void
558 {
559  Assert(MemoryContextIsValid(context));
560 
561  /* Push onto head so this will be called before older registrants. */
562  cb->next = context->reset_cbs;
563  context->reset_cbs = cb;
564  /* Mark the context as non-reset (it probably is already). */
565  context->isReset = false;
566 }
567 
568 /*
569  * MemoryContextCallResetCallbacks
570  * Internal function to call all registered callbacks for context.
571  */
572 static void
574 {
576 
577  /*
578  * We pop each callback from the list before calling. That way, if an
579  * error occurs inside the callback, we won't try to call it a second time
580  * in the likely event that we reset or delete the context later.
581  */
582  while ((cb = context->reset_cbs) != NULL)
583  {
584  context->reset_cbs = cb->next;
585  cb->func(cb->arg);
586  }
587 }
588 
589 /*
590  * MemoryContextSetIdentifier
591  * Set the identifier string for a memory context.
592  *
593  * An identifier can be provided to help distinguish among different contexts
594  * of the same kind in memory context stats dumps. The identifier string
595  * must live at least as long as the context it is for; typically it is
596  * allocated inside that context, so that it automatically goes away on
597  * context deletion. Pass id = NULL to forget any old identifier.
598  */
599 void
601 {
602  Assert(MemoryContextIsValid(context));
603  context->ident = id;
604 }
605 
606 /*
607  * MemoryContextSetParent
608  * Change a context to belong to a new parent (or no parent).
609  *
610  * We provide this as an API function because it is sometimes useful to
611  * change a context's lifespan after creation. For example, a context
612  * might be created underneath a transient context, filled with data,
613  * and then reparented underneath CacheMemoryContext to make it long-lived.
614  * In this way no special effort is needed to get rid of the context in case
615  * a failure occurs before its contents are completely set up.
616  *
617  * Callers often assume that this function cannot fail, so don't put any
618  * elog(ERROR) calls in it.
619  *
620  * A possible caller error is to reparent a context under itself, creating
621  * a loop in the context graph. We assert here that context != new_parent,
622  * but checking for multi-level loops seems more trouble than it's worth.
623  */
624 void
626 {
627  Assert(MemoryContextIsValid(context));
628  Assert(context != new_parent);
629 
630  /* Fast path if it's got correct parent already */
631  if (new_parent == context->parent)
632  return;
633 
634  /* Delink from existing parent, if any */
635  if (context->parent)
636  {
637  MemoryContext parent = context->parent;
638 
639  if (context->prevchild != NULL)
640  context->prevchild->nextchild = context->nextchild;
641  else
642  {
643  Assert(parent->firstchild == context);
644  parent->firstchild = context->nextchild;
645  }
646 
647  if (context->nextchild != NULL)
648  context->nextchild->prevchild = context->prevchild;
649  }
650 
651  /* And relink */
652  if (new_parent)
653  {
654  Assert(MemoryContextIsValid(new_parent));
655  context->parent = new_parent;
656  context->prevchild = NULL;
657  context->nextchild = new_parent->firstchild;
658  if (new_parent->firstchild != NULL)
659  new_parent->firstchild->prevchild = context;
660  new_parent->firstchild = context;
661  }
662  else
663  {
664  context->parent = NULL;
665  context->prevchild = NULL;
666  context->nextchild = NULL;
667  }
668 }
669 
670 /*
671  * MemoryContextAllowInCriticalSection
672  * Allow/disallow allocations in this memory context within a critical
673  * section.
674  *
675  * Normally, memory allocations are not allowed within a critical section,
676  * because a failure would lead to PANIC. There are a few exceptions to
677  * that, like allocations related to debugging code that is not supposed to
678  * be enabled in production. This function can be used to exempt specific
679  * memory contexts from the assertion in palloc().
680  */
681 void
683 {
684  Assert(MemoryContextIsValid(context));
685 
686  context->allowInCritSection = allow;
687 }
688 
689 /*
690  * GetMemoryChunkContext
691  * Given a currently-allocated chunk, determine the MemoryContext that
692  * the chunk belongs to.
693  */
695 GetMemoryChunkContext(void *pointer)
696 {
697  return MCXT_METHOD(pointer, get_chunk_context) (pointer);
698 }
699 
700 /*
701  * GetMemoryChunkSpace
702  * Given a currently-allocated chunk, determine the total space
703  * it occupies (including all memory-allocation overhead).
704  *
705  * This is useful for measuring the total space occupied by a set of
706  * allocated chunks.
707  */
708 Size
709 GetMemoryChunkSpace(void *pointer)
710 {
711  return MCXT_METHOD(pointer, get_chunk_space) (pointer);
712 }
713 
714 /*
715  * MemoryContextGetParent
716  * Get the parent context (if any) of the specified context
717  */
720 {
721  Assert(MemoryContextIsValid(context));
722 
723  return context->parent;
724 }
725 
726 /*
727  * MemoryContextIsEmpty
728  * Is a memory context empty of any allocated space?
729  */
730 bool
732 {
733  Assert(MemoryContextIsValid(context));
734 
735  /*
736  * For now, we consider a memory context nonempty if it has any children;
737  * perhaps this should be changed later.
738  */
739  if (context->firstchild != NULL)
740  return false;
741  /* Otherwise use the type-specific inquiry */
742  return context->methods->is_empty(context);
743 }
744 
745 /*
746  * Find the memory allocated to blocks for this memory context. If recurse is
747  * true, also include children.
748  */
749 Size
751 {
752  Size total = context->mem_allocated;
753 
754  Assert(MemoryContextIsValid(context));
755 
756  if (recurse)
757  {
758  for (MemoryContext curr = context->firstchild;
759  curr != NULL;
760  curr = MemoryContextTraverseNext(curr, context))
761  {
762  total += curr->mem_allocated;
763  }
764  }
765 
766  return total;
767 }
768 
769 /*
770  * Return the memory consumption statistics about the given context and its
771  * children.
772  */
773 void
775  MemoryContextCounters *consumed)
776 {
777  Assert(MemoryContextIsValid(context));
778 
779  memset(consumed, 0, sizeof(*consumed));
780 
781  /* Examine the context itself */
782  context->methods->stats(context, NULL, NULL, consumed, false);
783 
784  /* Examine children, using iteration not recursion */
785  for (MemoryContext curr = context->firstchild;
786  curr != NULL;
787  curr = MemoryContextTraverseNext(curr, context))
788  {
789  curr->methods->stats(curr, NULL, NULL, consumed, false);
790  }
791 }
792 
793 /*
794  * MemoryContextStats
795  * Print statistics about the named context and all its descendants.
796  *
797  * This is just a debugging utility, so it's not very fancy. However, we do
798  * make some effort to summarize when the output would otherwise be very long.
799  * The statistics are sent to stderr.
800  */
801 void
803 {
804  /* Hard-wired limits are usually good enough */
805  MemoryContextStatsDetail(context, 100, 100, true);
806 }
807 
808 /*
809  * MemoryContextStatsDetail
810  *
811  * Entry point for use if you want to vary the number of child contexts shown.
812  *
813  * If print_to_stderr is true, print statistics about the memory contexts
814  * with fprintf(stderr), otherwise use ereport().
815  */
816 void
818  int max_level, int max_children,
819  bool print_to_stderr)
820 {
821  MemoryContextCounters grand_totals;
822 
823  memset(&grand_totals, 0, sizeof(grand_totals));
824 
825  MemoryContextStatsInternal(context, 0, max_level, max_children,
826  &grand_totals, print_to_stderr);
827 
828  if (print_to_stderr)
829  fprintf(stderr,
830  "Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used\n",
831  grand_totals.totalspace, grand_totals.nblocks,
832  grand_totals.freespace, grand_totals.freechunks,
833  grand_totals.totalspace - grand_totals.freespace);
834  else
835  {
836  /*
837  * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent
838  * to the connected client.
839  *
840  * We don't buffer the information about all memory contexts in a
841  * backend into StringInfo and log it as one message. That would
842  * require the buffer to be enlarged, risking an OOM as there could be
843  * a large number of memory contexts in a backend. Instead, we log
844  * one message per memory context.
845  */
847  (errhidestmt(true),
848  errhidecontext(true),
849  errmsg_internal("Grand total: %zu bytes in %zu blocks; %zu free (%zu chunks); %zu used",
850  grand_totals.totalspace, grand_totals.nblocks,
851  grand_totals.freespace, grand_totals.freechunks,
852  grand_totals.totalspace - grand_totals.freespace)));
853  }
854 }
855 
856 /*
857  * MemoryContextStatsInternal
858  * One recursion level for MemoryContextStats
859  *
860  * Print stats for this context if possible, but in any case accumulate counts
861  * into *totals (if not NULL).
862  */
863 static void
865  int max_level, int max_children,
866  MemoryContextCounters *totals,
867  bool print_to_stderr)
868 {
869  MemoryContext child;
870  int ichild;
871 
872  Assert(MemoryContextIsValid(context));
873 
874  /* Examine the context itself */
875  context->methods->stats(context,
877  (void *) &level,
878  totals, print_to_stderr);
879 
880  /*
881  * Examine children.
882  *
883  * If we are past the recursion depth limit or already running low on
884  * stack, do not print them explicitly but just summarize them. Similarly,
885  * if there are more than max_children of them, we do not print the rest
886  * explicitly, but just summarize them.
887  */
888  child = context->firstchild;
889  ichild = 0;
890  if (level < max_level && !stack_is_too_deep())
891  {
892  for (; child != NULL && ichild < max_children;
893  child = child->nextchild, ichild++)
894  {
895  MemoryContextStatsInternal(child, level + 1,
896  max_level, max_children,
897  totals,
898  print_to_stderr);
899  }
900  }
901 
902  if (child != NULL)
903  {
904  /* Summarize the rest of the children, avoiding recursion. */
905  MemoryContextCounters local_totals;
906 
907  memset(&local_totals, 0, sizeof(local_totals));
908 
909  ichild = 0;
910  while (child != NULL)
911  {
912  child->methods->stats(child, NULL, NULL, &local_totals, false);
913  ichild++;
914  child = MemoryContextTraverseNext(child, context);
915  }
916 
917  if (print_to_stderr)
918  {
919  for (int i = 0; i <= level; i++)
920  fprintf(stderr, " ");
921  fprintf(stderr,
922  "%d more child contexts containing %zu total in %zu blocks; %zu free (%zu chunks); %zu used\n",
923  ichild,
924  local_totals.totalspace,
925  local_totals.nblocks,
926  local_totals.freespace,
927  local_totals.freechunks,
928  local_totals.totalspace - local_totals.freespace);
929  }
930  else
932  (errhidestmt(true),
933  errhidecontext(true),
934  errmsg_internal("level: %d; %d more child contexts containing %zu total in %zu blocks; %zu free (%zu chunks); %zu used",
935  level,
936  ichild,
937  local_totals.totalspace,
938  local_totals.nblocks,
939  local_totals.freespace,
940  local_totals.freechunks,
941  local_totals.totalspace - local_totals.freespace)));
942 
943  if (totals)
944  {
945  totals->nblocks += local_totals.nblocks;
946  totals->freechunks += local_totals.freechunks;
947  totals->totalspace += local_totals.totalspace;
948  totals->freespace += local_totals.freespace;
949  }
950  }
951 }
952 
953 /*
954  * MemoryContextStatsPrint
955  * Print callback used by MemoryContextStatsInternal
956  *
957  * For now, the passthru pointer just points to "int level"; later we might
958  * make that more complicated.
959  */
960 static void
961 MemoryContextStatsPrint(MemoryContext context, void *passthru,
962  const char *stats_string,
963  bool print_to_stderr)
964 {
965  int level = *(int *) passthru;
966  const char *name = context->name;
967  const char *ident = context->ident;
968  char truncated_ident[110];
969  int i;
970 
971  /*
972  * It seems preferable to label dynahash contexts with just the hash table
973  * name. Those are already unique enough, so the "dynahash" part isn't
974  * very helpful, and this way is more consistent with pre-v11 practice.
975  */
976  if (ident && strcmp(name, "dynahash") == 0)
977  {
978  name = ident;
979  ident = NULL;
980  }
981 
982  truncated_ident[0] = '\0';
983 
984  if (ident)
985  {
986  /*
987  * Some contexts may have very long identifiers (e.g., SQL queries).
988  * Arbitrarily truncate at 100 bytes, but be careful not to break
989  * multibyte characters. Also, replace ASCII control characters, such
990  * as newlines, with spaces.
991  */
992  int idlen = strlen(ident);
993  bool truncated = false;
994 
995  strcpy(truncated_ident, ": ");
996  i = strlen(truncated_ident);
997 
998  if (idlen > 100)
999  {
1000  idlen = pg_mbcliplen(ident, idlen, 100);
1001  truncated = true;
1002  }
1003 
1004  while (idlen-- > 0)
1005  {
1006  unsigned char c = *ident++;
1007 
1008  if (c < ' ')
1009  c = ' ';
1010  truncated_ident[i++] = c;
1011  }
1012  truncated_ident[i] = '\0';
1013 
1014  if (truncated)
1015  strcat(truncated_ident, "...");
1016  }
1017 
1018  if (print_to_stderr)
1019  {
1020  for (i = 0; i < level; i++)
1021  fprintf(stderr, " ");
1022  fprintf(stderr, "%s: %s%s\n", name, stats_string, truncated_ident);
1023  }
1024  else
1026  (errhidestmt(true),
1027  errhidecontext(true),
1028  errmsg_internal("level: %d; %s: %s%s",
1029  level, name, stats_string, truncated_ident)));
1030 }
1031 
1032 /*
1033  * MemoryContextCheck
1034  * Check all chunks in the named context and its children.
1035  *
1036  * This is just a debugging utility, so it's not fancy.
1037  */
1038 #ifdef MEMORY_CONTEXT_CHECKING
1039 void
1040 MemoryContextCheck(MemoryContext context)
1041 {
1042  Assert(MemoryContextIsValid(context));
1043  context->methods->check(context);
1044 
1045  for (MemoryContext curr = context->firstchild;
1046  curr != NULL;
1047  curr = MemoryContextTraverseNext(curr, context))
1048  {
1050  curr->methods->check(curr);
1051  }
1052 }
1053 #endif
1054 
1055 /*
1056  * MemoryContextCreate
1057  * Context-type-independent part of context creation.
1058  *
1059  * This is only intended to be called by context-type-specific
1060  * context creation routines, not by the unwashed masses.
1061  *
1062  * The memory context creation procedure goes like this:
1063  * 1. Context-type-specific routine makes some initial space allocation,
1064  * including enough space for the context header. If it fails,
1065  * it can ereport() with no damage done.
1066  * 2. Context-type-specific routine sets up all type-specific fields of
1067  * the header (those beyond MemoryContextData proper), as well as any
1068  * other management fields it needs to have a fully valid context.
1069  * Usually, failure in this step is impossible, but if it's possible
1070  * the initial space allocation should be freed before ereport'ing.
1071  * 3. Context-type-specific routine calls MemoryContextCreate() to fill in
1072  * the generic header fields and link the context into the context tree.
1073  * 4. We return to the context-type-specific routine, which finishes
1074  * up type-specific initialization. This routine can now do things
1075  * that might fail (like allocate more memory), so long as it's
1076  * sure the node is left in a state that delete will handle.
1077  *
1078  * node: the as-yet-uninitialized common part of the context header node.
1079  * tag: NodeTag code identifying the memory context type.
1080  * method_id: MemoryContextMethodID of the context-type being created.
1081  * parent: parent context, or NULL if this will be a top-level context.
1082  * name: name of context (must be statically allocated).
1083  *
1084  * Context routines generally assume that MemoryContextCreate can't fail,
1085  * so this can contain Assert but not elog/ereport.
1086  */
1087 void
1089  NodeTag tag,
1090  MemoryContextMethodID method_id,
1091  MemoryContext parent,
1092  const char *name)
1093 {
1094  /* Creating new memory contexts is not allowed in a critical section */
1095  Assert(CritSectionCount == 0);
1096 
1097  /* Initialize all standard fields of memory context header */
1098  node->type = tag;
1099  node->isReset = true;
1100  node->methods = &mcxt_methods[method_id];
1101  node->parent = parent;
1102  node->firstchild = NULL;
1103  node->mem_allocated = 0;
1104  node->prevchild = NULL;
1105  node->name = name;
1106  node->ident = NULL;
1107  node->reset_cbs = NULL;
1108 
1109  /* OK to link node into context tree */
1110  if (parent)
1111  {
1112  node->nextchild = parent->firstchild;
1113  if (parent->firstchild != NULL)
1114  parent->firstchild->prevchild = node;
1115  parent->firstchild = node;
1116  /* inherit allowInCritSection flag from parent */
1117  node->allowInCritSection = parent->allowInCritSection;
1118  }
1119  else
1120  {
1121  node->nextchild = NULL;
1122  node->allowInCritSection = false;
1123  }
1124 
1125  VALGRIND_CREATE_MEMPOOL(node, 0, false);
1126 }
1127 
1128 /*
1129  * MemoryContextAllocationFailure
1130  * For use by MemoryContextMethods implementations to handle when malloc
1131  * returns NULL. The behavior is specific to whether MCXT_ALLOC_NO_OOM
1132  * is in 'flags'.
1133  */
1134 void *
1136 {
1137  if ((flags & MCXT_ALLOC_NO_OOM) == 0)
1138  {
1140  ereport(ERROR,
1141  (errcode(ERRCODE_OUT_OF_MEMORY),
1142  errmsg("out of memory"),
1143  errdetail("Failed on request of size %zu in memory context \"%s\".",
1144  size, context->name)));
1145  }
1146  return NULL;
1147 }
1148 
1149 /*
1150  * MemoryContextSizeFailure
1151  * For use by MemoryContextMethods implementations to handle invalid
1152  * memory allocation request sizes.
1153  */
1154 void
1156 {
1157  elog(ERROR, "invalid memory alloc request size %zu", size);
1158 }
1159 
1160 /*
1161  * MemoryContextAlloc
1162  * Allocate space within the specified context.
1163  *
1164  * This could be turned into a macro, but we'd have to import
1165  * nodes/memnodes.h into postgres.h which seems a bad idea.
1166  */
1167 void *
1169 {
1170  void *ret;
1171 
1172  Assert(MemoryContextIsValid(context));
1173  AssertNotInCriticalSection(context);
1174 
1175  context->isReset = false;
1176 
1177  /*
1178  * For efficiency reasons, we purposefully offload the handling of
1179  * allocation failures to the MemoryContextMethods implementation as this
1180  * allows these checks to be performed only when an actual malloc needs to
1181  * be done to request more memory from the OS. Additionally, not having
1182  * to execute any instructions after this call allows the compiler to use
1183  * the sibling call optimization. If you're considering adding code after
1184  * this call, consider making it the responsibility of the 'alloc'
1185  * function instead.
1186  */
1187  ret = context->methods->alloc(context, size, 0);
1188 
1189  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1190 
1191  return ret;
1192 }
1193 
1194 /*
1195  * MemoryContextAllocZero
1196  * Like MemoryContextAlloc, but clears allocated memory
1197  *
1198  * We could just call MemoryContextAlloc then clear the memory, but this
1199  * is a very common combination, so we provide the combined operation.
1200  */
1201 void *
1203 {
1204  void *ret;
1205 
1206  Assert(MemoryContextIsValid(context));
1207  AssertNotInCriticalSection(context);
1208 
1209  context->isReset = false;
1210 
1211  ret = context->methods->alloc(context, size, 0);
1212 
1213  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1214 
1215  MemSetAligned(ret, 0, size);
1216 
1217  return ret;
1218 }
1219 
1220 /*
1221  * MemoryContextAllocExtended
1222  * Allocate space within the specified context using the given flags.
1223  */
1224 void *
1226 {
1227  void *ret;
1228 
1229  Assert(MemoryContextIsValid(context));
1230  AssertNotInCriticalSection(context);
1231 
1232  if (!((flags & MCXT_ALLOC_HUGE) != 0 ? AllocHugeSizeIsValid(size) :
1234  elog(ERROR, "invalid memory alloc request size %zu", size);
1235 
1236  context->isReset = false;
1237 
1238  ret = context->methods->alloc(context, size, flags);
1239  if (unlikely(ret == NULL))
1240  return NULL;
1241 
1242  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1243 
1244  if ((flags & MCXT_ALLOC_ZERO) != 0)
1245  MemSetAligned(ret, 0, size);
1246 
1247  return ret;
1248 }
1249 
1250 /*
1251  * HandleLogMemoryContextInterrupt
1252  * Handle receipt of an interrupt indicating logging of memory
1253  * contexts.
1254  *
1255  * All the actual work is deferred to ProcessLogMemoryContextInterrupt(),
1256  * because we cannot safely emit a log message inside the signal handler.
1257  */
1258 void
1260 {
1261  InterruptPending = true;
1262  LogMemoryContextPending = true;
1263  /* latch will be set by procsignal_sigusr1_handler */
1264 }
1265 
1266 /*
1267  * ProcessLogMemoryContextInterrupt
1268  * Perform logging of memory contexts of this backend process.
1269  *
1270  * Any backend that participates in ProcSignal signaling must arrange
1271  * to call this function if we see LogMemoryContextPending set.
1272  * It is called from CHECK_FOR_INTERRUPTS(), which is enough because
1273  * the target process for logging of memory contexts is a backend.
1274  */
1275 void
1277 {
1278  LogMemoryContextPending = false;
1279 
1280  /*
1281  * Use LOG_SERVER_ONLY to prevent this message from being sent to the
1282  * connected client.
1283  */
1285  (errhidestmt(true),
1286  errhidecontext(true),
1287  errmsg("logging memory contexts of PID %d", MyProcPid)));
1288 
1289  /*
1290  * When a backend process is consuming huge memory, logging all its memory
1291  * contexts might overrun available disk space. To prevent this, we limit
1292  * the depth of the hierarchy, as well as the number of child contexts to
1293  * log per parent to 100.
1294  *
1295  * As with MemoryContextStats(), we suppose that practical cases where the
1296  * dump gets long will typically be huge numbers of siblings under the
1297  * same parent context; while the additional debugging value from seeing
1298  * details about individual siblings beyond 100 will not be large.
1299  */
1300  MemoryContextStatsDetail(TopMemoryContext, 100, 100, false);
1301 }
1302 
1303 void *
1305 {
1306  /* duplicates MemoryContextAlloc to avoid increased overhead */
1307  void *ret;
1309 
1310  Assert(MemoryContextIsValid(context));
1311  AssertNotInCriticalSection(context);
1312 
1313  context->isReset = false;
1314 
1315  /*
1316  * For efficiency reasons, we purposefully offload the handling of
1317  * allocation failures to the MemoryContextMethods implementation as this
1318  * allows these checks to be performed only when an actual malloc needs to
1319  * be done to request more memory from the OS. Additionally, not having
1320  * to execute any instructions after this call allows the compiler to use
1321  * the sibling call optimization. If you're considering adding code after
1322  * this call, consider making it the responsibility of the 'alloc'
1323  * function instead.
1324  */
1325  ret = context->methods->alloc(context, size, 0);
1326  /* We expect OOM to be handled by the alloc function */
1327  Assert(ret != NULL);
1328  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1329 
1330  return ret;
1331 }
1332 
1333 void *
1335 {
1336  /* duplicates MemoryContextAllocZero to avoid increased overhead */
1337  void *ret;
1339 
1340  Assert(MemoryContextIsValid(context));
1341  AssertNotInCriticalSection(context);
1342 
1343  context->isReset = false;
1344 
1345  ret = context->methods->alloc(context, size, 0);
1346 
1347  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1348 
1349  MemSetAligned(ret, 0, size);
1350 
1351  return ret;
1352 }
1353 
1354 void *
1356 {
1357  /* duplicates MemoryContextAllocExtended to avoid increased overhead */
1358  void *ret;
1360 
1361  Assert(MemoryContextIsValid(context));
1362  AssertNotInCriticalSection(context);
1363 
1364  context->isReset = false;
1365 
1366  ret = context->methods->alloc(context, size, flags);
1367  if (unlikely(ret == NULL))
1368  {
1369  return NULL;
1370  }
1371 
1372  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1373 
1374  if ((flags & MCXT_ALLOC_ZERO) != 0)
1375  MemSetAligned(ret, 0, size);
1376 
1377  return ret;
1378 }
1379 
1380 /*
1381  * MemoryContextAllocAligned
1382  * Allocate 'size' bytes of memory in 'context' aligned to 'alignto'
1383  * bytes.
1384  *
1385  * Currently, we align addresses by requesting additional bytes from the
1386  * MemoryContext's standard allocator function and then aligning the returned
1387  * address by the required alignment. This means that the given MemoryContext
1388  * must support providing us with a chunk of memory that's larger than 'size'.
1389  * For allocators such as Slab, that's not going to work, as slab only allows
1390  * chunks of the size that's specified when the context is created.
1391  *
1392  * 'alignto' must be a power of 2.
1393  * 'flags' may be 0 or set the same as MemoryContextAllocExtended().
1394  */
1395 void *
1397  Size size, Size alignto, int flags)
1398 {
1399  MemoryChunk *alignedchunk;
1400  Size alloc_size;
1401  void *unaligned;
1402  void *aligned;
1403 
1404  /* wouldn't make much sense to waste that much space */
1405  Assert(alignto < (128 * 1024 * 1024));
1406 
1407  /* ensure alignto is a power of 2 */
1408  Assert((alignto & (alignto - 1)) == 0);
1409 
1410  /*
1411  * If the alignment requirements are less than what we already guarantee
1412  * then just use the standard allocation function.
1413  */
1414  if (unlikely(alignto <= MAXIMUM_ALIGNOF))
1415  return MemoryContextAllocExtended(context, size, flags);
1416 
1417  /*
1418  * We implement aligned pointers by simply allocating enough memory for
1419  * the requested size plus the alignment and an additional "redirection"
1420  * MemoryChunk. This additional MemoryChunk is required for operations
1421  * such as pfree when used on the pointer returned by this function. We
1422  * use this redirection MemoryChunk in order to find the pointer to the
1423  * memory that was returned by the MemoryContextAllocExtended call below.
1424  * We do that by "borrowing" the block offset field and instead of using
1425  * that to find the offset into the owning block, we use it to find the
1426  * original allocated address.
1427  *
1428  * Here we must allocate enough extra memory so that we can still align
1429  * the pointer returned by MemoryContextAllocExtended and also have enough
1430  * space for the redirection MemoryChunk. Since allocations will already
1431  * be at least aligned by MAXIMUM_ALIGNOF, we can subtract that amount
1432  * from the allocation size to save a little memory.
1433  */
1434  alloc_size = size + PallocAlignedExtraBytes(alignto);
1435 
1436 #ifdef MEMORY_CONTEXT_CHECKING
1437  /* ensure there's space for a sentinel byte */
1438  alloc_size += 1;
1439 #endif
1440 
1441  /* perform the actual allocation */
1442  unaligned = MemoryContextAllocExtended(context, alloc_size, flags);
1443 
1444  /* set the aligned pointer */
1445  aligned = (void *) TYPEALIGN(alignto, (char *) unaligned +
1446  sizeof(MemoryChunk));
1447 
1448  alignedchunk = PointerGetMemoryChunk(aligned);
1449 
1450  /*
1451  * We set the redirect MemoryChunk so that the block offset calculation is
1452  * used to point back to the 'unaligned' allocated chunk. This allows us
1453  * to use MemoryChunkGetBlock() to find the unaligned chunk when we need
1454  * to perform operations such as pfree() and repalloc().
1455  *
1456  * We store 'alignto' in the MemoryChunk's 'value' so that we know what
1457  * the alignment was set to should we ever be asked to realloc this
1458  * pointer.
1459  */
1460  MemoryChunkSetHdrMask(alignedchunk, unaligned, alignto,
1462 
1463  /* double check we produced a correctly aligned pointer */
1464  Assert((void *) TYPEALIGN(alignto, aligned) == aligned);
1465 
1466 #ifdef MEMORY_CONTEXT_CHECKING
1467  alignedchunk->requested_size = size;
1468  /* set mark to catch clobber of "unused" space */
1469  set_sentinel(aligned, size);
1470 #endif
1471 
1472  /* Mark the bytes before the redirection header as noaccess */
1473  VALGRIND_MAKE_MEM_NOACCESS(unaligned,
1474  (char *) alignedchunk - (char *) unaligned);
1475 
1476  /* Disallow access to the redirection chunk header. */
1477  VALGRIND_MAKE_MEM_NOACCESS(alignedchunk, sizeof(MemoryChunk));
1478 
1479  return aligned;
1480 }
1481 
1482 /*
1483  * palloc_aligned
1484  * Allocate 'size' bytes returning a pointer that's aligned to the
1485  * 'alignto' boundary.
1486  *
1487  * Currently, we align addresses by requesting additional bytes from the
1488  * MemoryContext's standard allocator function and then aligning the returned
1489  * address by the required alignment. This means that the given MemoryContext
1490  * must support providing us with a chunk of memory that's larger than 'size'.
1491  * For allocators such as Slab, that's not going to work, as slab only allows
1492  * chunks of the size that's specified when the context is created.
1493  *
1494  * 'alignto' must be a power of 2.
1495  * 'flags' may be 0 or set the same as MemoryContextAllocExtended().
1496  */
1497 void *
1498 palloc_aligned(Size size, Size alignto, int flags)
1499 {
1500  return MemoryContextAllocAligned(CurrentMemoryContext, size, alignto, flags);
1501 }
1502 
1503 /*
1504  * pfree
1505  * Release an allocated chunk.
1506  */
1507 void
1508 pfree(void *pointer)
1509 {
1510 #ifdef USE_VALGRIND
1512  MemoryContext context = GetMemoryChunkContext(pointer);
1513 #endif
1514 
1515  MCXT_METHOD(pointer, free_p) (pointer);
1516 
1517 #ifdef USE_VALGRIND
1518  if (method != MCTX_ALIGNED_REDIRECT_ID)
1519  VALGRIND_MEMPOOL_FREE(context, pointer);
1520 #endif
1521 }
1522 
1523 /*
1524  * repalloc
1525  * Adjust the size of a previously allocated chunk.
1526  */
1527 void *
1528 repalloc(void *pointer, Size size)
1529 {
1530 #ifdef USE_VALGRIND
1532 #endif
1533 #if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1534  MemoryContext context = GetMemoryChunkContext(pointer);
1535 #endif
1536  void *ret;
1537 
1538  AssertNotInCriticalSection(context);
1539 
1540  /* isReset must be false already */
1541  Assert(!context->isReset);
1542 
1543  /*
1544  * For efficiency reasons, we purposefully offload the handling of
1545  * allocation failures to the MemoryContextMethods implementation as this
1546  * allows these checks to be performed only when an actual malloc needs to
1547  * be done to request more memory from the OS. Additionally, not having
1548  * to execute any instructions after this call allows the compiler to use
1549  * the sibling call optimization. If you're considering adding code after
1550  * this call, consider making it the responsibility of the 'realloc'
1551  * function instead.
1552  */
1553  ret = MCXT_METHOD(pointer, realloc) (pointer, size, 0);
1554 
1555 #ifdef USE_VALGRIND
1556  if (method != MCTX_ALIGNED_REDIRECT_ID)
1557  VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
1558 #endif
1559 
1560  return ret;
1561 }
1562 
1563 /*
1564  * repalloc_extended
1565  * Adjust the size of a previously allocated chunk,
1566  * with HUGE and NO_OOM options.
1567  */
1568 void *
1569 repalloc_extended(void *pointer, Size size, int flags)
1570 {
1571 #if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND)
1572  MemoryContext context = GetMemoryChunkContext(pointer);
1573 #endif
1574  void *ret;
1575 
1576  AssertNotInCriticalSection(context);
1577 
1578  /* isReset must be false already */
1579  Assert(!context->isReset);
1580 
1581  /*
1582  * For efficiency reasons, we purposefully offload the handling of
1583  * allocation failures to the MemoryContextMethods implementation as this
1584  * allows these checks to be performed only when an actual malloc needs to
1585  * be done to request more memory from the OS. Additionally, not having
1586  * to execute any instructions after this call allows the compiler to use
1587  * the sibling call optimization. If you're considering adding code after
1588  * this call, consider making it the responsibility of the 'realloc'
1589  * function instead.
1590  */
1591  ret = MCXT_METHOD(pointer, realloc) (pointer, size, flags);
1592  if (unlikely(ret == NULL))
1593  return NULL;
1594 
1595  VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
1596 
1597  return ret;
1598 }
1599 
1600 /*
1601  * repalloc0
1602  * Adjust the size of a previously allocated chunk and zero out the added
1603  * space.
1604  */
1605 void *
1606 repalloc0(void *pointer, Size oldsize, Size size)
1607 {
1608  void *ret;
1609 
1610  /* catch wrong argument order */
1611  if (unlikely(oldsize > size))
1612  elog(ERROR, "invalid repalloc0 call: oldsize %zu, new size %zu",
1613  oldsize, size);
1614 
1615  ret = repalloc(pointer, size);
1616  memset((char *) ret + oldsize, 0, (size - oldsize));
1617  return ret;
1618 }
1619 
1620 /*
1621  * MemoryContextAllocHuge
1622  * Allocate (possibly-expansive) space within the specified context.
1623  *
1624  * See considerations in comment at MaxAllocHugeSize.
1625  */
1626 void *
1628 {
1629  void *ret;
1630 
1631  Assert(MemoryContextIsValid(context));
1632  AssertNotInCriticalSection(context);
1633 
1634  context->isReset = false;
1635 
1636  /*
1637  * For efficiency reasons, we purposefully offload the handling of
1638  * allocation failures to the MemoryContextMethods implementation as this
1639  * allows these checks to be performed only when an actual malloc needs to
1640  * be done to request more memory from the OS. Additionally, not having
1641  * to execute any instructions after this call allows the compiler to use
1642  * the sibling call optimization. If you're considering adding code after
1643  * this call, consider making it the responsibility of the 'alloc'
1644  * function instead.
1645  */
1646  ret = context->methods->alloc(context, size, MCXT_ALLOC_HUGE);
1647 
1648  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1649 
1650  return ret;
1651 }
1652 
1653 /*
1654  * repalloc_huge
1655  * Adjust the size of a previously allocated chunk, permitting a large
1656  * value. The previous allocation need not have been "huge".
1657  */
1658 void *
1659 repalloc_huge(void *pointer, Size size)
1660 {
1661  /* this one seems not worth its own implementation */
1662  return repalloc_extended(pointer, size, MCXT_ALLOC_HUGE);
1663 }
1664 
1665 /*
1666  * MemoryContextStrdup
1667  * Like strdup(), but allocate from the specified context
1668  */
1669 char *
1670 MemoryContextStrdup(MemoryContext context, const char *string)
1671 {
1672  char *nstr;
1673  Size len = strlen(string) + 1;
1674 
1675  nstr = (char *) MemoryContextAlloc(context, len);
1676 
1677  memcpy(nstr, string, len);
1678 
1679  return nstr;
1680 }
1681 
1682 char *
1683 pstrdup(const char *in)
1684 {
1686 }
1687 
1688 /*
1689  * pnstrdup
1690  * Like pstrdup(), but append null byte to a
1691  * not-necessarily-null-terminated input string.
1692  */
1693 char *
1694 pnstrdup(const char *in, Size len)
1695 {
1696  char *out;
1697 
1698  len = strnlen(in, len);
1699 
1700  out = palloc(len + 1);
1701  memcpy(out, in, len);
1702  out[len] = '\0';
1703 
1704  return out;
1705 }
1706 
1707 /*
1708  * Make copy of string with all trailing newline characters removed.
1709  */
1710 char *
1711 pchomp(const char *in)
1712 {
1713  size_t n;
1714 
1715  n = strlen(in);
1716  while (n > 0 && in[n - 1] == '\n')
1717  n--;
1718  return pnstrdup(in, n);
1719 }
MemoryContext AlignedAllocGetChunkContext(void *pointer)
Definition: alignedalloc.c:121
void * AlignedAllocRealloc(void *pointer, Size size, int flags)
Definition: alignedalloc.c:60
Size AlignedAllocGetChunkSpace(void *pointer)
Definition: alignedalloc.c:143
void AlignedAllocFree(void *pointer)
Definition: alignedalloc.c:29
void AllocSetReset(MemoryContext context)
Definition: aset.c:537
void * AllocSetRealloc(void *pointer, Size size, int flags)
Definition: aset.c:1169
Size AllocSetGetChunkSpace(void *pointer)
Definition: aset.c:1462
MemoryContext AllocSetGetChunkContext(void *pointer)
Definition: aset.c:1433
void AllocSetStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
Definition: aset.c:1521
void * AllocSetAlloc(MemoryContext context, Size size, int flags)
Definition: aset.c:967
bool AllocSetIsEmpty(MemoryContext context)
Definition: aset.c:1496
void AllocSetFree(void *pointer)
Definition: aset.c:1062
void AllocSetDelete(MemoryContext context)
Definition: aset.c:607
#define MAXALIGN(LEN)
Definition: c.h:798
#define TYPEALIGN(ALIGNVAL, LEN)
Definition: c.h:791
#define MemSetAligned(start, val, len)
Definition: c.h:1037
#define unlikely(x)
Definition: c.h:298
size_t Size
Definition: c.h:592
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
int errhidestmt(bool hide_stmt)
Definition: elog.c:1413
int errdetail(const char *fmt,...)
Definition: elog.c:1205
int errhidecontext(bool hide_ctx)
Definition: elog.c:1432
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define LOG_SERVER_ONLY
Definition: elog.h:32
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
#define MCXT_ALLOC_ZERO
Definition: fe_memutils.h:18
#define MCXT_ALLOC_HUGE
Definition: fe_memutils.h:16
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:17
void GenerationReset(MemoryContext context)
Definition: generation.c:283
void * GenerationAlloc(MemoryContext context, Size size, int flags)
Definition: generation.c:527
void GenerationFree(void *pointer)
Definition: generation.c:689
MemoryContext GenerationGetChunkContext(void *pointer)
Definition: generation.c:942
Size GenerationGetChunkSpace(void *pointer)
Definition: generation.c:968
bool GenerationIsEmpty(MemoryContext context)
Definition: generation.c:997
void GenerationStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
Definition: generation.c:1028
void * GenerationRealloc(void *pointer, Size size, int flags)
Definition: generation.c:800
void GenerationDelete(MemoryContext context)
Definition: generation.c:328
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:39
volatile sig_atomic_t InterruptPending
Definition: globals.c:30
int MyProcPid
Definition: globals.c:45
volatile uint32 CritSectionCount
Definition: globals.c:43
#define realloc(a, b)
Definition: header.h:60
#define ident
Definition: indent_codes.h:47
int i
Definition: isn.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1083
static void MemoryContextStatsInternal(MemoryContext context, int level, int max_level, int max_children, MemoryContextCounters *totals, bool print_to_stderr)
Definition: mcxt.c:864
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1694
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:573
MemoryContext MessageContext
Definition: mcxt.c:141
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
Definition: mcxt.c:1396
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:731
void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed)
Definition: mcxt.c:774
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:371
void MemoryContextCreate(MemoryContext node, NodeTag tag, MemoryContextMethodID method_id, MemoryContext parent, const char *name)
Definition: mcxt.c:1088
MemoryContext TopTransactionContext
Definition: mcxt.c:142
char * pchomp(const char *in)
Definition: mcxt.c:1711
void HandleLogMemoryContextInterrupt(void)
Definition: mcxt.c:1259
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
Definition: mcxt.c:556
static MemoryContextMethodID GetMemoryChunkMethodID(const void *pointer)
Definition: mcxt.c:179
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:625
static void * BogusRealloc(void *pointer, Size size, int flags)
Definition: mcxt.c:281
char * pstrdup(const char *in)
Definition: mcxt.c:1683
void pfree(void *pointer)
Definition: mcxt.c:1508
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:709
void * repalloc0(void *pointer, Size oldsize, Size size)
Definition: mcxt.c:1606
static Size BogusGetChunkSpace(void *pointer)
Definition: mcxt.c:297
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:527
MemoryContext TopMemoryContext
Definition: mcxt.c:137
#define AssertNotInCriticalSection(context)
Definition: mcxt.c:163
void * palloc0(Size size)
Definition: mcxt.c:1334
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1202
MemoryContext CurTransactionContext
Definition: mcxt.c:143
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1225
MemoryContext CurrentMemoryContext
Definition: mcxt.c:131
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1528
static MemoryContext MemoryContextTraverseNext(MemoryContext curr, MemoryContext top)
Definition: mcxt.c:245
void * palloc_extended(Size size, int flags)
Definition: mcxt.c:1355
MemoryContext GetMemoryChunkContext(void *pointer)
Definition: mcxt.c:695
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1168
void MemoryContextStatsDetail(MemoryContext context, int max_level, int max_children, bool print_to_stderr)
Definition: mcxt.c:817
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
Definition: mcxt.c:750
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:802
void MemoryContextInit(void)
Definition: mcxt.c:327
static void BogusFree(void *pointer)
Definition: mcxt.c:274
MemoryContext PostmasterContext
Definition: mcxt.c:139
void * palloc_aligned(Size size, Size alignto, int flags)
Definition: mcxt.c:1498
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1670
static const MemoryContextMethods mcxt_methods[]
Definition: mcxt.c:41
void * MemoryContextAllocationFailure(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1135
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:719
void ProcessLogMemoryContextInterrupt(void)
Definition: mcxt.c:1276
MemoryContext ErrorContext
Definition: mcxt.c:138
static MemoryContext BogusGetChunkContext(void *pointer)
Definition: mcxt.c:289
MemoryContext CacheMemoryContext
Definition: mcxt.c:140
void MemoryContextSizeFailure(MemoryContext context, Size size, int flags)
Definition: mcxt.c:1155
void * MemoryContextAllocHuge(MemoryContext context, Size size)
Definition: mcxt.c:1627
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:442
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:682
static void MemoryContextDeleteOnly(MemoryContext context)
Definition: mcxt.c:484
void MemoryContextResetChildren(MemoryContext context)
Definition: mcxt.c:421
static void MemoryContextStatsPrint(MemoryContext context, void *passthru, const char *stats_string, bool print_to_stderr)
Definition: mcxt.c:961
void * palloc(Size size)
Definition: mcxt.c:1304
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:600
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:390
static uint64 GetMemoryChunkHeader(const void *pointer)
Definition: mcxt.c:208
MemoryContext PortalContext
Definition: mcxt.c:146
void * repalloc_huge(void *pointer, Size size)
Definition: mcxt.c:1659
void * repalloc_extended(void *pointer, Size size, int flags)
Definition: mcxt.c:1569
#define MCXT_METHOD(pointer, method)
Definition: mcxt.c:170
#define VALGRIND_DESTROY_MEMPOOL(context)
Definition: memdebug.h:25
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition: memdebug.h:26
#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size)
Definition: memdebug.h:31
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
Definition: memdebug.h:24
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
Definition: memdebug.h:29
#define VALGRIND_MEMPOOL_FREE(context, addr)
Definition: memdebug.h:30
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition: memdebug.h:27
#define MemoryContextIsValid(context)
Definition: memnodes.h:145
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153
#define AllocHugeSizeIsValid(size)
Definition: memutils.h:49
#define AllocSizeIsValid(size)
Definition: memutils.h:42
#define MEMORY_CONTEXT_METHODID_MASK
#define PallocAlignedExtraBytes(alignto)
MemoryContextMethodID
@ MCTX_GENERATION_ID
@ MCTX_UNUSED4_ID
@ MCTX_UNUSED3_ID
@ MCTX_UNUSED1_ID
@ MCTX_UNUSED2_ID
@ MCTX_SLAB_ID
@ MCTX_ASET_ID
@ MCTX_ALIGNED_REDIRECT_ID
struct MemoryChunk MemoryChunk
#define PointerGetMemoryChunk(p)
static void MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block, Size value, MemoryContextMethodID methodid)
NodeTag
Definition: nodes.h:27
const void size_t len
#define fprintf
Definition: port.h:242
size_t strnlen(const char *str, size_t maxlen)
Definition: strnlen.c:26
bool stack_is_too_deep(void)
Definition: postgres.c:3545
char * c
static pg_noinline void Size size
Definition: slab.c:607
void * SlabAlloc(MemoryContext context, Size size, int flags)
Definition: slab.c:630
void SlabFree(void *pointer)
Definition: slab.c:701
void SlabReset(MemoryContext context)
Definition: slab.c:431
Size SlabGetChunkSpace(void *pointer)
Definition: slab.c:887
bool SlabIsEmpty(MemoryContext context)
Definition: slab.c:912
MemoryContext SlabGetChunkContext(void *pointer)
Definition: slab.c:863
void SlabStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
Definition: slab.c:929
void SlabDelete(MemoryContext context)
Definition: slab.c:485
void * SlabRealloc(void *pointer, Size size, int flags)
Definition: slab.c:826
struct MemoryContextCallback * next
Definition: palloc.h:51
MemoryContextCallbackFunction func
Definition: palloc.h:49
MemoryContext prevchild
Definition: memnodes.h:129
MemoryContext firstchild
Definition: memnodes.h:128
bool allowInCritSection
Definition: memnodes.h:124
const char * ident
Definition: memnodes.h:132
MemoryContext parent
Definition: memnodes.h:127
MemoryContextCallback * reset_cbs
Definition: memnodes.h:133
const MemoryContextMethods * methods
Definition: memnodes.h:126
MemoryContext nextchild
Definition: memnodes.h:130
const char * name
Definition: memnodes.h:131
void(* delete_context)(MemoryContext context)
Definition: memnodes.h:86
void(* stats)(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals, bool print_to_stderr)
Definition: memnodes.h:102
bool(* is_empty)(MemoryContext context)
Definition: memnodes.h:101
void *(* alloc)(MemoryContext context, Size size, int flags)
Definition: memnodes.h:66
void(* reset)(MemoryContext context)
Definition: memnodes.h:83
const char * name