diff -r 68b8827f4738 src/backend/utils/mmgr/aset.c --- a/src/backend/utils/mmgr/aset.c Fri Nov 13 11:17:04 2009 +0000 +++ b/src/backend/utils/mmgr/aset.c Wed Dec 09 14:41:34 2009 +0100 @@ -64,6 +64,7 @@ #include "postgres.h" +#include "pg_trace.h" #include "utils/memutils.h" /* Define this to detail debug alloc information */ @@ -463,6 +464,8 @@ AssertArg(AllocSetIsValid(set)); + TRACE_POSTGRESQL_ASET_RESET(context); + /* Nothing to do if no pallocs since startup or last reset */ if (set->isReset) return; @@ -495,6 +498,8 @@ #endif block->freeptr = datastart; block->next = NULL; + TRACE_POSTGRESQL_ASET_BLOCK_RESET(context, block, + block->endptr - ((char *) block)); } else { @@ -503,6 +508,8 @@ /* Wipe freed memory for debugging purposes */ memset(block, 0x7F, block->freeptr - ((char *) block)); #endif + TRACE_POSTGRESQL_ASET_BLOCK_FREE(context, block, + block->endptr - ((char *) block)); free(block); } block = next; @@ -529,6 +536,7 @@ AllocBlock block = set->blocks; AssertArg(AllocSetIsValid(set)); + TRACE_POSTGRESQL_ASET_DELETE(context); #ifdef MEMORY_CONTEXT_CHECKING /* Check for corruption and leaks before freeing */ @@ -548,6 +556,8 @@ /* Wipe freed memory for debugging purposes */ memset(block, 0x7F, block->freeptr - ((char *) block)); #endif + TRACE_POSTGRESQL_ASET_BLOCK_FREE(context, block, + block->endptr - ((char *) block)); free(block); block = next; } @@ -570,6 +580,7 @@ AssertArg(AllocSetIsValid(set)); + TRACE_POSTGRESQL_ASET_ALLOC(context, size); /* * If requested size exceeds maximum for chunks, allocate an entire block * for this request. @@ -623,6 +634,7 @@ set->isReset = false; AllocAllocInfo(set, chunk); + TRACE_POSTGRESQL_ASET_BLOCK_NEW(context, block, blksize); return AllocChunkGetPointer(chunk); } @@ -771,6 +783,7 @@ errdetail("Failed on request of size %lu.", (unsigned long) size))); } + TRACE_POSTGRESQL_ASET_BLOCK_NEW(context, block, blksize); block->aset = set; block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ; @@ -830,6 +843,7 @@ AllocChunk chunk = AllocPointerGetChunk(pointer); AllocFreeInfo(set, chunk); + TRACE_POSTGRESQL_ASET_FREE(context, pointer); #ifdef MEMORY_CONTEXT_CHECKING /* Test for someone scribbling on unused space in chunk */ @@ -866,6 +880,9 @@ set->blocks = block->next; else prevblock->next = block->next; + + TRACE_POSTGRESQL_ASET_BLOCK_FREE(context, block, + block->endptr - ((char *) block)); #ifdef CLOBBER_FREED_MEMORY /* Wipe freed memory for debugging purposes */ memset(block, 0x7F, block->freeptr - ((char *) block)); @@ -905,6 +922,8 @@ AllocChunk chunk = AllocPointerGetChunk(pointer); Size oldsize = chunk->size; + TRACE_POSTGRESQL_ASET_REALLOC(context, pointer, size, oldsize); + #ifdef MEMORY_CONTEXT_CHECKING /* Test for someone scribbling on unused space in chunk */ if (chunk->requested_size < oldsize) @@ -948,6 +967,7 @@ */ AllocBlock block = set->blocks; AllocBlock prevblock = NULL; + AllocBlock newblock; Size chksize; Size blksize; @@ -967,7 +987,11 @@ /* Do the realloc */ chksize = MAXALIGN(size); blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ; - block = (AllocBlock) realloc(block, blksize); + newblock = (AllocBlock) realloc(block, blksize); + + TRACE_POSTGRESQL_ASET_BLOCK_REALLOC(context, block, newblock, blksize); + block = newblock; + if (block == NULL) { MemoryContextStats(TopMemoryContext); diff -r 68b8827f4738 src/backend/utils/mmgr/mcxt.c --- a/src/backend/utils/mmgr/mcxt.c Fri Nov 13 11:17:04 2009 +0000 +++ b/src/backend/utils/mmgr/mcxt.c Wed Dec 09 14:41:34 2009 +0100 @@ -22,7 +22,7 @@ #include "postgres.h" #include "utils/memutils.h" - +#include "pg_trace.h" /***************************************************************************** * GLOBAL MEMORY * @@ -123,6 +123,8 @@ { AssertArg(MemoryContextIsValid(context)); + TRACE_POSTGRESQL_MCXT_RESET(context->name, context); + /* save a function call in common case where there are no children */ if (context->firstchild != NULL) MemoryContextResetChildren(context); @@ -168,6 +170,8 @@ MemoryContextDeleteChildren(context); + TRACE_POSTGRESQL_MCXT_DELETE(context->name, context, context->parent); + /* * We delink the context from its parent before deleting it, so that if * there's an error we won't have deleted/busted contexts still attached @@ -490,6 +494,8 @@ parent->firstchild = node; } + TRACE_POSTGRESQL_MCXT_CREATE(node->name, node, parent); + /* Return to type-specific creation routine to finish up */ return node; } @@ -510,7 +516,8 @@ elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); - return (*context->methods->alloc) (context, size); +// TRACE_POSTGRESQL_MCXT_ALLOC(context, size); + return ((*context->methods->alloc) (context, size)); } /* @@ -524,6 +531,7 @@ MemoryContextAllocZero(MemoryContext context, Size size) { void *ret; + StandardChunkHeader *header; AssertArg(MemoryContextIsValid(context)); @@ -531,7 +539,12 @@ elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); + ret = (*context->methods->alloc) (context, size); + header = (StandardChunkHeader *) + ((char *) ret - STANDARDCHUNKHEADERSIZE); + +// TRACE_POSTGRESQL_MCXT_ALLOC(context->name, context, size, header->size, true); MemSetAligned(ret, 0, size); @@ -549,6 +562,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size) { void *ret; + StandardChunkHeader *header; AssertArg(MemoryContextIsValid(context)); @@ -558,6 +572,11 @@ ret = (*context->methods->alloc) (context, size); + header = (StandardChunkHeader *) + ((char *) ret - STANDARDCHUNKHEADERSIZE); + +// TRACE_POSTGRESQL_MCXT_ALLOC(context->name, context, size, header->size, true); + MemSetLoop(ret, 0, size); return ret; @@ -588,6 +607,8 @@ AssertArg(MemoryContextIsValid(header->context)); +// TRACE_POSTGRESQL_MCXT_FREE(header->context, pointer); + (*header->context->methods->free_p) (header->context, pointer); } @@ -620,6 +641,8 @@ elog(ERROR, "invalid memory alloc request size %lu", (unsigned long) size); + TRACE_POSTGRESQL_MCXT_REALLOC(header->context->name, header->context, header->size, size); + return (*header->context->methods->realloc) (header->context, pointer, size); } diff -r 68b8827f4738 src/backend/utils/probes.d --- a/src/backend/utils/probes.d Fri Nov 13 11:17:04 2009 +0000 +++ b/src/backend/utils/probes.d Wed Dec 09 14:41:34 2009 +0100 @@ -90,4 +90,21 @@ probe xlog__switch(); probe wal__buffer__write__dirty__start(); probe wal__buffer__write__dirty__done(); + + probe mcxt__create(char *, void *, void *); + probe mcxt__delete(char *, void *, void *); +/* probe mcxt__alloc(void *, size_t); + probe mcxt__free(void *, void *); */ + probe mcxt__reset(char *, void *); + probe mcxt__realloc(char *, void *, size_t, size_t); + + probe aset__delete(void *); + probe aset__reset(void *); + probe aset__alloc(void *, size_t); + probe aset__realloc(void *, void *, size_t, size_t); + probe aset__free(void *, void *); + probe aset__block__reset(void *, void *, size_t); + probe aset__block__free(void *, void *, size_t); + probe aset__block__new(void *, void *, size_t); + probe aset__block__realloc(void *, void *, void *, size_t); };