Revert dubious message wording change.
[PostgreSQL.git] / src / backend / utils / mmgr / mcxt.c
blobae4ed739ddb7c9bd4fc75cdcc5e188a29945112e
1 /*-------------------------------------------------------------------------
3 * mcxt.c
4 * POSTGRES memory context management code.
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.
12 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
16 * IDENTIFICATION
17 * $PostgreSQL$
19 *-------------------------------------------------------------------------
22 #include "postgres.h"
24 #include "utils/memutils.h"
27 /*****************************************************************************
28 * GLOBAL MEMORY *
29 *****************************************************************************/
32 * CurrentMemoryContext
33 * Default memory context for allocations.
35 MemoryContext CurrentMemoryContext = NULL;
38 * Standard top-level contexts. For a description of the purpose of each
39 * of these contexts, refer to src/backend/utils/mmgr/README
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;
49 /* This is a transient link to the active portal's memory context: */
50 MemoryContext PortalContext = NULL;
52 static void MemoryContextStatsInternal(MemoryContext context, int level);
55 /*****************************************************************************
56 * EXPORTED ROUTINES *
57 *****************************************************************************/
61 * MemoryContextInit
62 * Start up the memory-context subsystem.
64 * This must be called before creating contexts or allocating memory in
65 * contexts. TopMemoryContext and ErrorContext are initialized here;
66 * other contexts must be created afterwards.
68 * In normal multi-backend operation, this is called once during
69 * postmaster startup, and not at all by individual backend startup
70 * (since the backends inherit an already-initialized context subsystem
71 * by virtue of being forked off the postmaster).
73 * In a standalone backend this must be called during backend startup.
75 void
76 MemoryContextInit(void)
78 AssertState(TopMemoryContext == NULL);
81 * Initialize TopMemoryContext as an AllocSetContext with slow growth rate
82 * --- we don't really expect much to be allocated in it.
84 * (There is special-case code in MemoryContextCreate() for this call.)
86 TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
87 "TopMemoryContext",
89 8 * 1024,
90 8 * 1024);
93 * Not having any other place to point CurrentMemoryContext, make it point
94 * to TopMemoryContext. Caller should change this soon!
96 CurrentMemoryContext = TopMemoryContext;
99 * Initialize ErrorContext as an AllocSetContext with slow growth rate ---
100 * we don't really expect much to be allocated in it. More to the point,
101 * require it to contain at least 8K at all times. This is the only case
102 * where retained memory in a context is *essential* --- we want to be
103 * sure ErrorContext still has some memory even if we've run out
104 * elsewhere!
106 ErrorContext = AllocSetContextCreate(TopMemoryContext,
107 "ErrorContext",
108 8 * 1024,
109 8 * 1024,
110 8 * 1024);
114 * MemoryContextReset
115 * Release all space allocated within a context and its descendants,
116 * but don't delete the contexts themselves.
118 * The type-specific reset routine handles the context itself, but we
119 * have to do the recursion for the children.
121 void
122 MemoryContextReset(MemoryContext context)
124 AssertArg(MemoryContextIsValid(context));
126 /* save a function call in common case where there are no children */
127 if (context->firstchild != NULL)
128 MemoryContextResetChildren(context);
130 (*context->methods->reset) (context);
134 * MemoryContextResetChildren
135 * Release all space allocated within a context's descendants,
136 * but don't delete the contexts themselves. The named context
137 * itself is not touched.
139 void
140 MemoryContextResetChildren(MemoryContext context)
142 MemoryContext child;
144 AssertArg(MemoryContextIsValid(context));
146 for (child = context->firstchild; child != NULL; child = child->nextchild)
147 MemoryContextReset(child);
151 * MemoryContextDelete
152 * Delete a context and its descendants, and release all space
153 * allocated therein.
155 * The type-specific delete routine removes all subsidiary storage
156 * for the context, but we have to delete the context node itself,
157 * as well as recurse to get the children. We must also delink the
158 * node from its parent, if it has one.
160 void
161 MemoryContextDelete(MemoryContext context)
163 AssertArg(MemoryContextIsValid(context));
164 /* We had better not be deleting TopMemoryContext ... */
165 Assert(context != TopMemoryContext);
166 /* And not CurrentMemoryContext, either */
167 Assert(context != CurrentMemoryContext);
169 MemoryContextDeleteChildren(context);
172 * We delink the context from its parent before deleting it, so that if
173 * there's an error we won't have deleted/busted contexts still attached
174 * to the context tree. Better a leak than a crash.
176 if (context->parent)
178 MemoryContext parent = context->parent;
180 if (context == parent->firstchild)
181 parent->firstchild = context->nextchild;
182 else
184 MemoryContext child;
186 for (child = parent->firstchild; child; child = child->nextchild)
188 if (context == child->nextchild)
190 child->nextchild = context->nextchild;
191 break;
196 (*context->methods->delete) (context);
197 pfree(context);
201 * MemoryContextDeleteChildren
202 * Delete all the descendants of the named context and release all
203 * space allocated therein. The named context itself is not touched.
205 void
206 MemoryContextDeleteChildren(MemoryContext context)
208 AssertArg(MemoryContextIsValid(context));
211 * MemoryContextDelete will delink the child from me, so just iterate as
212 * long as there is a child.
214 while (context->firstchild != NULL)
215 MemoryContextDelete(context->firstchild);
219 * MemoryContextResetAndDeleteChildren
220 * Release all space allocated within a context and delete all
221 * its descendants.
223 * This is a common combination case where we want to preserve the
224 * specific context but get rid of absolutely everything under it.
226 void
227 MemoryContextResetAndDeleteChildren(MemoryContext context)
229 AssertArg(MemoryContextIsValid(context));
231 MemoryContextDeleteChildren(context);
232 (*context->methods->reset) (context);
236 * GetMemoryChunkSpace
237 * Given a currently-allocated chunk, determine the total space
238 * it occupies (including all memory-allocation overhead).
240 * This is useful for measuring the total space occupied by a set of
241 * allocated chunks.
243 Size
244 GetMemoryChunkSpace(void *pointer)
246 StandardChunkHeader *header;
249 * Try to detect bogus pointers handed to us, poorly though we can.
250 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
251 * allocated chunk.
253 Assert(pointer != NULL);
254 Assert(pointer == (void *) MAXALIGN(pointer));
257 * OK, it's probably safe to look at the chunk header.
259 header = (StandardChunkHeader *)
260 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
262 AssertArg(MemoryContextIsValid(header->context));
264 return (*header->context->methods->get_chunk_space) (header->context,
265 pointer);
269 * GetMemoryChunkContext
270 * Given a currently-allocated chunk, determine the context
271 * it belongs to.
273 MemoryContext
274 GetMemoryChunkContext(void *pointer)
276 StandardChunkHeader *header;
279 * Try to detect bogus pointers handed to us, poorly though we can.
280 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
281 * allocated chunk.
283 Assert(pointer != NULL);
284 Assert(pointer == (void *) MAXALIGN(pointer));
287 * OK, it's probably safe to look at the chunk header.
289 header = (StandardChunkHeader *)
290 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
292 AssertArg(MemoryContextIsValid(header->context));
294 return header->context;
298 * MemoryContextIsEmpty
299 * Is a memory context empty of any allocated space?
301 bool
302 MemoryContextIsEmpty(MemoryContext context)
304 AssertArg(MemoryContextIsValid(context));
307 * For now, we consider a memory context nonempty if it has any children;
308 * perhaps this should be changed later.
310 if (context->firstchild != NULL)
311 return false;
312 /* Otherwise use the type-specific inquiry */
313 return (*context->methods->is_empty) (context);
317 * MemoryContextStats
318 * Print statistics about the named context and all its descendants.
320 * This is just a debugging utility, so it's not fancy. The statistics
321 * are merely sent to stderr.
323 void
324 MemoryContextStats(MemoryContext context)
326 MemoryContextStatsInternal(context, 0);
329 static void
330 MemoryContextStatsInternal(MemoryContext context, int level)
332 MemoryContext child;
334 AssertArg(MemoryContextIsValid(context));
336 (*context->methods->stats) (context, level);
337 for (child = context->firstchild; child != NULL; child = child->nextchild)
338 MemoryContextStatsInternal(child, level + 1);
342 * MemoryContextCheck
343 * Check all chunks in the named context.
345 * This is just a debugging utility, so it's not fancy.
347 #ifdef MEMORY_CONTEXT_CHECKING
348 void
349 MemoryContextCheck(MemoryContext context)
351 MemoryContext child;
353 AssertArg(MemoryContextIsValid(context));
355 (*context->methods->check) (context);
356 for (child = context->firstchild; child != NULL; child = child->nextchild)
357 MemoryContextCheck(child);
359 #endif
362 * MemoryContextContains
363 * Detect whether an allocated chunk of memory belongs to a given
364 * context or not.
366 * Caution: this test is reliable as long as 'pointer' does point to
367 * a chunk of memory allocated from *some* context. If 'pointer' points
368 * at memory obtained in some other way, there is a small chance of a
369 * false-positive result, since the bits right before it might look like
370 * a valid chunk header by chance.
372 bool
373 MemoryContextContains(MemoryContext context, void *pointer)
375 StandardChunkHeader *header;
378 * Try to detect bogus pointers handed to us, poorly though we can.
379 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
380 * allocated chunk.
382 if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
383 return false;
386 * OK, it's probably safe to look at the chunk header.
388 header = (StandardChunkHeader *)
389 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
392 * If the context link doesn't match then we certainly have a non-member
393 * chunk. Also check for a reasonable-looking size as extra guard against
394 * being fooled by bogus pointers.
396 if (header->context == context && AllocSizeIsValid(header->size))
397 return true;
398 return false;
401 /*--------------------
402 * MemoryContextCreate
403 * Context-type-independent part of context creation.
405 * This is only intended to be called by context-type-specific
406 * context creation routines, not by the unwashed masses.
408 * The context creation procedure is a little bit tricky because
409 * we want to be sure that we don't leave the context tree invalid
410 * in case of failure (such as insufficient memory to allocate the
411 * context node itself). The procedure goes like this:
412 * 1. Context-type-specific routine first calls MemoryContextCreate(),
413 * passing the appropriate tag/size/methods values (the methods
414 * pointer will ordinarily point to statically allocated data).
415 * The parent and name parameters usually come from the caller.
416 * 2. MemoryContextCreate() attempts to allocate the context node,
417 * plus space for the name. If this fails we can ereport() with no
418 * damage done.
419 * 3. We fill in all of the type-independent MemoryContext fields.
420 * 4. We call the type-specific init routine (using the methods pointer).
421 * The init routine is required to make the node minimally valid
422 * with zero chance of failure --- it can't allocate more memory,
423 * for example.
424 * 5. Now we have a minimally valid node that can behave correctly
425 * when told to reset or delete itself. We link the node to its
426 * parent (if any), making the node part of the context tree.
427 * 6. We return to the context-type-specific routine, which finishes
428 * up type-specific initialization. This routine can now do things
429 * that might fail (like allocate more memory), so long as it's
430 * sure the node is left in a state that delete will handle.
432 * This protocol doesn't prevent us from leaking memory if step 6 fails
433 * during creation of a top-level context, since there's no parent link
434 * in that case. However, if you run out of memory while you're building
435 * a top-level context, you might as well go home anyway...
437 * Normally, the context node and the name are allocated from
438 * TopMemoryContext (NOT from the parent context, since the node must
439 * survive resets of its parent context!). However, this routine is itself
440 * used to create TopMemoryContext! If we see that TopMemoryContext is NULL,
441 * we assume we are creating TopMemoryContext and use malloc() to allocate
442 * the node.
444 * Note that the name field of a MemoryContext does not point to
445 * separately-allocated storage, so it should not be freed at context
446 * deletion.
447 *--------------------
449 MemoryContext
450 MemoryContextCreate(NodeTag tag, Size size,
451 MemoryContextMethods *methods,
452 MemoryContext parent,
453 const char *name)
455 MemoryContext node;
456 Size needed = size + strlen(name) + 1;
458 /* Get space for node and name */
459 if (TopMemoryContext != NULL)
461 /* Normal case: allocate the node in TopMemoryContext */
462 node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,
463 needed);
465 else
467 /* Special case for startup: use good ol' malloc */
468 node = (MemoryContext) malloc(needed);
469 Assert(node != NULL);
472 /* Initialize the node as best we can */
473 MemSet(node, 0, size);
474 node->type = tag;
475 node->methods = methods;
476 node->parent = NULL; /* for the moment */
477 node->firstchild = NULL;
478 node->nextchild = NULL;
479 node->name = ((char *) node) + size;
480 strcpy(node->name, name);
482 /* Type-specific routine finishes any other essential initialization */
483 (*node->methods->init) (node);
485 /* OK to link node to parent (if any) */
486 if (parent)
488 node->parent = parent;
489 node->nextchild = parent->firstchild;
490 parent->firstchild = node;
493 /* Return to type-specific creation routine to finish up */
494 return node;
498 * MemoryContextAlloc
499 * Allocate space within the specified context.
501 * This could be turned into a macro, but we'd have to import
502 * nodes/memnodes.h into postgres.h which seems a bad idea.
504 void *
505 MemoryContextAlloc(MemoryContext context, Size size)
507 AssertArg(MemoryContextIsValid(context));
509 if (!AllocSizeIsValid(size))
510 elog(ERROR, "invalid memory alloc request size %lu",
511 (unsigned long) size);
513 return (*context->methods->alloc) (context, size);
517 * MemoryContextAllocZero
518 * Like MemoryContextAlloc, but clears allocated memory
520 * We could just call MemoryContextAlloc then clear the memory, but this
521 * is a very common combination, so we provide the combined operation.
523 void *
524 MemoryContextAllocZero(MemoryContext context, Size size)
526 void *ret;
528 AssertArg(MemoryContextIsValid(context));
530 if (!AllocSizeIsValid(size))
531 elog(ERROR, "invalid memory alloc request size %lu",
532 (unsigned long) size);
534 ret = (*context->methods->alloc) (context, size);
536 MemSetAligned(ret, 0, size);
538 return ret;
542 * MemoryContextAllocZeroAligned
543 * MemoryContextAllocZero where length is suitable for MemSetLoop
545 * This might seem overly specialized, but it's not because newNode()
546 * is so often called with compile-time-constant sizes.
548 void *
549 MemoryContextAllocZeroAligned(MemoryContext context, Size size)
551 void *ret;
553 AssertArg(MemoryContextIsValid(context));
555 if (!AllocSizeIsValid(size))
556 elog(ERROR, "invalid memory alloc request size %lu",
557 (unsigned long) size);
559 ret = (*context->methods->alloc) (context, size);
561 MemSetLoop(ret, 0, size);
563 return ret;
567 * pfree
568 * Release an allocated chunk.
570 void
571 pfree(void *pointer)
573 StandardChunkHeader *header;
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.
580 Assert(pointer != NULL);
581 Assert(pointer == (void *) MAXALIGN(pointer));
584 * OK, it's probably safe to look at the chunk header.
586 header = (StandardChunkHeader *)
587 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
589 AssertArg(MemoryContextIsValid(header->context));
591 (*header->context->methods->free_p) (header->context, pointer);
595 * repalloc
596 * Adjust the size of a previously allocated chunk.
598 void *
599 repalloc(void *pointer, Size size)
601 StandardChunkHeader *header;
604 * Try to detect bogus pointers handed to us, poorly though we can.
605 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an
606 * allocated chunk.
608 Assert(pointer != NULL);
609 Assert(pointer == (void *) MAXALIGN(pointer));
612 * OK, it's probably safe to look at the chunk header.
614 header = (StandardChunkHeader *)
615 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
617 AssertArg(MemoryContextIsValid(header->context));
619 if (!AllocSizeIsValid(size))
620 elog(ERROR, "invalid memory alloc request size %lu",
621 (unsigned long) size);
623 return (*header->context->methods->realloc) (header->context,
624 pointer, size);
628 * MemoryContextSwitchTo
629 * Returns the current context; installs the given context.
631 * This is inlined when using GCC.
633 * TODO: investigate supporting inlining for some non-GCC compilers.
635 #ifndef __GNUC__
637 MemoryContext
638 MemoryContextSwitchTo(MemoryContext context)
640 MemoryContext old;
642 AssertArg(MemoryContextIsValid(context));
644 old = CurrentMemoryContext;
645 CurrentMemoryContext = context;
646 return old;
648 #endif /* ! __GNUC__ */
651 * MemoryContextStrdup
652 * Like strdup(), but allocate from the specified context
654 char *
655 MemoryContextStrdup(MemoryContext context, const char *string)
657 char *nstr;
658 Size len = strlen(string) + 1;
660 nstr = (char *) MemoryContextAlloc(context, len);
662 memcpy(nstr, string, len);
664 return nstr;
668 * pnstrdup
669 * Like pstrdup(), but append null byte to a
670 * not-necessarily-null-terminated input string.
672 char *
673 pnstrdup(const char *in, Size len)
675 char *out = palloc(len + 1);
677 memcpy(out, in, len);
678 out[len] = '\0';
679 return out;
683 #if defined(WIN32) || defined(__CYGWIN__)
685 * Memory support routines for libpgport on Win32
687 * Win32 can't load a library that PGDLLIMPORTs a variable
688 * if the link object files also PGDLLIMPORT the same variable.
689 * For this reason, libpgport can't reference CurrentMemoryContext
690 * in the palloc macro calls.
692 * To fix this, we create several functions here that allow us to
693 * manage memory without doing the inline in libpgport.
695 void *
696 pgport_palloc(Size sz)
698 return palloc(sz);
702 char *
703 pgport_pstrdup(const char *str)
705 return pstrdup(str);
709 /* Doesn't reference a PGDLLIMPORT variable, but here for completeness. */
710 void
711 pgport_pfree(void *pointer)
713 pfree(pointer);
716 #endif