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-2019, 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"
28 
29 
30 /*****************************************************************************
31  * GLOBAL MEMORY *
32  *****************************************************************************/
33 
34 /*
35  * CurrentMemoryContext
36  * Default memory context for allocations.
37  */
39 
40 /*
41  * Standard top-level contexts. For a description of the purpose of each
42  * of these contexts, refer to src/backend/utils/mmgr/README
43  */
51 
52 /* This is a transient link to the active portal's memory context: */
54 
56 static void MemoryContextStatsInternal(MemoryContext context, int level,
57  bool print, int max_children,
58  MemoryContextCounters *totals);
59 static void MemoryContextStatsPrint(MemoryContext context, void *passthru,
60  const char *stats_string);
61 
62 /*
63  * You should not do memory allocations within a critical section, because
64  * an out-of-memory error will be escalated to a PANIC. To enforce that
65  * rule, the allocation functions Assert that.
66  */
67 #define AssertNotInCriticalSection(context) \
68  Assert(CritSectionCount == 0 || (context)->allowInCritSection)
69 
70 /*****************************************************************************
71  * EXPORTED ROUTINES *
72  *****************************************************************************/
73 
74 
75 /*
76  * MemoryContextInit
77  * Start up the memory-context subsystem.
78  *
79  * This must be called before creating contexts or allocating memory in
80  * contexts. TopMemoryContext and ErrorContext are initialized here;
81  * other contexts must be created afterwards.
82  *
83  * In normal multi-backend operation, this is called once during
84  * postmaster startup, and not at all by individual backend startup
85  * (since the backends inherit an already-initialized context subsystem
86  * by virtue of being forked off the postmaster). But in an EXEC_BACKEND
87  * build, each process must do this for itself.
88  *
89  * In a standalone backend this must be called during backend startup.
90  */
91 void
93 {
94  AssertState(TopMemoryContext == NULL);
95 
96  /*
97  * First, initialize TopMemoryContext, which is the parent of all others.
98  */
99  TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
100  "TopMemoryContext",
102 
103  /*
104  * Not having any other place to point CurrentMemoryContext, make it point
105  * to TopMemoryContext. Caller should change this soon!
106  */
107  CurrentMemoryContext = TopMemoryContext;
108 
109  /*
110  * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
111  * we don't really expect much to be allocated in it. More to the point,
112  * require it to contain at least 8K at all times. This is the only case
113  * where retained memory in a context is *essential* --- we want to be
114  * sure ErrorContext still has some memory even if we've run out
115  * elsewhere! Also, allow allocations in ErrorContext within a critical
116  * section. Otherwise a PANIC will cause an assertion failure in the error
117  * reporting code, before printing out the real cause of the failure.
118  *
119  * This should be the last step in this function, as elog.c assumes memory
120  * management works once ErrorContext is non-null.
121  */
122  ErrorContext = AllocSetContextCreate(TopMemoryContext,
123  "ErrorContext",
124  8 * 1024,
125  8 * 1024,
126  8 * 1024);
127  MemoryContextAllowInCriticalSection(ErrorContext, true);
128 }
129 
130 /*
131  * MemoryContextReset
132  * Release all space allocated within a context and delete all its
133  * descendant contexts (but not the named context itself).
134  */
135 void
137 {
139 
140  /* save a function call in common case where there are no children */
141  if (context->firstchild != NULL)
143 
144  /* save a function call if no pallocs since startup or last reset */
145  if (!context->isReset)
146  MemoryContextResetOnly(context);
147 }
148 
149 /*
150  * MemoryContextResetOnly
151  * Release all space allocated within a context.
152  * Nothing is done to the context's descendant contexts.
153  */
154 void
156 {
158 
159  /* Nothing to do if no pallocs since startup or last reset */
160  if (!context->isReset)
161  {
163 
164  /*
165  * If context->ident points into the context's memory, it will become
166  * a dangling pointer. We could prevent that by setting it to NULL
167  * here, but that would break valid coding patterns that keep the
168  * ident elsewhere, e.g. in a parent context. Another idea is to use
169  * MemoryContextContains(), but we don't require ident strings to be
170  * in separately-palloc'd chunks, so that risks false positives. So
171  * for now we assume the programmer got it right.
172  */
173 
174  context->methods->reset(context);
175  context->isReset = true;
176  VALGRIND_DESTROY_MEMPOOL(context);
177  VALGRIND_CREATE_MEMPOOL(context, 0, false);
178  }
179 }
180 
181 /*
182  * MemoryContextResetChildren
183  * Release all space allocated within a context's descendants,
184  * but don't delete the contexts themselves. The named context
185  * itself is not touched.
186  */
187 void
189 {
190  MemoryContext child;
191 
193 
194  for (child = context->firstchild; child != NULL; child = child->nextchild)
195  {
197  MemoryContextResetOnly(child);
198  }
199 }
200 
201 /*
202  * MemoryContextDelete
203  * Delete a context and its descendants, and release all space
204  * allocated therein.
205  *
206  * The type-specific delete routine removes all storage for the context,
207  * but we have to recurse to handle the children.
208  * We must also delink the context from its parent, if it has one.
209  */
210 void
212 {
214  /* We had better not be deleting TopMemoryContext ... */
215  Assert(context != TopMemoryContext);
216  /* And not CurrentMemoryContext, either */
217  Assert(context != CurrentMemoryContext);
218 
219  /* save a function call in common case where there are no children */
220  if (context->firstchild != NULL)
222 
223  /*
224  * It's not entirely clear whether 'tis better to do this before or after
225  * delinking the context; but an error in a callback will likely result in
226  * leaking the whole context (if it's not a root context) if we do it
227  * after, so let's do it before.
228  */
230 
231  /*
232  * We delink the context from its parent before deleting it, so that if
233  * there's an error we won't have deleted/busted contexts still attached
234  * to the context tree. Better a leak than a crash.
235  */
236  MemoryContextSetParent(context, NULL);
237 
238  /*
239  * Also reset the context's ident pointer, in case it points into the
240  * context. This would only matter if someone tries to get stats on the
241  * (already unlinked) context, which is unlikely, but let's be safe.
242  */
243  context->ident = NULL;
244 
245  context->methods->delete_context(context);
246 
247  VALGRIND_DESTROY_MEMPOOL(context);
248 }
249 
250 /*
251  * MemoryContextDeleteChildren
252  * Delete all the descendants of the named context and release all
253  * space allocated therein. The named context itself is not touched.
254  */
255 void
257 {
259 
260  /*
261  * MemoryContextDelete will delink the child from me, so just iterate as
262  * long as there is a child.
263  */
264  while (context->firstchild != NULL)
266 }
267 
268 /*
269  * MemoryContextRegisterResetCallback
270  * Register a function to be called before next context reset/delete.
271  * Such callbacks will be called in reverse order of registration.
272  *
273  * The caller is responsible for allocating a MemoryContextCallback struct
274  * to hold the info about this callback request, and for filling in the
275  * "func" and "arg" fields in the struct to show what function to call with
276  * what argument. Typically the callback struct should be allocated within
277  * the specified context, since that means it will automatically be freed
278  * when no longer needed.
279  *
280  * There is no API for deregistering a callback once registered. If you
281  * want it to not do anything anymore, adjust the state pointed to by its
282  * "arg" to indicate that.
283  */
284 void
287 {
289 
290  /* Push onto head so this will be called before older registrants. */
291  cb->next = context->reset_cbs;
292  context->reset_cbs = cb;
293  /* Mark the context as non-reset (it probably is already). */
294  context->isReset = false;
295 }
296 
297 /*
298  * MemoryContextCallResetCallbacks
299  * Internal function to call all registered callbacks for context.
300  */
301 static void
303 {
305 
306  /*
307  * We pop each callback from the list before calling. That way, if an
308  * error occurs inside the callback, we won't try to call it a second time
309  * in the likely event that we reset or delete the context later.
310  */
311  while ((cb = context->reset_cbs) != NULL)
312  {
313  context->reset_cbs = cb->next;
314  cb->func(cb->arg);
315  }
316 }
317 
318 /*
319  * MemoryContextSetIdentifier
320  * Set the identifier string for a memory context.
321  *
322  * An identifier can be provided to help distinguish among different contexts
323  * of the same kind in memory context stats dumps. The identifier string
324  * must live at least as long as the context it is for; typically it is
325  * allocated inside that context, so that it automatically goes away on
326  * context deletion. Pass id = NULL to forget any old identifier.
327  */
328 void
330 {
332  context->ident = id;
333 }
334 
335 /*
336  * MemoryContextSetParent
337  * Change a context to belong to a new parent (or no parent).
338  *
339  * We provide this as an API function because it is sometimes useful to
340  * change a context's lifespan after creation. For example, a context
341  * might be created underneath a transient context, filled with data,
342  * and then reparented underneath CacheMemoryContext to make it long-lived.
343  * In this way no special effort is needed to get rid of the context in case
344  * a failure occurs before its contents are completely set up.
345  *
346  * Callers often assume that this function cannot fail, so don't put any
347  * elog(ERROR) calls in it.
348  *
349  * A possible caller error is to reparent a context under itself, creating
350  * a loop in the context graph. We assert here that context != new_parent,
351  * but checking for multi-level loops seems more trouble than it's worth.
352  */
353 void
355 {
357  AssertArg(context != new_parent);
358 
359  /* Fast path if it's got correct parent already */
360  if (new_parent == context->parent)
361  return;
362 
363  /* Delink from existing parent, if any */
364  if (context->parent)
365  {
366  MemoryContext parent = context->parent;
367 
368  if (context->prevchild != NULL)
369  context->prevchild->nextchild = context->nextchild;
370  else
371  {
372  Assert(parent->firstchild == context);
373  parent->firstchild = context->nextchild;
374  }
375 
376  if (context->nextchild != NULL)
377  context->nextchild->prevchild = context->prevchild;
378  }
379 
380  /* And relink */
381  if (new_parent)
382  {
383  AssertArg(MemoryContextIsValid(new_parent));
384  context->parent = new_parent;
385  context->prevchild = NULL;
386  context->nextchild = new_parent->firstchild;
387  if (new_parent->firstchild != NULL)
388  new_parent->firstchild->prevchild = context;
389  new_parent->firstchild = context;
390  }
391  else
392  {
393  context->parent = NULL;
394  context->prevchild = NULL;
395  context->nextchild = NULL;
396  }
397 }
398 
399 /*
400  * MemoryContextAllowInCriticalSection
401  * Allow/disallow allocations in this memory context within a critical
402  * section.
403  *
404  * Normally, memory allocations are not allowed within a critical section,
405  * because a failure would lead to PANIC. There are a few exceptions to
406  * that, like allocations related to debugging code that is not supposed to
407  * be enabled in production. This function can be used to exempt specific
408  * memory contexts from the assertion in palloc().
409  */
410 void
412 {
414 
415  context->allowInCritSection = allow;
416 }
417 
418 /*
419  * GetMemoryChunkSpace
420  * Given a currently-allocated chunk, determine the total space
421  * it occupies (including all memory-allocation overhead).
422  *
423  * This is useful for measuring the total space occupied by a set of
424  * allocated chunks.
425  */
426 Size
427 GetMemoryChunkSpace(void *pointer)
428 {
429  MemoryContext context = GetMemoryChunkContext(pointer);
430 
431  return context->methods->get_chunk_space(context, pointer);
432 }
433 
434 /*
435  * MemoryContextGetParent
436  * Get the parent context (if any) of the specified context
437  */
440 {
442 
443  return context->parent;
444 }
445 
446 /*
447  * MemoryContextIsEmpty
448  * Is a memory context empty of any allocated space?
449  */
450 bool
452 {
454 
455  /*
456  * For now, we consider a memory context nonempty if it has any children;
457  * perhaps this should be changed later.
458  */
459  if (context->firstchild != NULL)
460  return false;
461  /* Otherwise use the type-specific inquiry */
462  return context->methods->is_empty(context);
463 }
464 
465 /*
466  * Find the memory allocated to blocks for this memory context. If recurse is
467  * true, also include children.
468  */
469 Size
471 {
472  Size total = context->mem_allocated;
473 
475 
476  if (recurse)
477  {
478  MemoryContext child = context->firstchild;
479 
480  for (child = context->firstchild;
481  child != NULL;
482  child = child->nextchild)
483  total += MemoryContextMemAllocated(child, true);
484  }
485 
486  return total;
487 }
488 
489 /*
490  * MemoryContextStats
491  * Print statistics about the named context and all its descendants.
492  *
493  * This is just a debugging utility, so it's not very fancy. However, we do
494  * make some effort to summarize when the output would otherwise be very long.
495  * The statistics are sent to stderr.
496  */
497 void
499 {
500  /* A hard-wired limit on the number of children is usually good enough */
501  MemoryContextStatsDetail(context, 100);
502 }
503 
504 /*
505  * MemoryContextStatsDetail
506  *
507  * Entry point for use if you want to vary the number of child contexts shown.
508  */
509 void
510 MemoryContextStatsDetail(MemoryContext context, int max_children)
511 {
512  MemoryContextCounters grand_totals;
513 
514  memset(&grand_totals, 0, sizeof(grand_totals));
515 
516  MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals);
517 
518  fprintf(stderr,
519  "Grand total: %zu bytes in %zd blocks; %zu free (%zd chunks); %zu used\n",
520  grand_totals.totalspace, grand_totals.nblocks,
521  grand_totals.freespace, grand_totals.freechunks,
522  grand_totals.totalspace - grand_totals.freespace);
523 }
524 
525 /*
526  * MemoryContextStatsInternal
527  * One recursion level for MemoryContextStats
528  *
529  * Print this context if print is true, but in any case accumulate counts into
530  * *totals (if given).
531  */
532 static void
534  bool print, int max_children,
535  MemoryContextCounters *totals)
536 {
537  MemoryContextCounters local_totals;
538  MemoryContext child;
539  int ichild;
540 
542 
543  /* Examine the context itself */
544  context->methods->stats(context,
545  print ? MemoryContextStatsPrint : NULL,
546  (void *) &level,
547  totals);
548 
549  /*
550  * Examine children. If there are more than max_children of them, we do
551  * not print the rest explicitly, but just summarize them.
552  */
553  memset(&local_totals, 0, sizeof(local_totals));
554 
555  for (child = context->firstchild, ichild = 0;
556  child != NULL;
557  child = child->nextchild, ichild++)
558  {
559  if (ichild < max_children)
560  MemoryContextStatsInternal(child, level + 1,
561  print, max_children,
562  totals);
563  else
564  MemoryContextStatsInternal(child, level + 1,
565  false, max_children,
566  &local_totals);
567  }
568 
569  /* Deal with excess children */
570  if (ichild > max_children)
571  {
572  if (print)
573  {
574  int i;
575 
576  for (i = 0; i <= level; i++)
577  fprintf(stderr, " ");
578  fprintf(stderr,
579  "%d more child contexts containing %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n",
580  ichild - max_children,
581  local_totals.totalspace,
582  local_totals.nblocks,
583  local_totals.freespace,
584  local_totals.freechunks,
585  local_totals.totalspace - local_totals.freespace);
586  }
587 
588  if (totals)
589  {
590  totals->nblocks += local_totals.nblocks;
591  totals->freechunks += local_totals.freechunks;
592  totals->totalspace += local_totals.totalspace;
593  totals->freespace += local_totals.freespace;
594  }
595  }
596 }
597 
598 /*
599  * MemoryContextStatsPrint
600  * Print callback used by MemoryContextStatsInternal
601  *
602  * For now, the passthru pointer just points to "int level"; later we might
603  * make that more complicated.
604  */
605 static void
606 MemoryContextStatsPrint(MemoryContext context, void *passthru,
607  const char *stats_string)
608 {
609  int level = *(int *) passthru;
610  const char *name = context->name;
611  const char *ident = context->ident;
612  int i;
613 
614  /*
615  * It seems preferable to label dynahash contexts with just the hash table
616  * name. Those are already unique enough, so the "dynahash" part isn't
617  * very helpful, and this way is more consistent with pre-v11 practice.
618  */
619  if (ident && strcmp(name, "dynahash") == 0)
620  {
621  name = ident;
622  ident = NULL;
623  }
624 
625  for (i = 0; i < level; i++)
626  fprintf(stderr, " ");
627  fprintf(stderr, "%s: %s", name, stats_string);
628  if (ident)
629  {
630  /*
631  * Some contexts may have very long identifiers (e.g., SQL queries).
632  * Arbitrarily truncate at 100 bytes, but be careful not to break
633  * multibyte characters. Also, replace ASCII control characters, such
634  * as newlines, with spaces.
635  */
636  int idlen = strlen(ident);
637  bool truncated = false;
638 
639  if (idlen > 100)
640  {
641  idlen = pg_mbcliplen(ident, idlen, 100);
642  truncated = true;
643  }
644  fprintf(stderr, ": ");
645  while (idlen-- > 0)
646  {
647  unsigned char c = *ident++;
648 
649  if (c < ' ')
650  c = ' ';
651  fputc(c, stderr);
652  }
653  if (truncated)
654  fprintf(stderr, "...");
655  }
656  fputc('\n', stderr);
657 }
658 
659 /*
660  * MemoryContextCheck
661  * Check all chunks in the named context.
662  *
663  * This is just a debugging utility, so it's not fancy.
664  */
665 #ifdef MEMORY_CONTEXT_CHECKING
666 void
667 MemoryContextCheck(MemoryContext context)
668 {
669  MemoryContext child;
670 
672 
673  context->methods->check(context);
674  for (child = context->firstchild; child != NULL; child = child->nextchild)
675  MemoryContextCheck(child);
676 }
677 #endif
678 
679 /*
680  * MemoryContextContains
681  * Detect whether an allocated chunk of memory belongs to a given
682  * context or not.
683  *
684  * Caution: this test is reliable as long as 'pointer' does point to
685  * a chunk of memory allocated from *some* context. If 'pointer' points
686  * at memory obtained in some other way, there is a small chance of a
687  * false-positive result, since the bits right before it might look like
688  * a valid chunk header by chance.
689  */
690 bool
691 MemoryContextContains(MemoryContext context, void *pointer)
692 {
693  MemoryContext ptr_context;
694 
695  /*
696  * NB: Can't use GetMemoryChunkContext() here - that performs assertions
697  * that aren't acceptable here since we might be passed memory not
698  * allocated by any memory context.
699  *
700  * Try to detect bogus pointers handed to us, poorly though we can.
701  * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
702  * allocated chunk.
703  */
704  if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
705  return false;
706 
707  /*
708  * OK, it's probably safe to look at the context.
709  */
710  ptr_context = *(MemoryContext *) (((char *) pointer) - sizeof(void *));
711 
712  return ptr_context == context;
713 }
714 
715 /*
716  * MemoryContextCreate
717  * Context-type-independent part of context creation.
718  *
719  * This is only intended to be called by context-type-specific
720  * context creation routines, not by the unwashed masses.
721  *
722  * The memory context creation procedure goes like this:
723  * 1. Context-type-specific routine makes some initial space allocation,
724  * including enough space for the context header. If it fails,
725  * it can ereport() with no damage done.
726  * 2. Context-type-specific routine sets up all type-specific fields of
727  * the header (those beyond MemoryContextData proper), as well as any
728  * other management fields it needs to have a fully valid context.
729  * Usually, failure in this step is impossible, but if it's possible
730  * the initial space allocation should be freed before ereport'ing.
731  * 3. Context-type-specific routine calls MemoryContextCreate() to fill in
732  * the generic header fields and link the context into the context tree.
733  * 4. We return to the context-type-specific routine, which finishes
734  * up type-specific initialization. This routine can now do things
735  * that might fail (like allocate more memory), so long as it's
736  * sure the node is left in a state that delete will handle.
737  *
738  * node: the as-yet-uninitialized common part of the context header node.
739  * tag: NodeTag code identifying the memory context type.
740  * methods: context-type-specific methods (usually statically allocated).
741  * parent: parent context, or NULL if this will be a top-level context.
742  * name: name of context (must be statically allocated).
743  *
744  * Context routines generally assume that MemoryContextCreate can't fail,
745  * so this can contain Assert but not elog/ereport.
746  */
747 void
749  NodeTag tag,
750  const MemoryContextMethods *methods,
751  MemoryContext parent,
752  const char *name)
753 {
754  /* Creating new memory contexts is not allowed in a critical section */
755  Assert(CritSectionCount == 0);
756 
757  /* Initialize all standard fields of memory context header */
758  node->type = tag;
759  node->isReset = true;
760  node->methods = methods;
761  node->parent = parent;
762  node->firstchild = NULL;
763  node->mem_allocated = 0;
764  node->prevchild = NULL;
765  node->name = name;
766  node->ident = NULL;
767  node->reset_cbs = NULL;
768 
769  /* OK to link node into context tree */
770  if (parent)
771  {
772  node->nextchild = parent->firstchild;
773  if (parent->firstchild != NULL)
774  parent->firstchild->prevchild = node;
775  parent->firstchild = node;
776  /* inherit allowInCritSection flag from parent */
777  node->allowInCritSection = parent->allowInCritSection;
778  }
779  else
780  {
781  node->nextchild = NULL;
782  node->allowInCritSection = false;
783  }
784 
785  VALGRIND_CREATE_MEMPOOL(node, 0, false);
786 }
787 
788 /*
789  * MemoryContextAlloc
790  * Allocate space within the specified context.
791  *
792  * This could be turned into a macro, but we'd have to import
793  * nodes/memnodes.h into postgres.h which seems a bad idea.
794  */
795 void *
797 {
798  void *ret;
799 
802 
803  if (!AllocSizeIsValid(size))
804  elog(ERROR, "invalid memory alloc request size %zu", size);
805 
806  context->isReset = false;
807 
808  ret = context->methods->alloc(context, size);
809  if (unlikely(ret == NULL))
810  {
811  MemoryContextStats(TopMemoryContext);
812 
813  /*
814  * Here, and elsewhere in this module, we show the target context's
815  * "name" but not its "ident" (if any) in user-visible error messages.
816  * The "ident" string might contain security-sensitive data, such as
817  * values in SQL commands.
818  */
819  ereport(ERROR,
820  (errcode(ERRCODE_OUT_OF_MEMORY),
821  errmsg("out of memory"),
822  errdetail("Failed on request of size %zu in memory context \"%s\".",
823  size, context->name)));
824  }
825 
826  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
827 
828  return ret;
829 }
830 
831 /*
832  * MemoryContextAllocZero
833  * Like MemoryContextAlloc, but clears allocated memory
834  *
835  * We could just call MemoryContextAlloc then clear the memory, but this
836  * is a very common combination, so we provide the combined operation.
837  */
838 void *
840 {
841  void *ret;
842 
845 
846  if (!AllocSizeIsValid(size))
847  elog(ERROR, "invalid memory alloc request size %zu", size);
848 
849  context->isReset = false;
850 
851  ret = context->methods->alloc(context, size);
852  if (unlikely(ret == NULL))
853  {
854  MemoryContextStats(TopMemoryContext);
855  ereport(ERROR,
856  (errcode(ERRCODE_OUT_OF_MEMORY),
857  errmsg("out of memory"),
858  errdetail("Failed on request of size %zu in memory context \"%s\".",
859  size, context->name)));
860  }
861 
862  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
863 
864  MemSetAligned(ret, 0, size);
865 
866  return ret;
867 }
868 
869 /*
870  * MemoryContextAllocZeroAligned
871  * MemoryContextAllocZero where length is suitable for MemSetLoop
872  *
873  * This might seem overly specialized, but it's not because newNode()
874  * is so often called with compile-time-constant sizes.
875  */
876 void *
878 {
879  void *ret;
880 
883 
884  if (!AllocSizeIsValid(size))
885  elog(ERROR, "invalid memory alloc request size %zu", size);
886 
887  context->isReset = false;
888 
889  ret = context->methods->alloc(context, size);
890  if (unlikely(ret == NULL))
891  {
892  MemoryContextStats(TopMemoryContext);
893  ereport(ERROR,
894  (errcode(ERRCODE_OUT_OF_MEMORY),
895  errmsg("out of memory"),
896  errdetail("Failed on request of size %zu in memory context \"%s\".",
897  size, context->name)));
898  }
899 
900  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
901 
902  MemSetLoop(ret, 0, size);
903 
904  return ret;
905 }
906 
907 /*
908  * MemoryContextAllocExtended
909  * Allocate space within the specified context using the given flags.
910  */
911 void *
913 {
914  void *ret;
915 
918 
919  if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) ||
920  ((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size)))
921  elog(ERROR, "invalid memory alloc request size %zu", size);
922 
923  context->isReset = false;
924 
925  ret = context->methods->alloc(context, size);
926  if (unlikely(ret == NULL))
927  {
928  if ((flags & MCXT_ALLOC_NO_OOM) == 0)
929  {
930  MemoryContextStats(TopMemoryContext);
931  ereport(ERROR,
932  (errcode(ERRCODE_OUT_OF_MEMORY),
933  errmsg("out of memory"),
934  errdetail("Failed on request of size %zu in memory context \"%s\".",
935  size, context->name)));
936  }
937  return NULL;
938  }
939 
940  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
941 
942  if ((flags & MCXT_ALLOC_ZERO) != 0)
943  MemSetAligned(ret, 0, size);
944 
945  return ret;
946 }
947 
948 void *
950 {
951  /* duplicates MemoryContextAlloc to avoid increased overhead */
952  void *ret;
954 
957 
958  if (!AllocSizeIsValid(size))
959  elog(ERROR, "invalid memory alloc request size %zu", size);
960 
961  context->isReset = false;
962 
963  ret = context->methods->alloc(context, size);
964  if (unlikely(ret == NULL))
965  {
966  MemoryContextStats(TopMemoryContext);
967  ereport(ERROR,
968  (errcode(ERRCODE_OUT_OF_MEMORY),
969  errmsg("out of memory"),
970  errdetail("Failed on request of size %zu in memory context \"%s\".",
971  size, context->name)));
972  }
973 
974  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
975 
976  return ret;
977 }
978 
979 void *
981 {
982  /* duplicates MemoryContextAllocZero to avoid increased overhead */
983  void *ret;
985 
988 
989  if (!AllocSizeIsValid(size))
990  elog(ERROR, "invalid memory alloc request size %zu", size);
991 
992  context->isReset = false;
993 
994  ret = context->methods->alloc(context, size);
995  if (unlikely(ret == NULL))
996  {
997  MemoryContextStats(TopMemoryContext);
998  ereport(ERROR,
999  (errcode(ERRCODE_OUT_OF_MEMORY),
1000  errmsg("out of memory"),
1001  errdetail("Failed on request of size %zu in memory context \"%s\".",
1002  size, context->name)));
1003  }
1004 
1005  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1006 
1007  MemSetAligned(ret, 0, size);
1008 
1009  return ret;
1010 }
1011 
1012 void *
1013 palloc_extended(Size size, int flags)
1014 {
1015  /* duplicates MemoryContextAllocExtended to avoid increased overhead */
1016  void *ret;
1018 
1019  AssertArg(MemoryContextIsValid(context));
1020  AssertNotInCriticalSection(context);
1021 
1022  if (((flags & MCXT_ALLOC_HUGE) != 0 && !AllocHugeSizeIsValid(size)) ||
1023  ((flags & MCXT_ALLOC_HUGE) == 0 && !AllocSizeIsValid(size)))
1024  elog(ERROR, "invalid memory alloc request size %zu", size);
1025 
1026  context->isReset = false;
1027 
1028  ret = context->methods->alloc(context, size);
1029  if (unlikely(ret == NULL))
1030  {
1031  if ((flags & MCXT_ALLOC_NO_OOM) == 0)
1032  {
1033  MemoryContextStats(TopMemoryContext);
1034  ereport(ERROR,
1035  (errcode(ERRCODE_OUT_OF_MEMORY),
1036  errmsg("out of memory"),
1037  errdetail("Failed on request of size %zu in memory context \"%s\".",
1038  size, context->name)));
1039  }
1040  return NULL;
1041  }
1042 
1043  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1044 
1045  if ((flags & MCXT_ALLOC_ZERO) != 0)
1046  MemSetAligned(ret, 0, size);
1047 
1048  return ret;
1049 }
1050 
1051 /*
1052  * pfree
1053  * Release an allocated chunk.
1054  */
1055 void
1056 pfree(void *pointer)
1057 {
1058  MemoryContext context = GetMemoryChunkContext(pointer);
1059 
1060  context->methods->free_p(context, pointer);
1061  VALGRIND_MEMPOOL_FREE(context, pointer);
1062 }
1063 
1064 /*
1065  * repalloc
1066  * Adjust the size of a previously allocated chunk.
1067  */
1068 void *
1069 repalloc(void *pointer, Size size)
1070 {
1071  MemoryContext context = GetMemoryChunkContext(pointer);
1072  void *ret;
1073 
1074  if (!AllocSizeIsValid(size))
1075  elog(ERROR, "invalid memory alloc request size %zu", size);
1076 
1077  AssertNotInCriticalSection(context);
1078 
1079  /* isReset must be false already */
1080  Assert(!context->isReset);
1081 
1082  ret = context->methods->realloc(context, pointer, size);
1083  if (unlikely(ret == NULL))
1084  {
1085  MemoryContextStats(TopMemoryContext);
1086  ereport(ERROR,
1087  (errcode(ERRCODE_OUT_OF_MEMORY),
1088  errmsg("out of memory"),
1089  errdetail("Failed on request of size %zu in memory context \"%s\".",
1090  size, context->name)));
1091  }
1092 
1093  VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
1094 
1095  return ret;
1096 }
1097 
1098 /*
1099  * MemoryContextAllocHuge
1100  * Allocate (possibly-expansive) space within the specified context.
1101  *
1102  * See considerations in comment at MaxAllocHugeSize.
1103  */
1104 void *
1106 {
1107  void *ret;
1108 
1109  AssertArg(MemoryContextIsValid(context));
1110  AssertNotInCriticalSection(context);
1111 
1112  if (!AllocHugeSizeIsValid(size))
1113  elog(ERROR, "invalid memory alloc request size %zu", size);
1114 
1115  context->isReset = false;
1116 
1117  ret = context->methods->alloc(context, size);
1118  if (unlikely(ret == NULL))
1119  {
1120  MemoryContextStats(TopMemoryContext);
1121  ereport(ERROR,
1122  (errcode(ERRCODE_OUT_OF_MEMORY),
1123  errmsg("out of memory"),
1124  errdetail("Failed on request of size %zu in memory context \"%s\".",
1125  size, context->name)));
1126  }
1127 
1128  VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1129 
1130  return ret;
1131 }
1132 
1133 /*
1134  * repalloc_huge
1135  * Adjust the size of a previously allocated chunk, permitting a large
1136  * value. The previous allocation need not have been "huge".
1137  */
1138 void *
1139 repalloc_huge(void *pointer, Size size)
1140 {
1141  MemoryContext context = GetMemoryChunkContext(pointer);
1142  void *ret;
1143 
1144  if (!AllocHugeSizeIsValid(size))
1145  elog(ERROR, "invalid memory alloc request size %zu", size);
1146 
1147  AssertNotInCriticalSection(context);
1148 
1149  /* isReset must be false already */
1150  Assert(!context->isReset);
1151 
1152  ret = context->methods->realloc(context, pointer, size);
1153  if (unlikely(ret == NULL))
1154  {
1155  MemoryContextStats(TopMemoryContext);
1156  ereport(ERROR,
1157  (errcode(ERRCODE_OUT_OF_MEMORY),
1158  errmsg("out of memory"),
1159  errdetail("Failed on request of size %zu in memory context \"%s\".",
1160  size, context->name)));
1161  }
1162 
1163  VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
1164 
1165  return ret;
1166 }
1167 
1168 /*
1169  * MemoryContextStrdup
1170  * Like strdup(), but allocate from the specified context
1171  */
1172 char *
1173 MemoryContextStrdup(MemoryContext context, const char *string)
1174 {
1175  char *nstr;
1176  Size len = strlen(string) + 1;
1177 
1178  nstr = (char *) MemoryContextAlloc(context, len);
1179 
1180  memcpy(nstr, string, len);
1181 
1182  return nstr;
1183 }
1184 
1185 char *
1186 pstrdup(const char *in)
1187 {
1188  return MemoryContextStrdup(CurrentMemoryContext, in);
1189 }
1190 
1191 /*
1192  * pnstrdup
1193  * Like pstrdup(), but append null byte to a
1194  * not-necessarily-null-terminated input string.
1195  */
1196 char *
1197 pnstrdup(const char *in, Size len)
1198 {
1199  char *out;
1200 
1201  len = strnlen(in, len);
1202 
1203  out = palloc(len + 1);
1204  memcpy(out, in, len);
1205  out[len] = '\0';
1206 
1207  return out;
1208 }
1209 
1210 /*
1211  * Make copy of string with all trailing newline characters removed.
1212  */
1213 char *
1214 pchomp(const char *in)
1215 {
1216  size_t n;
1217 
1218  n = strlen(in);
1219  while (n > 0 && in[n - 1] == '\n')
1220  n--;
1221  return pnstrdup(in, n);
1222 }
#define MemSetAligned(start, val, len)
Definition: c.h:989
MemoryContextCallbackFunction func
Definition: palloc.h:49
Size(* get_chunk_space)(MemoryContext context, void *pointer)
Definition: memnodes.h:65
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:211
#define AllocSetContextCreate
Definition: memutils.h:170
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1197
static void MemoryContextCallResetCallbacks(MemoryContext context)
Definition: mcxt.c:302
#define AssertState(condition)
Definition: c.h:736
MemoryContext TopTransactionContext
Definition: mcxt.c:49
MemoryContextCallback * reset_cbs
Definition: memnodes.h:90
void print(const void *obj)
Definition: print.c:36
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
Definition: mcxt.c:411
void MemoryContextInit(void)
Definition: mcxt.c:92
#define MCXT_ALLOC_HUGE
Definition: fe_memutils.h:16
const MemoryContextMethods * methods
Definition: memnodes.h:83
MemoryContext MemoryContextGetParent(MemoryContext context)
Definition: mcxt.c:439
MemoryContext ErrorContext
Definition: mcxt.c:45
void(* reset)(MemoryContext context)
Definition: memnodes.h:63
void * MemoryContextAllocExtended(MemoryContext context, Size size, int flags)
Definition: mcxt.c:912
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
Definition: mcxt.c:354
char * pstrdup(const char *in)
Definition: mcxt.c:1186
bool allowInCritSection
Definition: memnodes.h:81
static void MemoryContextStatsInternal(MemoryContext context, int level, bool print, int max_children, MemoryContextCounters *totals)
Definition: mcxt.c:533
MemoryContext CurTransactionContext
Definition: mcxt.c:50
void * palloc_extended(Size size, int flags)
Definition: mcxt.c:1013
#define MCXT_ALLOC_NO_OOM
Definition: fe_memutils.h:18
int errcode(int sqlerrcode)
Definition: elog.c:608
Size GetMemoryChunkSpace(void *pointer)
Definition: mcxt.c:427
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:136
#define AssertNotInCriticalSection(context)
Definition: mcxt.c:67
NodeTag
Definition: nodes.h:26
#define fprintf
Definition: port.h:196
void MemoryContextResetOnly(MemoryContext context)
Definition: mcxt.c:155
void(* stats)(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, MemoryContextCounters *totals)
Definition: memnodes.h:67
void *(* realloc)(MemoryContext context, void *pointer, Size size)
Definition: memnodes.h:62
MemoryContext PortalContext
Definition: mcxt.c:53
char * pchomp(const char *in)
Definition: mcxt.c:1214
MemoryContext firstchild
Definition: memnodes.h:85
void pfree(void *pointer)
Definition: mcxt.c:1056
void(* free_p)(MemoryContext context, void *pointer)
Definition: memnodes.h:61
#define ERROR
Definition: elog.h:43
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:451
bool(* is_empty)(MemoryContext context)
Definition: memnodes.h:66
#define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size)
Definition: memdebug.h:31
void MemoryContextStats(MemoryContext context)
Definition: mcxt.c:498
#define MemSetLoop(start, val, len)
Definition: c.h:1024
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:862
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:192
char * c
void * MemoryContextAllocHuge(MemoryContext context, Size size)
Definition: mcxt.c:1105
#define VALGRIND_MEMPOOL_FREE(context, addr)
Definition: memdebug.h:30
int errdetail(const char *fmt,...)
Definition: elog.c:957
MemoryContext prevchild
Definition: memnodes.h:86
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
void *(* alloc)(MemoryContext context, Size size)
Definition: memnodes.h:59
volatile uint32 CritSectionCount
Definition: globals.c:38
void MemoryContextCreate(MemoryContext node, NodeTag tag, const MemoryContextMethods *methods, MemoryContext parent, const char *name)
Definition: mcxt.c:748
#define ereport(elevel, rest)
Definition: elog.h:141
#define AssertArg(condition)
Definition: c.h:735
void * MemoryContextAllocZeroAligned(MemoryContext context, Size size)
Definition: mcxt.c:877
const char * ident
Definition: memnodes.h:89
MemoryContext TopMemoryContext
Definition: mcxt.c:44
#define AllocSizeIsValid(size)
Definition: memutils.h:42
void MemoryContextDeleteChildren(MemoryContext context)
Definition: mcxt.c:256
#define VALGRIND_DESTROY_MEMPOOL(context)
Definition: memdebug.h:25
void * palloc0(Size size)
Definition: mcxt.c:980
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:839
#define VALGRIND_CREATE_MEMPOOL(context, redzones, zeroed)
Definition: memdebug.h:24
Size MemoryContextMemAllocated(MemoryContext context, bool recurse)
Definition: mcxt.c:470
#define MemoryContextIsValid(context)
Definition: memnodes.h:102
#define VALGRIND_MEMPOOL_ALLOC(context, addr, size)
Definition: memdebug.h:29
#define Assert(condition)
Definition: c.h:733
void MemoryContextResetChildren(MemoryContext context)
Definition: mcxt.c:188
#define MCXT_ALLOC_ZERO
Definition: fe_memutils.h:19
bool MemoryContextContains(MemoryContext context, void *pointer)
Definition: mcxt.c:691
size_t Size
Definition: c.h:467
#define MAXALIGN(LEN)
Definition: c.h:686
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
Definition: mcxt.c:329
static void MemoryContextStatsPrint(MemoryContext context, void *passthru, const char *stats_string)
Definition: mcxt.c:606
size_t strnlen(const char *str, size_t maxlen)
Definition: strnlen.c:26
MemoryContext MessageContext
Definition: mcxt.c:48
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
const char * name
Definition: encode.c:521
Size mem_allocated
Definition: memnodes.h:82
#define AllocHugeSizeIsValid(size)
Definition: memutils.h:46
void * repalloc_huge(void *pointer, Size size)
Definition: mcxt.c:1139
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1173
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
struct MemoryContextCallback * next
Definition: palloc.h:51
#define elog(elevel,...)
Definition: elog.h:228
int i
MemoryContext parent
Definition: memnodes.h:84
#define unlikely(x)
Definition: c.h:208
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
Definition: mcxt.c:285
void(* delete_context)(MemoryContext context)
Definition: memnodes.h:64
MemoryContext PostmasterContext
Definition: mcxt.c:46
const char * name
Definition: memnodes.h:88
MemoryContext nextchild
Definition: memnodes.h:87
void MemoryContextStatsDetail(MemoryContext context, int max_children)
Definition: mcxt.c:510
static MemoryContext GetMemoryChunkContext(void *pointer)
Definition: memutils.h:113
MemoryContext CacheMemoryContext
Definition: mcxt.c:47
NodeTag type
Definition: memnodes.h:78