OSDN Git Service

First phase of plan-invalidation project: create a plan cache management
[pg-rex/syncrep.git] / 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-2007, PostgreSQL Global Development Group
13  * Portions Copyright (c) 1994, Regents of the University of California
14  *
15  *
16  * IDENTIFICATION
17  *        $PostgreSQL: pgsql/src/backend/utils/mmgr/mcxt.c,v 1.60 2007/03/13 00:33:42 tgl Exp $
18  *
19  *-------------------------------------------------------------------------
20  */
21
22 #include "postgres.h"
23
24 #include "utils/memutils.h"
25
26
27 /*****************************************************************************
28  *        GLOBAL MEMORY                                                                                                                  *
29  *****************************************************************************/
30
31 /*
32  * CurrentMemoryContext
33  *              Default memory context for allocations.
34  */
35 MemoryContext CurrentMemoryContext = NULL;
36
37 /*
38  * Standard top-level contexts. For a description of the purpose of each
39  * of these contexts, refer to src/backend/utils/mmgr/README
40  */
41 MemoryContext TopMemoryContext = NULL;
42 MemoryContext ErrorContext = NULL;
43 MemoryContext PostmasterContext = NULL;
44 MemoryContext CacheMemoryContext = NULL;
45 MemoryContext MessageContext = NULL;
46 MemoryContext TopTransactionContext = NULL;
47 MemoryContext CurTransactionContext = NULL;
48
49 /* This is a transient link to the active portal's memory context: */
50 MemoryContext PortalContext = NULL;
51
52
53 /*****************************************************************************
54  *        EXPORTED ROUTINES                                                                                                              *
55  *****************************************************************************/
56
57
58 /*
59  * MemoryContextInit
60  *              Start up the memory-context subsystem.
61  *
62  * This must be called before creating contexts or allocating memory in
63  * contexts.  TopMemoryContext and ErrorContext are initialized here;
64  * other contexts must be created afterwards.
65  *
66  * In normal multi-backend operation, this is called once during
67  * postmaster startup, and not at all by individual backend startup
68  * (since the backends inherit an already-initialized context subsystem
69  * by virtue of being forked off the postmaster).
70  *
71  * In a standalone backend this must be called during backend startup.
72  */
73 void
74 MemoryContextInit(void)
75 {
76         AssertState(TopMemoryContext == NULL);
77
78         /*
79          * Initialize TopMemoryContext as an AllocSetContext with slow growth rate
80          * --- we don't really expect much to be allocated in it.
81          *
82          * (There is special-case code in MemoryContextCreate() for this call.)
83          */
84         TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
85                                                                                          "TopMemoryContext",
86                                                                                          0,
87                                                                                          8 * 1024,
88                                                                                          8 * 1024);
89
90         /*
91          * Not having any other place to point CurrentMemoryContext, make it point
92          * to TopMemoryContext.  Caller should change this soon!
93          */
94         CurrentMemoryContext = TopMemoryContext;
95
96         /*
97          * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
98          * we don't really expect much to be allocated in it. More to the point,
99          * require it to contain at least 8K at all times. This is the only case
100          * where retained memory in a context is *essential* --- we want to be
101          * sure ErrorContext still has some memory even if we've run out
102          * elsewhere!
103          */
104         ErrorContext = AllocSetContextCreate(TopMemoryContext,
105                                                                                  "ErrorContext",
106                                                                                  8 * 1024,
107                                                                                  8 * 1024,
108                                                                                  8 * 1024);
109 }
110
111 /*
112  * MemoryContextReset
113  *              Release all space allocated within a context and its descendants,
114  *              but don't delete the contexts themselves.
115  *
116  * The type-specific reset routine handles the context itself, but we
117  * have to do the recursion for the children.
118  */
119 void
120 MemoryContextReset(MemoryContext context)
121 {
122         AssertArg(MemoryContextIsValid(context));
123
124         /* save a function call in common case where there are no children */
125         if (context->firstchild != NULL)
126                 MemoryContextResetChildren(context);
127
128         (*context->methods->reset) (context);
129 }
130
131 /*
132  * MemoryContextResetChildren
133  *              Release all space allocated within a context's descendants,
134  *              but don't delete the contexts themselves.  The named context
135  *              itself is not touched.
136  */
137 void
138 MemoryContextResetChildren(MemoryContext context)
139 {
140         MemoryContext child;
141
142         AssertArg(MemoryContextIsValid(context));
143
144         for (child = context->firstchild; child != NULL; child = child->nextchild)
145                 MemoryContextReset(child);
146 }
147
148 /*
149  * MemoryContextDelete
150  *              Delete a context and its descendants, and release all space
151  *              allocated therein.
152  *
153  * The type-specific delete routine removes all subsidiary storage
154  * for the context, but we have to delete the context node itself,
155  * as well as recurse to get the children.      We must also delink the
156  * node from its parent, if it has one.
157  */
158 void
159 MemoryContextDelete(MemoryContext context)
160 {
161         AssertArg(MemoryContextIsValid(context));
162         /* We had better not be deleting TopMemoryContext ... */
163         Assert(context != TopMemoryContext);
164         /* And not CurrentMemoryContext, either */
165         Assert(context != CurrentMemoryContext);
166
167         MemoryContextDeleteChildren(context);
168
169         /*
170          * We delink the context from its parent before deleting it, so that if
171          * there's an error we won't have deleted/busted contexts still attached
172          * to the context tree.  Better a leak than a crash.
173          */
174         if (context->parent)
175         {
176                 MemoryContext parent = context->parent;
177
178                 if (context == parent->firstchild)
179                         parent->firstchild = context->nextchild;
180                 else
181                 {
182                         MemoryContext child;
183
184                         for (child = parent->firstchild; child; child = child->nextchild)
185                         {
186                                 if (context == child->nextchild)
187                                 {
188                                         child->nextchild = context->nextchild;
189                                         break;
190                                 }
191                         }
192                 }
193         }
194         (*context->methods->delete) (context);
195         pfree(context);
196 }
197
198 /*
199  * MemoryContextDeleteChildren
200  *              Delete all the descendants of the named context and release all
201  *              space allocated therein.  The named context itself is not touched.
202  */
203 void
204 MemoryContextDeleteChildren(MemoryContext context)
205 {
206         AssertArg(MemoryContextIsValid(context));
207
208         /*
209          * MemoryContextDelete will delink the child from me, so just iterate as
210          * long as there is a child.
211          */
212         while (context->firstchild != NULL)
213                 MemoryContextDelete(context->firstchild);
214 }
215
216 /*
217  * MemoryContextResetAndDeleteChildren
218  *              Release all space allocated within a context and delete all
219  *              its descendants.
220  *
221  * This is a common combination case where we want to preserve the
222  * specific context but get rid of absolutely everything under it.
223  */
224 void
225 MemoryContextResetAndDeleteChildren(MemoryContext context)
226 {
227         AssertArg(MemoryContextIsValid(context));
228
229         MemoryContextDeleteChildren(context);
230         (*context->methods->reset) (context);
231 }
232
233 /*
234  * GetMemoryChunkSpace
235  *              Given a currently-allocated chunk, determine the total space
236  *              it occupies (including all memory-allocation overhead).
237  *
238  * This is useful for measuring the total space occupied by a set of
239  * allocated chunks.
240  */
241 Size
242 GetMemoryChunkSpace(void *pointer)
243 {
244         StandardChunkHeader *header;
245
246         /*
247          * Try to detect bogus pointers handed to us, poorly though we can.
248          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
249          * allocated chunk.
250          */
251         Assert(pointer != NULL);
252         Assert(pointer == (void *) MAXALIGN(pointer));
253
254         /*
255          * OK, it's probably safe to look at the chunk header.
256          */
257         header = (StandardChunkHeader *)
258                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
259
260         AssertArg(MemoryContextIsValid(header->context));
261
262         return (*header->context->methods->get_chunk_space) (header->context,
263                                                                                                                  pointer);
264 }
265
266 /*
267  * GetMemoryChunkContext
268  *              Given a currently-allocated chunk, determine the context
269  *              it belongs to.
270  */
271 MemoryContext
272 GetMemoryChunkContext(void *pointer)
273 {
274         StandardChunkHeader *header;
275
276         /*
277          * Try to detect bogus pointers handed to us, poorly though we can.
278          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
279          * allocated chunk.
280          */
281         Assert(pointer != NULL);
282         Assert(pointer == (void *) MAXALIGN(pointer));
283
284         /*
285          * OK, it's probably safe to look at the chunk header.
286          */
287         header = (StandardChunkHeader *)
288                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
289
290         AssertArg(MemoryContextIsValid(header->context));
291
292         return header->context;
293 }
294
295 /*
296  * MemoryContextIsEmpty
297  *              Is a memory context empty of any allocated space?
298  */
299 bool
300 MemoryContextIsEmpty(MemoryContext context)
301 {
302         AssertArg(MemoryContextIsValid(context));
303
304         /*
305          * For now, we consider a memory context nonempty if it has any children;
306          * perhaps this should be changed later.
307          */
308         if (context->firstchild != NULL)
309                 return false;
310         /* Otherwise use the type-specific inquiry */
311         return (*context->methods->is_empty) (context);
312 }
313
314 /*
315  * MemoryContextStats
316  *              Print statistics about the named context and all its descendants.
317  *
318  * This is just a debugging utility, so it's not fancy.  The statistics
319  * are merely sent to stderr.
320  */
321 void
322 MemoryContextStats(MemoryContext context)
323 {
324         MemoryContext child;
325
326         AssertArg(MemoryContextIsValid(context));
327
328         (*context->methods->stats) (context);
329         for (child = context->firstchild; child != NULL; child = child->nextchild)
330                 MemoryContextStats(child);
331 }
332
333
334 /*
335  * MemoryContextCheck
336  *              Check all chunks in the named context.
337  *
338  * This is just a debugging utility, so it's not fancy.
339  */
340 #ifdef MEMORY_CONTEXT_CHECKING
341 void
342 MemoryContextCheck(MemoryContext context)
343 {
344         MemoryContext child;
345
346         AssertArg(MemoryContextIsValid(context));
347
348         (*context->methods->check) (context);
349         for (child = context->firstchild; child != NULL; child = child->nextchild)
350                 MemoryContextCheck(child);
351 }
352 #endif
353
354 /*
355  * MemoryContextContains
356  *              Detect whether an allocated chunk of memory belongs to a given
357  *              context or not.
358  *
359  * Caution: this test is reliable as long as 'pointer' does point to
360  * a chunk of memory allocated from *some* context.  If 'pointer' points
361  * at memory obtained in some other way, there is a small chance of a
362  * false-positive result, since the bits right before it might look like
363  * a valid chunk header by chance.
364  */
365 bool
366 MemoryContextContains(MemoryContext context, void *pointer)
367 {
368         StandardChunkHeader *header;
369
370         /*
371          * Try to detect bogus pointers handed to us, poorly though we can.
372          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
373          * allocated chunk.
374          */
375         if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
376                 return false;
377
378         /*
379          * OK, it's probably safe to look at the chunk header.
380          */
381         header = (StandardChunkHeader *)
382                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
383
384         /*
385          * If the context link doesn't match then we certainly have a non-member
386          * chunk.  Also check for a reasonable-looking size as extra guard against
387          * being fooled by bogus pointers.
388          */
389         if (header->context == context && AllocSizeIsValid(header->size))
390                 return true;
391         return false;
392 }
393
394 /*--------------------
395  * MemoryContextCreate
396  *              Context-type-independent part of context creation.
397  *
398  * This is only intended to be called by context-type-specific
399  * context creation routines, not by the unwashed masses.
400  *
401  * The context creation procedure is a little bit tricky because
402  * we want to be sure that we don't leave the context tree invalid
403  * in case of failure (such as insufficient memory to allocate the
404  * context node itself).  The procedure goes like this:
405  *      1.      Context-type-specific routine first calls MemoryContextCreate(),
406  *              passing the appropriate tag/size/methods values (the methods
407  *              pointer will ordinarily point to statically allocated data).
408  *              The parent and name parameters usually come from the caller.
409  *      2.      MemoryContextCreate() attempts to allocate the context node,
410  *              plus space for the name.  If this fails we can ereport() with no
411  *              damage done.
412  *      3.      We fill in all of the type-independent MemoryContext fields.
413  *      4.      We call the type-specific init routine (using the methods pointer).
414  *              The init routine is required to make the node minimally valid
415  *              with zero chance of failure --- it can't allocate more memory,
416  *              for example.
417  *      5.      Now we have a minimally valid node that can behave correctly
418  *              when told to reset or delete itself.  We link the node to its
419  *              parent (if any), making the node part of the context tree.
420  *      6.      We return to the context-type-specific routine, which finishes
421  *              up type-specific initialization.  This routine can now do things
422  *              that might fail (like allocate more memory), so long as it's
423  *              sure the node is left in a state that delete will handle.
424  *
425  * This protocol doesn't prevent us from leaking memory if step 6 fails
426  * during creation of a top-level context, since there's no parent link
427  * in that case.  However, if you run out of memory while you're building
428  * a top-level context, you might as well go home anyway...
429  *
430  * Normally, the context node and the name are allocated from
431  * TopMemoryContext (NOT from the parent context, since the node must
432  * survive resets of its parent context!).      However, this routine is itself
433  * used to create TopMemoryContext!  If we see that TopMemoryContext is NULL,
434  * we assume we are creating TopMemoryContext and use malloc() to allocate
435  * the node.
436  *
437  * Note that the name field of a MemoryContext does not point to
438  * separately-allocated storage, so it should not be freed at context
439  * deletion.
440  *--------------------
441  */
442 MemoryContext
443 MemoryContextCreate(NodeTag tag, Size size,
444                                         MemoryContextMethods *methods,
445                                         MemoryContext parent,
446                                         const char *name)
447 {
448         MemoryContext node;
449         Size            needed = size + strlen(name) + 1;
450
451         /* Get space for node and name */
452         if (TopMemoryContext != NULL)
453         {
454                 /* Normal case: allocate the node in TopMemoryContext */
455                 node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,
456                                                                                                   needed);
457         }
458         else
459         {
460                 /* Special case for startup: use good ol' malloc */
461                 node = (MemoryContext) malloc(needed);
462                 Assert(node != NULL);
463         }
464
465         /* Initialize the node as best we can */
466         MemSet(node, 0, size);
467         node->type = tag;
468         node->methods = methods;
469         node->parent = NULL;            /* for the moment */
470         node->firstchild = NULL;
471         node->nextchild = NULL;
472         node->name = ((char *) node) + size;
473         strcpy(node->name, name);
474
475         /* Type-specific routine finishes any other essential initialization */
476         (*node->methods->init) (node);
477
478         /* OK to link node to parent (if any) */
479         if (parent)
480         {
481                 node->parent = parent;
482                 node->nextchild = parent->firstchild;
483                 parent->firstchild = node;
484         }
485
486         /* Return to type-specific creation routine to finish up */
487         return node;
488 }
489
490 /*
491  * MemoryContextAlloc
492  *              Allocate space within the specified context.
493  *
494  * This could be turned into a macro, but we'd have to import
495  * nodes/memnodes.h into postgres.h which seems a bad idea.
496  */
497 void *
498 MemoryContextAlloc(MemoryContext context, Size size)
499 {
500         AssertArg(MemoryContextIsValid(context));
501
502         if (!AllocSizeIsValid(size))
503                 elog(ERROR, "invalid memory alloc request size %lu",
504                          (unsigned long) size);
505
506         return (*context->methods->alloc) (context, size);
507 }
508
509 /*
510  * MemoryContextAllocZero
511  *              Like MemoryContextAlloc, but clears allocated memory
512  *
513  *      We could just call MemoryContextAlloc then clear the memory, but this
514  *      is a very common combination, so we provide the combined operation.
515  */
516 void *
517 MemoryContextAllocZero(MemoryContext context, Size size)
518 {
519         void       *ret;
520
521         AssertArg(MemoryContextIsValid(context));
522
523         if (!AllocSizeIsValid(size))
524                 elog(ERROR, "invalid memory alloc request size %lu",
525                          (unsigned long) size);
526
527         ret = (*context->methods->alloc) (context, size);
528
529         MemSetAligned(ret, 0, size);
530
531         return ret;
532 }
533
534 /*
535  * MemoryContextAllocZeroAligned
536  *              MemoryContextAllocZero where length is suitable for MemSetLoop
537  *
538  *      This might seem overly specialized, but it's not because newNode()
539  *      is so often called with compile-time-constant sizes.
540  */
541 void *
542 MemoryContextAllocZeroAligned(MemoryContext context, Size size)
543 {
544         void       *ret;
545
546         AssertArg(MemoryContextIsValid(context));
547
548         if (!AllocSizeIsValid(size))
549                 elog(ERROR, "invalid memory alloc request size %lu",
550                          (unsigned long) size);
551
552         ret = (*context->methods->alloc) (context, size);
553
554         MemSetLoop(ret, 0, size);
555
556         return ret;
557 }
558
559 /*
560  * pfree
561  *              Release an allocated chunk.
562  */
563 void
564 pfree(void *pointer)
565 {
566         StandardChunkHeader *header;
567
568         /*
569          * Try to detect bogus pointers handed to us, poorly though we can.
570          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
571          * allocated chunk.
572          */
573         Assert(pointer != NULL);
574         Assert(pointer == (void *) MAXALIGN(pointer));
575
576         /*
577          * OK, it's probably safe to look at the chunk header.
578          */
579         header = (StandardChunkHeader *)
580                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
581
582         AssertArg(MemoryContextIsValid(header->context));
583
584         (*header->context->methods->free_p) (header->context, pointer);
585 }
586
587 /*
588  * repalloc
589  *              Adjust the size of a previously allocated chunk.
590  */
591 void *
592 repalloc(void *pointer, Size size)
593 {
594         StandardChunkHeader *header;
595
596         /*
597          * Try to detect bogus pointers handed to us, poorly though we can.
598          * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
599          * allocated chunk.
600          */
601         Assert(pointer != NULL);
602         Assert(pointer == (void *) MAXALIGN(pointer));
603
604         /*
605          * OK, it's probably safe to look at the chunk header.
606          */
607         header = (StandardChunkHeader *)
608                 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
609
610         AssertArg(MemoryContextIsValid(header->context));
611
612         if (!AllocSizeIsValid(size))
613                 elog(ERROR, "invalid memory alloc request size %lu",
614                          (unsigned long) size);
615
616         return (*header->context->methods->realloc) (header->context,
617                                                                                                  pointer, size);
618 }
619
620 /*
621  * MemoryContextSwitchTo
622  *              Returns the current context; installs the given context.
623  *
624  * This is inlined when using GCC.
625  *
626  * TODO: investigate supporting inlining for some non-GCC compilers.
627  */
628 #ifndef __GNUC__
629
630 MemoryContext
631 MemoryContextSwitchTo(MemoryContext context)
632 {
633         MemoryContext old;
634
635         AssertArg(MemoryContextIsValid(context));
636
637         old = CurrentMemoryContext;
638         CurrentMemoryContext = context;
639         return old;
640 }
641 #endif   /* ! __GNUC__ */
642
643 /*
644  * MemoryContextStrdup
645  *              Like strdup(), but allocate from the specified context
646  */
647 char *
648 MemoryContextStrdup(MemoryContext context, const char *string)
649 {
650         char       *nstr;
651         Size            len = strlen(string) + 1;
652
653         nstr = (char *) MemoryContextAlloc(context, len);
654
655         memcpy(nstr, string, len);
656
657         return nstr;
658 }
659
660
661 #if defined(WIN32) || defined(__CYGWIN__)
662 /*
663  *      Memory support routines for libpgport on Win32
664  *
665  *      Win32 can't load a library that DLLIMPORTs a variable
666  *      if the link object files also DLLIMPORT the same variable.
667  *      For this reason, libpgport can't reference CurrentMemoryContext
668  *      in the palloc macro calls.
669  *
670  *      To fix this, we create several functions here that allow us to
671  *      manage memory without doing the inline in libpgport.
672  */
673 void *
674 pgport_palloc(Size sz)
675 {
676         return palloc(sz);
677 }
678
679
680 char *
681 pgport_pstrdup(const char *str)
682 {
683         return pstrdup(str);
684 }
685
686
687 /* Doesn't reference a DLLIMPORT variable, but here for completeness. */
688 void
689 pgport_pfree(void *pointer)
690 {
691         pfree(pointer);
692 }
693
694 #endif