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