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.
This commit is contained in:
Heikki Linnakangas 2011-05-21 14:47:19 -04:00
parent 0319da638f
commit 30e98a7e6e
3 changed files with 19 additions and 25 deletions

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */