More MemoryContext integration.
authorRobert Haas <rhaas@postgresql.org>
Wed, 4 Jun 2014 19:04:04 +0000 (15:04 -0400)
committerRobert Haas <rhaas@postgresql.org>
Wed, 4 Jun 2014 19:04:04 +0000 (15:04 -0400)
src/backend/access/nbtree/nbtsort.c
src/backend/utils/mmgr/balloc.c
src/backend/utils/mmgr/mcxt.c
src/backend/utils/sort/tuplesort.c
src/include/utils/balloc.h

index be5e46d29cc58440fda42a900aa2f7ec992717e5..048b215118642837c76e8cc2d06b1b6cb6ebc52e 100644 (file)
@@ -72,7 +72,6 @@
 #include "storage/smgr.h"
 #include "tcop/tcopprot.h"
 #include "utils/rel.h"
-#include "utils/balloc.h"
 #include "utils/tuplesort.h"
 
 
@@ -770,7 +769,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
                        {
                                _bt_buildadd(wstate, state, itup);
                                if (should_free)
-                                       BlockAllocatorFree(itup);
+                                       pfree(itup);
                                itup = tuplesort_getindextuple(btspool->sortstate,
                                                                                           true, &should_free);
                        }
@@ -778,7 +777,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
                        {
                                _bt_buildadd(wstate, state, itup2);
                                if (should_free2)
-                                       BlockAllocatorFree(itup2);
+                                       pfree(itup2);
                                itup2 = tuplesort_getindextuple(btspool2->sortstate,
                                                                                                true, &should_free2);
                        }
@@ -797,7 +796,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
 
                        _bt_buildadd(wstate, state, itup);
                        if (should_free)
-                               BlockAllocatorFree(itup);
+                               pfree(itup);
                }
        }
 
index 2c54cb9b30d2e2903a8caff2835cc3c3222fdd56..2fc256df60cd1e11ce2935e82ee76933c2e72dd0 100644 (file)
@@ -359,9 +359,8 @@ BlockAllocatorAlloc(MemoryContext context, Size size)
  * Free memory allocated via BlockAllocatorAlloc.
  */
 void
-BlockAllocatorFree(void *ptr)
+BlockAllocatorFree(AllocatorRegion *aregion, void *ptr)
 {
-       AllocatorRegion *region;
        char   *fpm_base;
        char   *base = NULL;
        BlockAllocatorSpan *span;
@@ -372,16 +371,15 @@ BlockAllocatorFree(void *ptr)
        uint16  size_class;
 
        /* Locate the containing span. */
-       region = LookupAllocatorRegion(ptr);
-       fpm_base = fpm_segment_base(region->fpm);
+       fpm_base = fpm_segment_base(aregion->fpm);
        pageno = fpm_pointer_to_page(fpm_base, ptr);
-       span = BlockAllocatorMapGet(region->pagemap, pageno);
+       span = BlockAllocatorMapGet(aregion->pagemap, pageno);
 
        /*
         * If this is a shared-memory region, we might need locking.  If so,
         * lock the heap.
         */
-       if (region->seg != NULL)
+       if (aregion->seg != NULL)
        {
                BlockAllocatorHeap *heap = relptr_access(fpm_base, span->parent);
                base = fpm_base;
@@ -403,8 +401,8 @@ BlockAllocatorFree(void *ptr)
                BlockAllocatorUnlinkSpan(base, heap, span);
                first_page = fpm_pointer_to_page(fpm_base,
                                                                                 relptr_access(base, span->start));
-               FreePageManagerPut(region->fpm, first_page, span->npages);
-               BlockAllocatorFree(span);
+               FreePageManagerPut(aregion->fpm, first_page, span->npages);
+               pfree(span);
 
                /* We're done, but must release any lock first. */
                if (lock != NULL)
@@ -458,7 +456,7 @@ BlockAllocatorFree(void *ptr)
                BlockAllocatorUnlinkSpan(base, heap, span);
                first_page = fpm_pointer_to_page(fpm_base,
                                                                                 relptr_access(base, span->start));
-               FreePageManagerPut(region->fpm, first_page, span->npages);
+               FreePageManagerPut(aregion->fpm, first_page, span->npages);
 
                /*
                 * Span-of-spans blocks store the span which describes them
@@ -467,7 +465,7 @@ BlockAllocatorFree(void *ptr)
                 * type, we need to separately free the span object also.
                 */
                if (size_class != BA_SCLASS_BLOCK_OF_SPANS)
-                       BlockAllocatorFree(span);
+                       pfree(span);
        }
 
        /* If we locked the heap, release the lock. */
@@ -559,6 +557,43 @@ BlockAllocatorGetChunkSpace(AllocatorRegion *aregion, void *ptr)
                return balloc_size_classes[size_class];
 }
 
+/*
+ * Given a pointer, and the AllocatorRegion which contains it, find the
+ * memory context.
+ */
+MemoryContext
+BlockAllocatorGetChunkContext(AllocatorRegion *aregion, void *ptr)
+{
+       char   *fpm_base;
+       BlockAllocatorSpan *span;
+       BlockAllocatorHeap *heap;
+       BlockAllocatorHeap *heap0;
+       BlockAllocatorContext *context;
+       Size    pageno;
+
+       /* Locate the containing block. */
+       fpm_base = fpm_segment_base(aregion->fpm);
+       pageno = fpm_pointer_to_page(fpm_base, ptr);
+       span = BlockAllocatorMapGet(aregion->pagemap, pageno);
+
+       /* Follow the parent poiner to find the containing heap. */
+       heap = relptr_access(fpm_base, span->parent);
+
+       /*
+        * Department of incredible ugliness: neither the heap nor the span
+        * actually contains a pointer to the context.  However, we know which
+        * heap this has to be based on the size class.  Hello, pointer
+        * arithmetic!
+        */
+       heap0 = heap - span->size_class;
+       context = (BlockAllocatorContext *)
+               (((char *) heap0) - offsetof(BlockAllocatorContext, heaps[0]));
+
+       Assert(IsA(context, BlockAllocatorContext));
+
+       return &context->header;
+}
+
 /*
  * Unneeded callback provided by the MemoryContext machinery.
  */
index 7b1cc74a46e20aa0c60de339637a1f5482e7e646..0835dd9246dfaf2405dae7a96f718fcb13a47cd2 100644 (file)
@@ -389,6 +389,20 @@ GetMemoryChunkContext(void *pointer)
        Assert(pointer != NULL);
        Assert(pointer == (void *) MAXALIGN(pointer));
 
+       /*
+        * If allocator regions are in use, then this pointer might be within
+        * such a region, in which case it won't have a chunk header.  So, we have
+        * to test for and handle that case first.
+        */
+       if (aregion_private_pages_allocated > 0)
+       {
+               AllocatorRegion *aregion;
+
+               aregion = LookupAllocatorRegion(pointer);
+               if (aregion != NULL)
+                       return BlockAllocatorGetChunkContext(aregion, pointer);
+       }
+
        /*
         * OK, it's probably safe to look at the chunk header.
         */
@@ -500,6 +514,20 @@ MemoryContextContains(MemoryContext context, void *pointer)
        if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))
                return false;
 
+       /*
+        * If allocator regions are in use, then this pointer might be within
+        * such a region, in which case it won't have a chunk header.  So, we have
+        * to test for and handle that case first.
+        */
+       if (aregion_private_pages_allocated > 0)
+       {
+               AllocatorRegion *aregion;
+
+               aregion = LookupAllocatorRegion(pointer);
+               if (aregion != NULL)
+                       return BlockAllocatorGetChunkContext(aregion, pointer) == context;
+       }
+
        /*
         * OK, it's probably safe to look at the chunk header.
         */
@@ -758,6 +786,23 @@ pfree(void *pointer)
        Assert(pointer != NULL);
        Assert(pointer == (void *) MAXALIGN(pointer));
 
+       /*
+        * If allocator regions are in use, then this pointer might be within
+        * such a region, in which case it won't have a chunk header.  So, we have
+        * to test for and handle that case first.
+        */
+       if (aregion_private_pages_allocated > 0)
+       {
+               AllocatorRegion *aregion;
+
+               aregion = LookupAllocatorRegion(pointer);
+               if (aregion != NULL)
+               {
+                       BlockAllocatorFree(aregion, pointer);
+                       return;
+               }
+       }
+
        /*
         * OK, it's probably safe to look at the chunk header.
         */
index ad88d1a8e1aaa5af9c2ecd72fcfc5a1372334d61..d4e9591ac9d3b0fb822c0707fb541fb984fff443 100644 (file)
@@ -3378,7 +3378,7 @@ writetup_index(Tuplesortstate *state, int tapenum, SortTuple *stup)
                                                 (void *) &tuplen, sizeof(tuplen));
 
        FREEMEM(state, GetMemoryChunkSpace(tuple));
-       BlockAllocatorFree(tuple);
+       pfree(tuple);
 }
 
 static void
index 7758b778ea647fa968173abca42161f998e69c99..7845a1e28a7e5d91ac2ded3f41571d8b6ee3bb5d 100644 (file)
@@ -15,7 +15,6 @@
 #define BALLOC_H
 
 #include "storage/lwlock.h"
-#include "utils/relptr.h"
 
 struct AllocatorRegion;
 typedef struct BlockAllocatorContext BlockAllocatorContext;
@@ -29,13 +28,15 @@ extern MemoryContext BlockAllocatorContextCreate(MemoryContext parent,
 
 /* MemoryContetMethods for block allocator */
 extern void *BlockAllocatorAlloc(MemoryContext, Size);
-extern void BlockAllocatorFree(void *ptr);                     /* WRONG SIGNATURE */
+extern void BlockAllocatorFree(struct AllocatorRegion *, void *ptr);
 /* REALLOC IS MISSING! */
 extern void BlockAllocatorInit(MemoryContext);
 extern void BlockAllocatorReset(MemoryContext);
 extern void BlockAllocatorDelete(MemoryContext);
 extern Size BlockAllocatorGetChunkSpace(struct AllocatorRegion *, void *ptr);
 extern Size BlockAllocatorGetAllocSpace(Size size);    /* EXTRA FUNCTION */
+extern MemoryContext BlockAllocatorGetChunkContext(struct AllocatorRegion *,
+                                                                                                  void *ptr);
 /* IS_EMPTY IS MISSING! */
 /* STATS IS MISSING! */
 /* CHECK IS MISSING */