LCOV - differential code coverage report
Current view: top level - src/include/utils - memutils.h (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 61.0 % 41 25 16 25
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 1 1 1
Baseline: lcov-20250906-005545-baseline Branches: 47.5 % 40 19 21 19
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 61.0 % 41 25 16 25
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
Branch coverage date bins:
(30,360] days: 47.5 % 40 19 21 19

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * memutils.h
                                  4                 :                :  *    This file contains declarations for memory allocation utility
                                  5                 :                :  *    functions.  These are functions that are not quite widely used
                                  6                 :                :  *    enough to justify going in utils/palloc.h, but are still part
                                  7                 :                :  *    of the API of the memory management subsystem.
                                  8                 :                :  *
                                  9                 :                :  *
                                 10                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                 11                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 12                 :                :  *
                                 13                 :                :  * src/include/utils/memutils.h
                                 14                 :                :  *
                                 15                 :                :  *-------------------------------------------------------------------------
                                 16                 :                :  */
                                 17                 :                : #ifndef MEMUTILS_H
                                 18                 :                : #define MEMUTILS_H
                                 19                 :                : 
                                 20                 :                : #include "nodes/memnodes.h"
                                 21                 :                : 
                                 22                 :                : 
                                 23                 :                : /*
                                 24                 :                :  * MaxAllocSize, MaxAllocHugeSize
                                 25                 :                :  *      Quasi-arbitrary limits on size of allocations.
                                 26                 :                :  *
                                 27                 :                :  * Note:
                                 28                 :                :  *      There is no guarantee that smaller allocations will succeed, but
                                 29                 :                :  *      larger requests will be summarily denied.
                                 30                 :                :  *
                                 31                 :                :  * palloc() enforces MaxAllocSize, chosen to correspond to the limiting size
                                 32                 :                :  * of varlena objects under TOAST.  See VARSIZE_4B() and related macros in
                                 33                 :                :  * postgres.h.  Many datatypes assume that any allocatable size can be
                                 34                 :                :  * represented in a varlena header.  This limit also permits a caller to use
                                 35                 :                :  * an "int" variable for an index into or length of an allocation.  Callers
                                 36                 :                :  * careful to avoid these hazards can access the higher limit with
                                 37                 :                :  * MemoryContextAllocHuge().  Both limits permit code to assume that it may
                                 38                 :                :  * compute twice an allocation's size without overflow.
                                 39                 :                :  */
                                 40                 :                : #define MaxAllocSize    ((Size) 0x3fffffff) /* 1 gigabyte - 1 */
                                 41                 :                : 
                                 42                 :                : #define AllocSizeIsValid(size)  ((Size) (size) <= MaxAllocSize)
                                 43                 :                : 
                                 44                 :                : /* Must be less than SIZE_MAX */
                                 45                 :                : #define MaxAllocHugeSize    (SIZE_MAX / 2)
                                 46                 :                : 
                                 47                 :                : #define InvalidAllocSize    SIZE_MAX
                                 48                 :                : 
                                 49                 :                : #define AllocHugeSizeIsValid(size)  ((Size) (size) <= MaxAllocHugeSize)
                                 50                 :                : 
                                 51                 :                : 
                                 52                 :                : /*
                                 53                 :                :  * Standard top-level memory contexts.
                                 54                 :                :  *
                                 55                 :                :  * Only TopMemoryContext and ErrorContext are initialized by
                                 56                 :                :  * MemoryContextInit() itself.
                                 57                 :                :  */
                                 58                 :                : extern PGDLLIMPORT MemoryContext TopMemoryContext;
                                 59                 :                : extern PGDLLIMPORT MemoryContext ErrorContext;
                                 60                 :                : extern PGDLLIMPORT MemoryContext PostmasterContext;
                                 61                 :                : extern PGDLLIMPORT MemoryContext CacheMemoryContext;
                                 62                 :                : extern PGDLLIMPORT MemoryContext MessageContext;
                                 63                 :                : extern PGDLLIMPORT MemoryContext TopTransactionContext;
                                 64                 :                : extern PGDLLIMPORT MemoryContext CurTransactionContext;
                                 65                 :                : 
                                 66                 :                : /* This is a transient link to the active portal's memory context: */
                                 67                 :                : extern PGDLLIMPORT MemoryContext PortalContext;
                                 68                 :                : 
                                 69                 :                : 
                                 70                 :                : /*
                                 71                 :                :  * Memory-context-type-independent functions in mcxt.c
                                 72                 :                :  */
                                 73                 :                : extern void MemoryContextInit(void);
                                 74                 :                : extern void MemoryContextReset(MemoryContext context);
                                 75                 :                : extern void MemoryContextDelete(MemoryContext context);
                                 76                 :                : extern void MemoryContextResetOnly(MemoryContext context);
                                 77                 :                : extern void MemoryContextResetChildren(MemoryContext context);
                                 78                 :                : extern void MemoryContextDeleteChildren(MemoryContext context);
                                 79                 :                : extern void MemoryContextSetIdentifier(MemoryContext context, const char *id);
                                 80                 :                : extern void MemoryContextSetParent(MemoryContext context,
                                 81                 :                :                                    MemoryContext new_parent);
                                 82                 :                : extern MemoryContext GetMemoryChunkContext(void *pointer);
                                 83                 :                : extern Size GetMemoryChunkSpace(void *pointer);
                                 84                 :                : extern MemoryContext MemoryContextGetParent(MemoryContext context);
                                 85                 :                : extern bool MemoryContextIsEmpty(MemoryContext context);
                                 86                 :                : extern Size MemoryContextMemAllocated(MemoryContext context, bool recurse);
                                 87                 :                : extern void MemoryContextMemConsumed(MemoryContext context,
                                 88                 :                :                                      MemoryContextCounters *consumed);
                                 89                 :                : extern void MemoryContextStats(MemoryContext context);
                                 90                 :                : extern void MemoryContextStatsDetail(MemoryContext context,
                                 91                 :                :                                      int max_level, int max_children,
                                 92                 :                :                                      bool print_to_stderr);
                                 93                 :                : extern void MemoryContextAllowInCriticalSection(MemoryContext context,
                                 94                 :                :                                                 bool allow);
                                 95                 :                : 
                                 96                 :                : #ifdef MEMORY_CONTEXT_CHECKING
                                 97                 :                : extern void MemoryContextCheck(MemoryContext context);
                                 98                 :                : #endif
                                 99                 :                : 
                                100                 :                : /* Handy macro for copying and assigning context ID ... but note double eval */
                                101                 :                : #define MemoryContextCopyAndSetIdentifier(cxt, id) \
                                102                 :                :     MemoryContextSetIdentifier(cxt, MemoryContextStrdup(cxt, id))
                                103                 :                : 
                                104                 :                : extern void HandleLogMemoryContextInterrupt(void);
                                105                 :                : extern void ProcessLogMemoryContextInterrupt(void);
                                106                 :                : 
                                107                 :                : /*
                                108                 :                :  * Memory-context-type-specific functions
                                109                 :                :  */
                                110                 :                : 
                                111                 :                : /* aset.c */
                                112                 :                : extern MemoryContext AllocSetContextCreateInternal(MemoryContext parent,
                                113                 :                :                                                    const char *name,
                                114                 :                :                                                    Size minContextSize,
                                115                 :                :                                                    Size initBlockSize,
                                116                 :                :                                                    Size maxBlockSize);
                                117                 :                : 
                                118                 :                : /*
                                119                 :                :  * This wrapper macro exists to check for non-constant strings used as context
                                120                 :                :  * names; that's no longer supported.  (Use MemoryContextSetIdentifier if you
                                121                 :                :  * want to provide a variable identifier.)
                                122                 :                :  */
                                123                 :                : #ifdef HAVE__BUILTIN_CONSTANT_P
                                124                 :                : #define AllocSetContextCreate(parent, name, ...) \
                                125                 :                :     (StaticAssertExpr(__builtin_constant_p(name), \
                                126                 :                :                       "memory context names must be constant strings"), \
                                127                 :                :      AllocSetContextCreateInternal(parent, name, __VA_ARGS__))
                                128                 :                : #else
                                129                 :                : #define AllocSetContextCreate \
                                130                 :                :     AllocSetContextCreateInternal
                                131                 :                : #endif
                                132                 :                : 
                                133                 :                : /* slab.c */
                                134                 :                : extern MemoryContext SlabContextCreate(MemoryContext parent,
                                135                 :                :                                        const char *name,
                                136                 :                :                                        Size blockSize,
                                137                 :                :                                        Size chunkSize);
                                138                 :                : 
                                139                 :                : /* generation.c */
                                140                 :                : extern MemoryContext GenerationContextCreate(MemoryContext parent,
                                141                 :                :                                              const char *name,
                                142                 :                :                                              Size minContextSize,
                                143                 :                :                                              Size initBlockSize,
                                144                 :                :                                              Size maxBlockSize);
                                145                 :                : 
                                146                 :                : /* bump.c */
                                147                 :                : extern MemoryContext BumpContextCreate(MemoryContext parent,
                                148                 :                :                                        const char *name,
                                149                 :                :                                        Size minContextSize,
                                150                 :                :                                        Size initBlockSize,
                                151                 :                :                                        Size maxBlockSize);
                                152                 :                : 
                                153                 :                : /*
                                154                 :                :  * Recommended default alloc parameters, suitable for "ordinary" contexts
                                155                 :                :  * that might hold quite a lot of data.
                                156                 :                :  */
                                157                 :                : #define ALLOCSET_DEFAULT_MINSIZE   0
                                158                 :                : #define ALLOCSET_DEFAULT_INITSIZE  (8 * 1024)
                                159                 :                : #define ALLOCSET_DEFAULT_MAXSIZE   (8 * 1024 * 1024)
                                160                 :                : #define ALLOCSET_DEFAULT_SIZES \
                                161                 :                :     ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
                                162                 :                : 
                                163                 :                : /*
                                164                 :                :  * Recommended alloc parameters for "small" contexts that are never expected
                                165                 :                :  * to contain much data (for example, a context to contain a query plan).
                                166                 :                :  */
                                167                 :                : #define ALLOCSET_SMALL_MINSIZE   0
                                168                 :                : #define ALLOCSET_SMALL_INITSIZE  (1 * 1024)
                                169                 :                : #define ALLOCSET_SMALL_MAXSIZE   (8 * 1024)
                                170                 :                : #define ALLOCSET_SMALL_SIZES \
                                171                 :                :     ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
                                172                 :                : 
                                173                 :                : /*
                                174                 :                :  * Recommended alloc parameters for contexts that should start out small,
                                175                 :                :  * but might sometimes grow big.
                                176                 :                :  */
                                177                 :                : #define ALLOCSET_START_SMALL_SIZES \
                                178                 :                :     ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE
                                179                 :                : 
                                180                 :                : 
                                181                 :                : /*
                                182                 :                :  * Threshold above which a request in an AllocSet context is certain to be
                                183                 :                :  * allocated separately (and thereby have constant allocation overhead).
                                184                 :                :  * Few callers should be interested in this, but tuplesort/tuplestore need
                                185                 :                :  * to know it.
                                186                 :                :  */
                                187                 :                : #define ALLOCSET_SEPARATE_THRESHOLD  8192
                                188                 :                : 
                                189                 :                : #define SLAB_DEFAULT_BLOCK_SIZE     (8 * 1024)
                                190                 :                : #define SLAB_LARGE_BLOCK_SIZE       (8 * 1024 * 1024)
                                191                 :                : 
                                192                 :                : /*
                                193                 :                :  * pg_memory_is_all_zeros
                                194                 :                :  *
                                195                 :                :  * Test if a memory region starting at "ptr" and of size "len" is full of
                                196                 :                :  * zeroes.
                                197                 :                :  *
                                198                 :                :  * The test is divided into multiple cases for safety reason and multiple
                                199                 :                :  * phases for efficiency.
                                200                 :                :  *
                                201                 :                :  * Case 1: len < sizeof(size_t) bytes, then byte-by-byte comparison.
                                202                 :                :  * Case 2: len < (sizeof(size_t) * 8 - 1) bytes:
                                203                 :                :  *       - Phase 1: byte-by-byte comparison, until the pointer is aligned.
                                204                 :                :  *       - Phase 2: size_t comparisons, with aligned pointers, up to the last
                                205                 :                :  *                  location possible.
                                206                 :                :  *       - Phase 3: byte-by-byte comparison, until the end location.
                                207                 :                :  * Case 3: len >= (sizeof(size_t) * 8) bytes, same as case 2 except that an
                                208                 :                :  *         additional phase is placed between Phase 1 and Phase 2, with
                                209                 :                :  *         (8 * sizeof(size_t)) comparisons using bitwise OR to encourage
                                210                 :                :  *         compilers to use SIMD instructions if available, up to the last
                                211                 :                :  *         aligned location possible.
                                212                 :                :  *
                                213                 :                :  * Case 1 and Case 2 are mandatory to ensure that we won't read beyond the
                                214                 :                :  * memory area.  This is portable for 32-bit and 64-bit architectures.
                                215                 :                :  *
                                216                 :                :  * Caller must ensure that "ptr" is not NULL.
                                217                 :                :  */
                                218                 :                : static inline bool
  309 michael@paquier.xyz       219                 :CBC      809504 : pg_memory_is_all_zeros(const void *ptr, size_t len)
                                220                 :                : {
  292                           221                 :         809504 :     const unsigned char *p = (const unsigned char *) ptr;
                                222                 :         809504 :     const unsigned char *end = &p[len];
                                223                 :         809504 :     const unsigned char *aligned_end = (const unsigned char *)
                                224                 :         809504 :         ((uintptr_t) end & (~(sizeof(size_t) - 1)));
                                225                 :                : 
                                226         [ -  + ]:         809504 :     if (len < sizeof(size_t))
                                227                 :                :     {
  292 michael@paquier.xyz       228         [ #  # ]:UBC           0 :         while (p < end)
                                229                 :                :         {
                                230         [ #  # ]:              0 :             if (*p++ != 0)
                                231                 :              0 :                 return false;
                                232                 :                :         }
                                233                 :              0 :         return true;
                                234                 :                :     }
                                235                 :                : 
                                236                 :                :     /* "len" in the [sizeof(size_t), sizeof(size_t) * 8 - 1] range */
  292 michael@paquier.xyz       237         [ +  + ]:CBC      809504 :     if (len < sizeof(size_t) * 8)
                                238                 :                :     {
                                239                 :                :         /* Compare bytes until the pointer "p" is aligned */
                                240         [ -  + ]:          11160 :         while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
                                241                 :                :         {
  292 michael@paquier.xyz       242         [ #  # ]:UBC           0 :             if (p == end)
                                243                 :              0 :                 return true;
                                244         [ #  # ]:              0 :             if (*p++ != 0)
                                245                 :              0 :                 return false;
                                246                 :                :         }
                                247                 :                : 
                                248                 :                :         /*
                                249                 :                :          * Compare remaining size_t-aligned chunks.
                                250                 :                :          *
                                251                 :                :          * There is no risk to read beyond the memory area, as "aligned_end"
                                252                 :                :          * cannot be higher than "end".
                                253                 :                :          */
  292 michael@paquier.xyz       254         [ +  + ]:CBC       35628 :         for (; p < aligned_end; p += sizeof(size_t))
                                255                 :                :         {
                                256         [ +  + ]:          32237 :             if (*(size_t *) p != 0)
                                257                 :           7769 :                 return false;
                                258                 :                :         }
                                259                 :                : 
                                260                 :                :         /* Compare remaining bytes until the end */
                                261         [ -  + ]:           3391 :         while (p < end)
                                262                 :                :         {
  292 michael@paquier.xyz       263         [ #  # ]:UBC           0 :             if (*p++ != 0)
                                264                 :              0 :                 return false;
                                265                 :                :         }
  292 michael@paquier.xyz       266                 :CBC        3391 :         return true;
                                267                 :                :     }
                                268                 :                : 
                                269                 :                :     /* "len" in the [sizeof(size_t) * 8, inf) range */
                                270                 :                : 
                                271                 :                :     /* Compare bytes until the pointer "p" is aligned */
                                272         [ -  + ]:         798344 :     while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0)
                                273                 :                :     {
  292 michael@paquier.xyz       274         [ #  # ]:UBC           0 :         if (p == end)
                                275                 :              0 :             return true;
                                276                 :                : 
                                277         [ #  # ]:              0 :         if (*p++ != 0)
                                278                 :              0 :             return false;
                                279                 :                :     }
                                280                 :                : 
                                281                 :                :     /*
                                282                 :                :      * Compare 8 * sizeof(size_t) chunks at once.
                                283                 :                :      *
                                284                 :                :      * For performance reasons, we manually unroll this loop and purposefully
                                285                 :                :      * use bitwise-ORs to combine each comparison.  This prevents boolean
                                286                 :                :      * short-circuiting and lets the compiler know that it's safe to access
                                287                 :                :      * all 8 elements regardless of the result of the other comparisons.  This
                                288                 :                :      * seems to be enough to coax a few compilers into using SIMD
                                289                 :                :      * instructions.
                                290                 :                :      */
  292 michael@paquier.xyz       291         [ +  + ]:CBC     1610702 :     for (; p < aligned_end - (sizeof(size_t) * 7); p += sizeof(size_t) * 8)
                                292                 :                :     {
                                293                 :        1321607 :         if ((((size_t *) p)[0] != 0) | (((size_t *) p)[1] != 0) |
                                294                 :        1321607 :             (((size_t *) p)[2] != 0) | (((size_t *) p)[3] != 0) |
                                295                 :        1321607 :             (((size_t *) p)[4] != 0) | (((size_t *) p)[5] != 0) |
                                296         [ +  + ]:        1321607 :             (((size_t *) p)[6] != 0) | (((size_t *) p)[7] != 0))
                                297                 :         509249 :             return false;
                                298                 :                :     }
                                299                 :                : 
                                300                 :                :     /*
                                301                 :                :      * Compare remaining size_t-aligned chunks.
                                302                 :                :      *
                                303                 :                :      * There is no risk to read beyond the memory area, as "aligned_end"
                                304                 :                :      * cannot be higher than "end".
                                305                 :                :      */
                                306         [ +  + ]:        1395273 :     for (; p < aligned_end; p += sizeof(size_t))
                                307                 :                :     {
                                308         [ +  + ]:        1375890 :         if (*(size_t *) p != 0)
  309                           309                 :         269712 :             return false;
                                310                 :                :     }
                                311                 :                : 
                                312                 :                :     /* Compare remaining bytes until the end */
  292                           313         [ -  + ]:          19383 :     while (p < end)
                                314                 :                :     {
  292 michael@paquier.xyz       315         [ #  # ]:UBC           0 :         if (*p++ != 0)
                                316                 :              0 :             return false;
                                317                 :                :     }
                                318                 :                : 
  309 michael@paquier.xyz       319                 :CBC       19383 :     return true;
                                320                 :                : }
                                321                 :                : 
                                322                 :                : #endif                          /* MEMUTILS_H */
        

Generated by: LCOV version 2.4-beta