]> granicus.if.org Git - postgresql/blob - src/backend/utils/mmgr/mcxt.c
pgindent run for 9.4
[postgresql] / src / backend / utils / mmgr / mcxt.c
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-2014, 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 /* see palloc.h.  Must be before postgres.h */
23 #define MCXT_INCLUDE_DEFINITIONS
24
25 #include "postgres.h"
26
27 #include "miscadmin.h"
28 #include "utils/memdebug.h"
29 #include "utils/memutils.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 PostmasterContext = NULL;
49 MemoryContext CacheMemoryContext = NULL;
50 MemoryContext MessageContext = NULL;
51 MemoryContext TopTransactionContext = NULL;
52 MemoryContext CurTransactionContext = NULL;
53
54 /* This is a transient link to the active portal's memory context: */
55 MemoryContext PortalContext = NULL;
56
57 static void MemoryContextStatsInternal(MemoryContext context, int level);
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  * There are a two exceptions: 1) error recovery uses ErrorContext, which
65  * has some memory set aside so that you don't run out. And 2) checkpointer
66  * currently just hopes for the best, which is wrong and ought to be fixed,
67  * but it's a known issue so let's not complain about in the meanwhile.
68  */
69 #define AssertNotInCriticalSection(context) \
70         Assert(CritSectionCount == 0 || (context) == ErrorContext || \
71                    AmCheckpointerProcess())
72
73 /*****************************************************************************
74  *        EXPORTED ROUTINES                                                                                                              *
75  *****************************************************************************/
76
77
78 /*
79  * MemoryContextInit
80  *              Start up the memory-context subsystem.
81  *
82  * This must be called before creating contexts or allocating memory in
83  * contexts.  TopMemoryContext and ErrorContext are initialized here;
84  * other contexts must be created afterwards.
85  *
86  * In normal multi-backend operation, this is called once during
87  * postmaster startup, and not at all by individual backend startup
88  * (since the backends inherit an already-initialized context subsystem
89  * by virtue of being forked off the postmaster).  But in an EXEC_BACKEND
90  * build, each process must do this for itself.
91  *
92  * In a standalone backend this must be called during backend startup.
93  */
94 void
95 MemoryContextInit(void)
96 {
97         AssertState(TopMemoryContext == NULL);
98
99         /*
100          * Initialize TopMemoryContext as an AllocSetContext with slow growth rate
101          * --- we don't really expect much to be allocated in it.
102          *
103          * (There is special-case code in MemoryContextCreate() for this call.)
104          */
105         TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
106                                                                                          "TopMemoryContext",
107                                                                                          0,
108                                                                                          8 * 1024,
109                                                                                          8 * 1024);
110
111         /*
112          * Not having any other place to point CurrentMemoryContext, make it point
113          * to TopMemoryContext.  Caller should change this soon!
114          */
115         CurrentMemoryContext = TopMemoryContext;
116
117         /*
118          * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
119          * we don't really expect much to be allocated in it. More to the point,
120          * require it to contain at least 8K at all times. This is the only case
121          * where retained memory in a context is *essential* --- we want to be
122          * sure ErrorContext still has some memory even if we've run out
123          * elsewhere!
124          *
125          * This should be the last step in this function, as elog.c assumes memory
126          * management works once ErrorContext is non-null.
127          */
128         ErrorContext = AllocSetContextCreate(TopMemoryContext,
129                                                                                  "ErrorContext",
130                                                                                  8 * 1024,
131                                                                                  8 * 1024,
132                                                                                  8 * 1024);
133 }
134
135 /*
136  * MemoryContextReset
137  *              Release all space allocated within a context and its descendants,
138  *              but don't delete the contexts themselves.
139  *
140  * The type-specific reset routine handles the context itself, but we
141  * have to do the recursion for the children.
142  */
143 void
144 MemoryContextReset(MemoryContext context)
145 {
146         AssertArg(MemoryContextIsValid(context));
147
148         /* save a function call in common case where there are no children */
149         if (context->firstchild != NULL)
150                 MemoryContextResetChildren(context);
151
152         /* Nothing to do if no pallocs since startup or last reset */
153         if (!context->isReset)
154         {
155                 (*context->methods->reset) (context);
156                 context->isReset = true;
157                 VALGRIND_DESTROY_MEMPOOL(context);
158                 VALGRIND_CREATE_MEMPOOL(context, 0, false);
159         }
160 }
161
162 /*
163  * MemoryContextResetChildren
164  *              Release all space allocated within a context's descendants,
165  *              but don't delete the contexts themselves.  The named context
166  *              itself is not touched.
167  */
168 void
169 MemoryContextResetChildren(MemoryContext context)
170 {
171         MemoryContext child;
172
173         AssertArg(MemoryContextIsValid(context));
174
175         for (child = context->firstchild; child != NULL; child = child->nextchild)
176                 MemoryContextReset(child);
177 }
178
179 /*
180  * MemoryContextDelete
181  *              Delete a context and its descendants, and release all space
182  *              allocated therein.
183  *
184  * The type-specific delete routine removes all subsidiary storage
185  * for the context, but we have to delete the context node itself,
186  * as well as recurse to get the children.  We must also delink the
187  * node from its parent, if it has one.
188  */
189 void
190 MemoryContextDelete(MemoryContext context)
191 {
192         AssertArg(MemoryContextIsValid(context));
193         /* We had better not be deleting TopMemoryContext ... */
194         Assert(context != TopMemoryContext);
195         /* And not CurrentMemoryContext, either */
196         Assert(context != CurrentMemoryContext);
197
198         MemoryContextDeleteChildren(context);
199
200         /*
201          * We delink the context from its parent before deleting it, so that if
202          * there's an error we won't have deleted/busted contexts still attached
203          * to the context tree.  Better a leak than a crash.
204          */
205         MemoryContextSetParent(context, NULL);
206
207         (*context->methods->delete_context) (context);
208         VALGRIND_DESTROY_MEMPOOL(context);
209         pfree(context);
210 }
211
212 /*
213  * MemoryContextDeleteChildren
214  *              Delete all the descendants of the named context and release all
215  *              space allocated therein.  The named context itself is not touched.
216  */
217 void
218 MemoryContextDeleteChildren(MemoryContext context)
219 {
220         AssertArg(MemoryContextIsValid(context));
221
222         /*
223          * MemoryContextDelete will delink the child from me, so just iterate as
224          * long as there is a child.
225          */
226         while (context->firstchild != NULL)
227                 MemoryContextDelete(context->firstchild);
228 }
229
230 /*
231  * MemoryContextResetAndDeleteChildren
232  *              Release all space allocated within a context and delete all
233  *              its descendants.
234  *
235  * This is a common combination case where we want to preserve the
236  * specific context but get rid of absolutely everything under it.
237  */
238 void
239 MemoryContextResetAndDeleteChildren(MemoryContext context)
240 {
241         AssertArg(MemoryContextIsValid(context));
242
243         MemoryContextDeleteChildren(context);
244         MemoryContextReset(context);
245 }
246
247 /*
248  * MemoryContextSetParent
249  *              Change a context to belong to a new parent (or no parent).
250  *
251  * We provide this as an API function because it is sometimes useful to
252  * change a context's lifespan after creation.  For example, a context
253  * might be created underneath a transient context, filled with data,
254  * and then reparented underneath CacheMemoryContext to make it long-lived.
255  * In this way no special effort is needed to get rid of the context in case
256  * a failure occurs before its contents are completely set up.
257  *
258  * Callers often assume that this function cannot fail, so don't put any
259  * elog(ERROR) calls in it.
260  *
261  * A possible caller error is to reparent a context under itself, creating
262  * a loop in the context graph.  We assert here that context != new_parent,
263  * but checking for multi-level loops seems more trouble than it's worth.
264  */
265 void
266 MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
267 {
268         AssertArg(MemoryContextIsValid(context));
269         AssertArg(context != new_parent);
270
271         /* Delink from existing parent, if any */
272         if (context->parent)
273         {
274                 MemoryContext parent = context->parent;
275
276                 if (context == parent->firstchild)
277                         parent->firstchild = context->nextchild;
278                 else
279                 {
280                         MemoryContext child;
281
282                         for (child = parent->firstchild; child; child = child->nextchild)
283                         {
284                                 if (context == child->nextchild)
285                                 {
286                                         child->nextchild = context->nextchild;
287                                         break;
288                                 }
289                         }
290                 }
291         }
292
293         /* And relink */
294         if (new_parent)
295         {
296                 AssertArg(MemoryContextIsValid(new_parent));
297                 context->parent = new_parent;
298                 context->nextchild = new_parent->firstchild;
299                 new_parent->firstchild = context;
300         }
301         else
302         {
303                 context->parent = NULL;
304                 context->nextchild = NULL;
305         }
306 }
307
308 /*
309  * GetMemoryChunkSpace
310  *              Given a currently-allocated chunk, determine the total space
311  *              it occupies (including all memory-allocation overhead).
312  *
313  * This is useful for measuring the total space occupied by a set of
314  * allocated chunks.
315  */
316 Size
317 GetMemoryChunkSpace(void *pointer)
318 {
319         StandardChunkHeader *header;
320
321         /*
322          * Try to detect bogus pointers handed to us, poorly though we can.
323          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
324          * allocated chunk.
325          */
326         Assert(pointer != NULL);
327         Assert(pointer == (void *) MAXALIGN(pointer));
328
329         /*
330          * OK, it's probably safe to look at the chunk header.
331          */
332         header = (StandardChunkHeader *)
333                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
334
335         AssertArg(MemoryContextIsValid(header->context));
336
337         return (*header->context->methods->get_chunk_space) (header->context,
338                                                                                                                  pointer);
339 }
340
341 /*
342  * GetMemoryChunkContext
343  *              Given a currently-allocated chunk, determine the context
344  *              it belongs to.
345  */
346 MemoryContext
347 GetMemoryChunkContext(void *pointer)
348 {
349         StandardChunkHeader *header;
350
351         /*
352          * Try to detect bogus pointers handed to us, poorly though we can.
353          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
354          * allocated chunk.
355          */
356         Assert(pointer != NULL);
357         Assert(pointer == (void *) MAXALIGN(pointer));
358
359         /*
360          * OK, it's probably safe to look at the chunk header.
361          */
362         header = (StandardChunkHeader *)
363                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
364
365         AssertArg(MemoryContextIsValid(header->context));
366
367         return header->context;
368 }
369
370 /*
371  * MemoryContextGetParent
372  *              Get the parent context (if any) of the specified context
373  */
374 MemoryContext
375 MemoryContextGetParent(MemoryContext context)
376 {
377         AssertArg(MemoryContextIsValid(context));
378
379         return context->parent;
380 }
381
382 /*
383  * MemoryContextIsEmpty
384  *              Is a memory context empty of any allocated space?
385  */
386 bool
387 MemoryContextIsEmpty(MemoryContext context)
388 {
389         AssertArg(MemoryContextIsValid(context));
390
391         /*
392          * For now, we consider a memory context nonempty if it has any children;
393          * perhaps this should be changed later.
394          */
395         if (context->firstchild != NULL)
396                 return false;
397         /* Otherwise use the type-specific inquiry */
398         return (*context->methods->is_empty) (context);
399 }
400
401 /*
402  * MemoryContextStats
403  *              Print statistics about the named context and all its descendants.
404  *
405  * This is just a debugging utility, so it's not fancy.  The statistics
406  * are merely sent to stderr.
407  */
408 void
409 MemoryContextStats(MemoryContext context)
410 {
411         MemoryContextStatsInternal(context, 0);
412 }
413
414 static void
415 MemoryContextStatsInternal(MemoryContext context, int level)
416 {
417         MemoryContext child;
418
419         AssertArg(MemoryContextIsValid(context));
420
421         (*context->methods->stats) (context, level);
422         for (child = context->firstchild; child != NULL; child = child->nextchild)
423                 MemoryContextStatsInternal(child, level + 1);
424 }
425
426 /*
427  * MemoryContextCheck
428  *              Check all chunks in the named context.
429  *
430  * This is just a debugging utility, so it's not fancy.
431  */
432 #ifdef MEMORY_CONTEXT_CHECKING
433 void
434 MemoryContextCheck(MemoryContext context)
435 {
436         MemoryContext child;
437
438         AssertArg(MemoryContextIsValid(context));
439
440         (*context->methods->check) (context);
441         for (child = context->firstchild; child != NULL; child = child->nextchild)
442                 MemoryContextCheck(child);
443 }
444 #endif
445
446 /*
447  * MemoryContextContains
448  *              Detect whether an allocated chunk of memory belongs to a given
449  *              context or not.
450  *
451  * Caution: this test is reliable as long as 'pointer' does point to
452  * a chunk of memory allocated from *some* context.  If 'pointer' points
453  * at memory obtained in some other way, there is a small chance of a
454  * false-positive result, since the bits right before it might look like
455  * a valid chunk header by chance.
456  */
457 bool
458 MemoryContextContains(MemoryContext context, void *pointer)
459 {
460         StandardChunkHeader *header;
461
462         /*
463          * Try to detect bogus pointers handed to us, poorly though we can.
464          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
465          * allocated chunk.
466          */
467         if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
468                 return false;
469
470         /*
471          * OK, it's probably safe to look at the chunk header.
472          */
473         header = (StandardChunkHeader *)
474                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
475
476         return header->context == context;
477 }
478
479 /*--------------------
480  * MemoryContextCreate
481  *              Context-type-independent part of context creation.
482  *
483  * This is only intended to be called by context-type-specific
484  * context creation routines, not by the unwashed masses.
485  *
486  * The context creation procedure is a little bit tricky because
487  * we want to be sure that we don't leave the context tree invalid
488  * in case of failure (such as insufficient memory to allocate the
489  * context node itself).  The procedure goes like this:
490  *      1.  Context-type-specific routine first calls MemoryContextCreate(),
491  *              passing the appropriate tag/size/methods values (the methods
492  *              pointer will ordinarily point to statically allocated data).
493  *              The parent and name parameters usually come from the caller.
494  *      2.  MemoryContextCreate() attempts to allocate the context node,
495  *              plus space for the name.  If this fails we can ereport() with no
496  *              damage done.
497  *      3.  We fill in all of the type-independent MemoryContext fields.
498  *      4.  We call the type-specific init routine (using the methods pointer).
499  *              The init routine is required to make the node minimally valid
500  *              with zero chance of failure --- it can't allocate more memory,
501  *              for example.
502  *      5.  Now we have a minimally valid node that can behave correctly
503  *              when told to reset or delete itself.  We link the node to its
504  *              parent (if any), making the node part of the context tree.
505  *      6.  We return to the context-type-specific routine, which finishes
506  *              up type-specific initialization.  This routine can now do things
507  *              that might fail (like allocate more memory), so long as it's
508  *              sure the node is left in a state that delete will handle.
509  *
510  * This protocol doesn't prevent us from leaking memory if step 6 fails
511  * during creation of a top-level context, since there's no parent link
512  * in that case.  However, if you run out of memory while you're building
513  * a top-level context, you might as well go home anyway...
514  *
515  * Normally, the context node and the name are allocated from
516  * TopMemoryContext (NOT from the parent context, since the node must
517  * survive resets of its parent context!).  However, this routine is itself
518  * used to create TopMemoryContext!  If we see that TopMemoryContext is NULL,
519  * we assume we are creating TopMemoryContext and use malloc() to allocate
520  * the node.
521  *
522  * Note that the name field of a MemoryContext does not point to
523  * separately-allocated storage, so it should not be freed at context
524  * deletion.
525  *--------------------
526  */
527 MemoryContext
528 MemoryContextCreate(NodeTag tag, Size size,
529                                         MemoryContextMethods *methods,
530                                         MemoryContext parent,
531                                         const char *name)
532 {
533         MemoryContext node;
534         Size            needed = size + strlen(name) + 1;
535
536         Assert(CritSectionCount == 0);
537
538         /* Get space for node and name */
539         if (TopMemoryContext != NULL)
540         {
541                 /* Normal case: allocate the node in TopMemoryContext */
542                 node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,
543                                                                                                   needed);
544         }
545         else
546         {
547                 /* Special case for startup: use good ol' malloc */
548                 node = (MemoryContext) malloc(needed);
549                 Assert(node != NULL);
550         }
551
552         /* Initialize the node as best we can */
553         MemSet(node, 0, size);
554         node->type = tag;
555         node->methods = methods;
556         node->parent = NULL;            /* for the moment */
557         node->firstchild = NULL;
558         node->nextchild = NULL;
559         node->isReset = true;
560         node->name = ((char *) node) + size;
561         strcpy(node->name, name);
562
563         /* Type-specific routine finishes any other essential initialization */
564         (*node->methods->init) (node);
565
566         /* OK to link node to parent (if any) */
567         /* Could use MemoryContextSetParent here, but doesn't seem worthwhile */
568         if (parent)
569         {
570                 node->parent = parent;
571                 node->nextchild = parent->firstchild;
572                 parent->firstchild = node;
573         }
574
575         VALGRIND_CREATE_MEMPOOL(node, 0, false);
576
577         /* Return to type-specific creation routine to finish up */
578         return node;
579 }
580
581 /*
582  * MemoryContextAlloc
583  *              Allocate space within the specified context.
584  *
585  * This could be turned into a macro, but we'd have to import
586  * nodes/memnodes.h into postgres.h which seems a bad idea.
587  */
588 void *
589 MemoryContextAlloc(MemoryContext context, Size size)
590 {
591         void       *ret;
592
593         AssertArg(MemoryContextIsValid(context));
594         AssertNotInCriticalSection(context);
595
596         if (!AllocSizeIsValid(size))
597                 elog(ERROR, "invalid memory alloc request size %zu", size);
598
599         context->isReset = false;
600
601         ret = (*context->methods->alloc) (context, size);
602         VALGRIND_MEMPOOL_ALLOC(context, ret, size);
603
604         return ret;
605 }
606
607 /*
608  * MemoryContextAllocZero
609  *              Like MemoryContextAlloc, but clears allocated memory
610  *
611  *      We could just call MemoryContextAlloc then clear the memory, but this
612  *      is a very common combination, so we provide the combined operation.
613  */
614 void *
615 MemoryContextAllocZero(MemoryContext context, Size size)
616 {
617         void       *ret;
618
619         AssertArg(MemoryContextIsValid(context));
620         AssertNotInCriticalSection(context);
621
622         if (!AllocSizeIsValid(size))
623                 elog(ERROR, "invalid memory alloc request size %zu", size);
624
625         context->isReset = false;
626
627         ret = (*context->methods->alloc) (context, size);
628         VALGRIND_MEMPOOL_ALLOC(context, ret, size);
629
630         MemSetAligned(ret, 0, size);
631
632         return ret;
633 }
634
635 /*
636  * MemoryContextAllocZeroAligned
637  *              MemoryContextAllocZero where length is suitable for MemSetLoop
638  *
639  *      This might seem overly specialized, but it's not because newNode()
640  *      is so often called with compile-time-constant sizes.
641  */
642 void *
643 MemoryContextAllocZeroAligned(MemoryContext context, Size size)
644 {
645         void       *ret;
646
647         AssertArg(MemoryContextIsValid(context));
648         AssertNotInCriticalSection(context);
649
650         if (!AllocSizeIsValid(size))
651                 elog(ERROR, "invalid memory alloc request size %zu", size);
652
653         context->isReset = false;
654
655         ret = (*context->methods->alloc) (context, size);
656         VALGRIND_MEMPOOL_ALLOC(context, ret, size);
657
658         MemSetLoop(ret, 0, size);
659
660         return ret;
661 }
662
663 void *
664 palloc(Size size)
665 {
666         /* duplicates MemoryContextAlloc to avoid increased overhead */
667         void       *ret;
668
669         AssertArg(MemoryContextIsValid(CurrentMemoryContext));
670         AssertNotInCriticalSection(CurrentMemoryContext);
671
672         if (!AllocSizeIsValid(size))
673                 elog(ERROR, "invalid memory alloc request size %zu", size);
674
675         CurrentMemoryContext->isReset = false;
676
677         ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size);
678         VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size);
679
680         return ret;
681 }
682
683 void *
684 palloc0(Size size)
685 {
686         /* duplicates MemoryContextAllocZero to avoid increased overhead */
687         void       *ret;
688
689         AssertArg(MemoryContextIsValid(CurrentMemoryContext));
690         AssertNotInCriticalSection(CurrentMemoryContext);
691
692         if (!AllocSizeIsValid(size))
693                 elog(ERROR, "invalid memory alloc request size %zu", size);
694
695         CurrentMemoryContext->isReset = false;
696
697         ret = (*CurrentMemoryContext->methods->alloc) (CurrentMemoryContext, size);
698         VALGRIND_MEMPOOL_ALLOC(CurrentMemoryContext, ret, size);
699
700         MemSetAligned(ret, 0, size);
701
702         return ret;
703 }
704
705 /*
706  * pfree
707  *              Release an allocated chunk.
708  */
709 void
710 pfree(void *pointer)
711 {
712         MemoryContext context;
713
714         /*
715          * Try to detect bogus pointers handed to us, poorly though we can.
716          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
717          * allocated chunk.
718          */
719         Assert(pointer != NULL);
720         Assert(pointer == (void *) MAXALIGN(pointer));
721
722         /*
723          * OK, it's probably safe to look at the chunk header.
724          */
725         context = ((StandardChunkHeader *)
726                            ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
727
728         AssertArg(MemoryContextIsValid(context));
729
730         (*context->methods->free_p) (context, pointer);
731         VALGRIND_MEMPOOL_FREE(context, pointer);
732 }
733
734 /*
735  * repalloc
736  *              Adjust the size of a previously allocated chunk.
737  */
738 void *
739 repalloc(void *pointer, Size size)
740 {
741         MemoryContext context;
742         void       *ret;
743
744         if (!AllocSizeIsValid(size))
745                 elog(ERROR, "invalid memory alloc request size %zu", size);
746
747         /*
748          * Try to detect bogus pointers handed to us, poorly though we can.
749          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
750          * allocated chunk.
751          */
752         Assert(pointer != NULL);
753         Assert(pointer == (void *) MAXALIGN(pointer));
754
755         /*
756          * OK, it's probably safe to look at the chunk header.
757          */
758         context = ((StandardChunkHeader *)
759                            ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
760
761         AssertArg(MemoryContextIsValid(context));
762         AssertNotInCriticalSection(context);
763
764         /* isReset must be false already */
765         Assert(!context->isReset);
766
767         ret = (*context->methods->realloc) (context, pointer, size);
768         VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
769
770         return ret;
771 }
772
773 /*
774  * MemoryContextAllocHuge
775  *              Allocate (possibly-expansive) space within the specified context.
776  *
777  * See considerations in comment at MaxAllocHugeSize.
778  */
779 void *
780 MemoryContextAllocHuge(MemoryContext context, Size size)
781 {
782         void       *ret;
783
784         AssertArg(MemoryContextIsValid(context));
785         AssertNotInCriticalSection(context);
786
787         if (!AllocHugeSizeIsValid(size))
788                 elog(ERROR, "invalid memory alloc request size %zu", size);
789
790         context->isReset = false;
791
792         ret = (*context->methods->alloc) (context, size);
793         VALGRIND_MEMPOOL_ALLOC(context, ret, size);
794
795         return ret;
796 }
797
798 /*
799  * repalloc_huge
800  *              Adjust the size of a previously allocated chunk, permitting a large
801  *              value.  The previous allocation need not have been "huge".
802  */
803 void *
804 repalloc_huge(void *pointer, Size size)
805 {
806         MemoryContext context;
807         void       *ret;
808
809         if (!AllocHugeSizeIsValid(size))
810                 elog(ERROR, "invalid memory alloc request size %zu", size);
811
812         /*
813          * Try to detect bogus pointers handed to us, poorly though we can.
814          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
815          * allocated chunk.
816          */
817         Assert(pointer != NULL);
818         Assert(pointer == (void *) MAXALIGN(pointer));
819
820         /*
821          * OK, it's probably safe to look at the chunk header.
822          */
823         context = ((StandardChunkHeader *)
824                            ((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
825
826         AssertArg(MemoryContextIsValid(context));
827         AssertNotInCriticalSection(context);
828
829         /* isReset must be false already */
830         Assert(!context->isReset);
831
832         ret = (*context->methods->realloc) (context, pointer, size);
833         VALGRIND_MEMPOOL_CHANGE(context, pointer, ret, size);
834
835         return ret;
836 }
837
838 /*
839  * MemoryContextStrdup
840  *              Like strdup(), but allocate from the specified context
841  */
842 char *
843 MemoryContextStrdup(MemoryContext context, const char *string)
844 {
845         char       *nstr;
846         Size            len = strlen(string) + 1;
847
848         nstr = (char *) MemoryContextAlloc(context, len);
849
850         memcpy(nstr, string, len);
851
852         return nstr;
853 }
854
855 char *
856 pstrdup(const char *in)
857 {
858         return MemoryContextStrdup(CurrentMemoryContext, in);
859 }
860
861 /*
862  * pnstrdup
863  *              Like pstrdup(), but append null byte to a
864  *              not-necessarily-null-terminated input string.
865  */
866 char *
867 pnstrdup(const char *in, Size len)
868 {
869         char       *out = palloc(len + 1);
870
871         memcpy(out, in, len);
872         out[len] = '\0';
873         return out;
874 }