LCOV - code coverage report
Current view: top level - src/backend/utils/mmgr - mcxt.c (source / functions) Hit Total Coverage
Test: PostgreSQL 12devel Lines: 186 287 64.8 %
Date: 2018-11-13 18:21:17 Functions: 29 35 82.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13