From: Heikki Linnakangas Date: Sat, 21 May 2011 18:47:19 +0000 (-0400) Subject: Pull up isReset flag from AllocSetContext to MemoryContext struct. This X-Git-Tag: REL9_1_BETA2~97 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=30e98a7e6e4869a7d6b3748ac9770bb8d69a8b26;p=postgresql Pull up isReset flag from AllocSetContext to MemoryContext struct. This avoids the overhead of one function call when calling MemoryContextReset(), and it seems like the isReset optimization would be applicable to any new memory context we might invent in the future anyway. This buys back the overhead I just added in previous patch to always call MemoryContextReset() in ExecScan, even when there's no quals or projections. --- diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index 140b0c74d9..9e321283e5 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -128,7 +128,7 @@ typedef void *AllocPointer; /* * AllocSetContext is our standard implementation of MemoryContext. * - * Note: isReset means there is nothing for AllocSetReset to do. This is + * Note: header.isReset means there is nothing for AllocSetReset to do. This is * different from the aset being physically empty (empty blocks list) because * we may still have a keeper block. It's also different from the set being * logically empty, because we don't attempt to detect pfree'ing the last @@ -140,7 +140,6 @@ typedef struct AllocSetContext /* Info about storage allocated in this context: */ AllocBlock blocks; /* head of list of blocks in this set */ AllocChunk freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */ - bool isReset; /* T = no space alloced since last reset */ /* Allocation parameters for this context: */ Size initBlockSize; /* initial block size */ Size maxBlockSize; /* maximum block size */ @@ -427,8 +426,6 @@ AllocSetContextCreate(MemoryContext parent, context->keeper = block; } - context->isReset = true; - return (MemoryContext) context; } @@ -472,10 +469,6 @@ AllocSetReset(MemoryContext context) AssertArg(AllocSetIsValid(set)); - /* Nothing to do if no pallocs since startup or last reset */ - if (set->isReset) - return; - #ifdef MEMORY_CONTEXT_CHECKING /* Check for corruption and leaks before freeing */ AllocSetCheck(context); @@ -519,8 +512,6 @@ AllocSetReset(MemoryContext context) /* Reset block size allocation sequence, too */ set->nextBlockSize = set->initBlockSize; - - set->isReset = true; } /* @@ -629,8 +620,6 @@ AllocSetAlloc(MemoryContext context, Size size) set->blocks = block; } - set->isReset = false; - AllocAllocInfo(set, chunk); return AllocChunkGetPointer(chunk); } @@ -662,9 +651,6 @@ AllocSetAlloc(MemoryContext context, Size size) randomize_mem((char *) AllocChunkGetPointer(chunk), size); #endif - /* isReset must be false already */ - Assert(!set->isReset); - AllocAllocInfo(set, chunk); return AllocChunkGetPointer(chunk); } @@ -822,8 +808,6 @@ AllocSetAlloc(MemoryContext context, Size size) randomize_mem((char *) AllocChunkGetPointer(chunk), size); #endif - set->isReset = false; - AllocAllocInfo(set, chunk); return AllocChunkGetPointer(chunk); } @@ -922,9 +906,6 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) set->header.name, chunk); #endif - /* isReset must be false already */ - Assert(!set->isReset); - /* * Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the * allocated area already is >= the new size. (In particular, we always @@ -1059,15 +1040,13 @@ AllocSetGetChunkSpace(MemoryContext context, void *pointer) static bool AllocSetIsEmpty(MemoryContext context) { - AllocSet set = (AllocSet) context; - /* * For now, we say "empty" only if the context is new or just reset. We * could examine the freelists to determine if all space has been freed, * but it's not really worth the trouble for present uses of this * functionality. */ - if (set->isReset) + if (context->isReset) return true; return false; } diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index 8783edf026..980cce518c 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -127,7 +127,12 @@ MemoryContextReset(MemoryContext context) if (context->firstchild != NULL) MemoryContextResetChildren(context); - (*context->methods->reset) (context); + /* Nothing to do if no pallocs since startup or last reset */ + if (!context->isReset) + { + (*context->methods->reset) (context); + context->isReset = true; + } } /* @@ -476,6 +481,7 @@ MemoryContextCreate(NodeTag tag, Size size, node->parent = NULL; /* for the moment */ node->firstchild = NULL; node->nextchild = NULL; + node->isReset = true; node->name = ((char *) node) + size; strcpy(node->name, name); @@ -504,13 +510,16 @@ MemoryContextCreate(NodeTag tag, Size size, void * MemoryContextAlloc(MemoryContext context, Size size) { + void *ret; AssertArg(MemoryContextIsValid(context)); if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); - return (*context->methods->alloc) (context, size); + ret = (*context->methods->alloc) (context, size); + context->isReset = false; + return ret; } /* @@ -535,6 +544,7 @@ MemoryContextAllocZero(MemoryContext context, Size size) MemSetAligned(ret, 0, size); + context->isReset = false; return ret; } @@ -560,6 +570,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size) MemSetLoop(ret, 0, size); + context->isReset = false; return ret; } @@ -620,6 +631,9 @@ repalloc(void *pointer, Size size) elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); + /* isReset must be false already */ + Assert(!header->context->isReset); + return (*header->context->methods->realloc) (header->context, pointer, size); } diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h index b62ed8f904..62a0f9730e 100644 --- a/src/include/nodes/memnodes.h +++ b/src/include/nodes/memnodes.h @@ -59,6 +59,7 @@ typedef struct MemoryContextData MemoryContext firstchild; /* head of linked list of children */ MemoryContext nextchild; /* next child of same parent */ char *name; /* context name (just for debugging) */ + bool isReset; /* T = no space alloced since last reset */ } MemoryContextData; /* utils/palloc.h contains typedef struct MemoryContextData *MemoryContext */