1 /*-------------------------------------------------------------------------
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-2007, PostgreSQL Global Development Group
13 * Portions Copyright (c) 1994, Regents of the University of California
17 * $PostgreSQL: pgsql/src/backend/utils/mmgr/mcxt.c,v 1.60 2007/03/13 00:33:42 tgl Exp $
19 *-------------------------------------------------------------------------
24 #include "utils/memutils.h"
27 /*****************************************************************************
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;
53 /*****************************************************************************
55 *****************************************************************************/
60 * Start up the memory-context subsystem.
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.
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).
71 * In a standalone backend this must be called during backend startup.
74 MemoryContextInit(void)
76 AssertState(TopMemoryContext == NULL);
79 * Initialize TopMemoryContext as an AllocSetContext with slow growth rate
80 * --- we don't really expect much to be allocated in it.
82 * (There is special-case code in MemoryContextCreate() for this call.)
84 TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL,
91 * Not having any other place to point CurrentMemoryContext, make it point
92 * to TopMemoryContext. Caller should change this soon!
94 CurrentMemoryContext = TopMemoryContext;
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
104 ErrorContext = AllocSetContextCreate(TopMemoryContext,
113 * Release all space allocated within a context and its descendants,
114 * but don't delete the contexts themselves.
116 * The type-specific reset routine handles the context itself, but we
117 * have to do the recursion for the children.
120 MemoryContextReset(MemoryContext context)
122 AssertArg(MemoryContextIsValid(context));
124 /* save a function call in common case where there are no children */
125 if (context->firstchild != NULL)
126 MemoryContextResetChildren(context);
128 (*context->methods->reset) (context);
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.
138 MemoryContextResetChildren(MemoryContext context)
142 AssertArg(MemoryContextIsValid(context));
144 for (child = context->firstchild; child != NULL; child = child->nextchild)
145 MemoryContextReset(child);
149 * MemoryContextDelete
150 * Delete a context and its descendants, and release all space
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.
159 MemoryContextDelete(MemoryContext context)
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);
167 MemoryContextDeleteChildren(context);
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.
176 MemoryContext parent = context->parent;
178 if (context == parent->firstchild)
179 parent->firstchild = context->nextchild;
184 for (child = parent->firstchild; child; child = child->nextchild)
186 if (context == child->nextchild)
188 child->nextchild = context->nextchild;
194 (*context->methods->delete) (context);
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.
204 MemoryContextDeleteChildren(MemoryContext context)
206 AssertArg(MemoryContextIsValid(context));
209 * MemoryContextDelete will delink the child from me, so just iterate as
210 * long as there is a child.
212 while (context->firstchild != NULL)
213 MemoryContextDelete(context->firstchild);
217 * MemoryContextResetAndDeleteChildren
218 * Release all space allocated within a context and delete all
221 * This is a common combination case where we want to preserve the
222 * specific context but get rid of absolutely everything under it.
225 MemoryContextResetAndDeleteChildren(MemoryContext context)
227 AssertArg(MemoryContextIsValid(context));
229 MemoryContextDeleteChildren(context);
230 (*context->methods->reset) (context);
234 * GetMemoryChunkSpace
235 * Given a currently-allocated chunk, determine the total space
236 * it occupies (including all memory-allocation overhead).
238 * This is useful for measuring the total space occupied by a set of
242 GetMemoryChunkSpace(void *pointer)
244 StandardChunkHeader *header;
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
251 Assert(pointer != NULL);
252 Assert(pointer == (void *) MAXALIGN(pointer));
255 * OK, it's probably safe to look at the chunk header.
257 header = (StandardChunkHeader *)
258 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
260 AssertArg(MemoryContextIsValid(header->context));
262 return (*header->context->methods->get_chunk_space) (header->context,
267 * GetMemoryChunkContext
268 * Given a currently-allocated chunk, determine the context
272 GetMemoryChunkContext(void *pointer)
274 StandardChunkHeader *header;
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
281 Assert(pointer != NULL);
282 Assert(pointer == (void *) MAXALIGN(pointer));
285 * OK, it's probably safe to look at the chunk header.
287 header = (StandardChunkHeader *)
288 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
290 AssertArg(MemoryContextIsValid(header->context));
292 return header->context;
296 * MemoryContextIsEmpty
297 * Is a memory context empty of any allocated space?
300 MemoryContextIsEmpty(MemoryContext context)
302 AssertArg(MemoryContextIsValid(context));
305 * For now, we consider a memory context nonempty if it has any children;
306 * perhaps this should be changed later.
308 if (context->firstchild != NULL)
310 /* Otherwise use the type-specific inquiry */
311 return (*context->methods->is_empty) (context);
316 * Print statistics about the named context and all its descendants.
318 * This is just a debugging utility, so it's not fancy. The statistics
319 * are merely sent to stderr.
322 MemoryContextStats(MemoryContext context)
326 AssertArg(MemoryContextIsValid(context));
328 (*context->methods->stats) (context);
329 for (child = context->firstchild; child != NULL; child = child->nextchild)
330 MemoryContextStats(child);
336 * Check all chunks in the named context.
338 * This is just a debugging utility, so it's not fancy.
340 #ifdef MEMORY_CONTEXT_CHECKING
342 MemoryContextCheck(MemoryContext context)
346 AssertArg(MemoryContextIsValid(context));
348 (*context->methods->check) (context);
349 for (child = context->firstchild; child != NULL; child = child->nextchild)
350 MemoryContextCheck(child);
355 * MemoryContextContains
356 * Detect whether an allocated chunk of memory belongs to a given
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.
366 MemoryContextContains(MemoryContext context, void *pointer)
368 StandardChunkHeader *header;
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
375 if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
379 * OK, it's probably safe to look at the chunk header.
381 header = (StandardChunkHeader *)
382 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
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.
389 if (header->context == context && AllocSizeIsValid(header->size))
394 /*--------------------
395 * MemoryContextCreate
396 * Context-type-independent part of context creation.
398 * This is only intended to be called by context-type-specific
399 * context creation routines, not by the unwashed masses.
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
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,
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.
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...
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
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
440 *--------------------
443 MemoryContextCreate(NodeTag tag, Size size,
444 MemoryContextMethods *methods,
445 MemoryContext parent,
449 Size needed = size + strlen(name) + 1;
451 /* Get space for node and name */
452 if (TopMemoryContext != NULL)
454 /* Normal case: allocate the node in TopMemoryContext */
455 node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,
460 /* Special case for startup: use good ol' malloc */
461 node = (MemoryContext) malloc(needed);
462 Assert(node != NULL);
465 /* Initialize the node as best we can */
466 MemSet(node, 0, size);
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);
475 /* Type-specific routine finishes any other essential initialization */
476 (*node->methods->init) (node);
478 /* OK to link node to parent (if any) */
481 node->parent = parent;
482 node->nextchild = parent->firstchild;
483 parent->firstchild = node;
486 /* Return to type-specific creation routine to finish up */
492 * Allocate space within the specified context.
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.
498 MemoryContextAlloc(MemoryContext context, Size size)
500 AssertArg(MemoryContextIsValid(context));
502 if (!AllocSizeIsValid(size))
503 elog(ERROR, "invalid memory alloc request size %lu",
504 (unsigned long) size);
506 return (*context->methods->alloc) (context, size);
510 * MemoryContextAllocZero
511 * Like MemoryContextAlloc, but clears allocated memory
513 * We could just call MemoryContextAlloc then clear the memory, but this
514 * is a very common combination, so we provide the combined operation.
517 MemoryContextAllocZero(MemoryContext context, Size size)
521 AssertArg(MemoryContextIsValid(context));
523 if (!AllocSizeIsValid(size))
524 elog(ERROR, "invalid memory alloc request size %lu",
525 (unsigned long) size);
527 ret = (*context->methods->alloc) (context, size);
529 MemSetAligned(ret, 0, size);
535 * MemoryContextAllocZeroAligned
536 * MemoryContextAllocZero where length is suitable for MemSetLoop
538 * This might seem overly specialized, but it's not because newNode()
539 * is so often called with compile-time-constant sizes.
542 MemoryContextAllocZeroAligned(MemoryContext context, Size size)
546 AssertArg(MemoryContextIsValid(context));
548 if (!AllocSizeIsValid(size))
549 elog(ERROR, "invalid memory alloc request size %lu",
550 (unsigned long) size);
552 ret = (*context->methods->alloc) (context, size);
554 MemSetLoop(ret, 0, size);
561 * Release an allocated chunk.
566 StandardChunkHeader *header;
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
573 Assert(pointer != NULL);
574 Assert(pointer == (void *) MAXALIGN(pointer));
577 * OK, it's probably safe to look at the chunk header.
579 header = (StandardChunkHeader *)
580 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
582 AssertArg(MemoryContextIsValid(header->context));
584 (*header->context->methods->free_p) (header->context, pointer);
589 * Adjust the size of a previously allocated chunk.
592 repalloc(void *pointer, Size size)
594 StandardChunkHeader *header;
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
601 Assert(pointer != NULL);
602 Assert(pointer == (void *) MAXALIGN(pointer));
605 * OK, it's probably safe to look at the chunk header.
607 header = (StandardChunkHeader *)
608 ((char *) pointer - STANDARDCHUNKHEADERSIZE);
610 AssertArg(MemoryContextIsValid(header->context));
612 if (!AllocSizeIsValid(size))
613 elog(ERROR, "invalid memory alloc request size %lu",
614 (unsigned long) size);
616 return (*header->context->methods->realloc) (header->context,
621 * MemoryContextSwitchTo
622 * Returns the current context; installs the given context.
624 * This is inlined when using GCC.
626 * TODO: investigate supporting inlining for some non-GCC compilers.
631 MemoryContextSwitchTo(MemoryContext context)
635 AssertArg(MemoryContextIsValid(context));
637 old = CurrentMemoryContext;
638 CurrentMemoryContext = context;
641 #endif /* ! __GNUC__ */
644 * MemoryContextStrdup
645 * Like strdup(), but allocate from the specified context
648 MemoryContextStrdup(MemoryContext context, const char *string)
651 Size len = strlen(string) + 1;
653 nstr = (char *) MemoryContextAlloc(context, len);
655 memcpy(nstr, string, len);
661 #if defined(WIN32) || defined(__CYGWIN__)
663 * Memory support routines for libpgport on Win32
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.
670 * To fix this, we create several functions here that allow us to
671 * manage memory without doing the inline in libpgport.
674 pgport_palloc(Size sz)
681 pgport_pstrdup(const char *str)
687 /* Doesn't reference a DLLIMPORT variable, but here for completeness. */
689 pgport_pfree(void *pointer)