LCOV - differential code coverage report
Current view: top level - src/backend/utils/mmgr - alignedalloc.c (source / functions) Coverage Total Hit UNC GNC
Current: Differential Code Coverage HEAD vs 15 Lines: 25.0 % 28 7 21 7
Current Date: 2023-04-08 15:15:32 Functions: 25.0 % 4 1 3 1
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  * alignedalloc.c
       4                 :  *    Allocator functions to implement palloc_aligned
       5                 :  *
       6                 :  * This is not a fully-fledged MemoryContext type as there is no means to
       7                 :  * create a MemoryContext of this type.  The code here only serves to allow
       8                 :  * operations such as pfree() and repalloc() to work correctly on a memory
       9                 :  * chunk that was allocated by palloc_aligned().
      10                 :  *
      11                 :  * Portions Copyright (c) 2022-2023, PostgreSQL Global Development Group
      12                 :  *
      13                 :  * IDENTIFICATION
      14                 :  *    src/backend/utils/mmgr/alignedalloc.c
      15                 :  *
      16                 :  *-------------------------------------------------------------------------
      17                 :  */
      18                 : 
      19                 : #include "postgres.h"
      20                 : 
      21                 : #include "utils/memdebug.h"
      22                 : #include "utils/memutils_memorychunk.h"
      23                 : 
      24                 : /*
      25                 :  * AlignedAllocFree
      26                 : *       Frees allocated memory; memory is removed from its owning context.
      27                 : */
      28                 : void
      29 GNC      234297 : AlignedAllocFree(void *pointer)
      30                 : {
      31          234297 :     MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
      32                 :     void       *unaligned;
      33                 : 
      34          234297 :     Assert(!MemoryChunkIsExternal(chunk));
      35                 : 
      36                 :     /* obtain the original (unaligned) allocated pointer */
      37          234297 :     unaligned = MemoryChunkGetBlock(chunk);
      38                 : 
      39                 : #ifdef MEMORY_CONTEXT_CHECKING
      40                 :     /* Test for someone scribbling on unused space in chunk */
      41          234297 :     if (!sentinel_ok(pointer, chunk->requested_size))
      42 UNC           0 :         elog(WARNING, "detected write past chunk end in %s %p",
      43                 :              GetMemoryChunkContext(unaligned)->name, chunk);
      44                 : #endif
      45                 : 
      46 GNC      234297 :     pfree(unaligned);
      47          234297 : }
      48                 : 
      49                 : /*
      50                 :  * AlignedAllocRealloc
      51                 :  *      Change the allocated size of a chunk and return possibly a different
      52                 :  *      pointer to a memory address aligned to the same boundary as the
      53                 :  *      originally requested alignment.  The contents of 'pointer' will be
      54                 :  *      copied into the returned pointer up until 'size'.  Any additional
      55                 :  *      memory will be uninitialized.
      56                 :  */
      57                 : void *
      58 UNC           0 : AlignedAllocRealloc(void *pointer, Size size)
      59                 : {
      60               0 :     MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
      61               0 :     Size        alignto = MemoryChunkGetValue(redirchunk);
      62               0 :     void       *unaligned = MemoryChunkGetBlock(redirchunk);
      63                 :     MemoryContext ctx;
      64                 :     Size        old_size;
      65                 :     void       *newptr;
      66                 : 
      67                 :     /* sanity check this is a power of 2 value */
      68               0 :     Assert((alignto & (alignto - 1)) == 0);
      69                 : 
      70                 :     /*
      71                 :      * Determine the size of the original allocation.  We can't determine this
      72                 :      * exactly as GetMemoryChunkSpace() returns the total space used for the
      73                 :      * allocation, which for contexts like aset includes rounding up to the
      74                 :      * next power of 2.  However, this value is just used to memcpy() the old
      75                 :      * data into the new allocation, so we only need to concern ourselves with
      76                 :      * not reading beyond the end of the original allocation's memory.  The
      77                 :      * drawback here is that we may copy more bytes than we need to, which
      78                 :      * only amounts to wasted effort.  We can safely subtract the extra bytes
      79                 :      * that we requested to allow us to align the pointer.  We must also
      80                 :      * subtract the space for the unaligned pointer's MemoryChunk since
      81                 :      * GetMemoryChunkSpace should have included that.  This does assume that
      82                 :      * all context types use MemoryChunk as a chunk header.
      83                 :      */
      84               0 :     old_size = GetMemoryChunkSpace(unaligned) -
      85                 :         PallocAlignedExtraBytes(alignto) - sizeof(MemoryChunk);
      86                 : 
      87                 : #ifdef MEMORY_CONTEXT_CHECKING
      88                 :     /* check that GetMemoryChunkSpace returned something realistic */
      89               0 :     Assert(old_size >= redirchunk->requested_size);
      90                 : #endif
      91                 : 
      92               0 :     ctx = GetMemoryChunkContext(unaligned);
      93               0 :     newptr = MemoryContextAllocAligned(ctx, size, alignto, 0);
      94                 : 
      95                 :     /*
      96                 :      * We may memcpy beyond the end of the original allocation request size,
      97                 :      * so we must mark the entire allocation as defined.
      98                 :      */
      99                 :     VALGRIND_MAKE_MEM_DEFINED(pointer, old_size);
     100               0 :     memcpy(newptr, pointer, Min(size, old_size));
     101               0 :     pfree(unaligned);
     102                 : 
     103               0 :     return newptr;
     104                 : }
     105                 : 
     106                 : /*
     107                 :  * AlignedAllocGetChunkContext
     108                 :  *      Return the MemoryContext that 'pointer' belongs to.
     109                 :  */
     110                 : MemoryContext
     111               0 : AlignedAllocGetChunkContext(void *pointer)
     112                 : {
     113               0 :     MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
     114                 : 
     115               0 :     Assert(!MemoryChunkIsExternal(chunk));
     116                 : 
     117               0 :     return GetMemoryChunkContext(MemoryChunkGetBlock(chunk));
     118                 : }
     119                 : 
     120                 : /*
     121                 :  * AlignedAllocGetChunkSpace
     122                 :  *      Given a currently-allocated chunk, determine the total space
     123                 :  *      it occupies (including all memory-allocation overhead).
     124                 :  */
     125                 : Size
     126               0 : AlignedAllocGetChunkSpace(void *pointer)
     127                 : {
     128               0 :     MemoryChunk *redirchunk = PointerGetMemoryChunk(pointer);
     129               0 :     void       *unaligned = MemoryChunkGetBlock(redirchunk);
     130                 : 
     131               0 :     return GetMemoryChunkSpace(unaligned);
     132                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a