diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index ec3e264a73..8d6d804025 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -150,11 +150,13 @@ typedef AllocSetContext *AllocSet; */ typedef struct AllocBlockData { - AllocSet aset; /* aset that owns this block */ AllocBlock prev; /* prev block in aset's blocks list, if any */ AllocBlock next; /* next block in aset's blocks list, if any */ char *freeptr; /* start of free space in this block */ char *endptr; /* end of space in this block */ +#ifdef MEMORY_CONTEXT_CHECKING + AllocSet aset; /* aset that owns this block */ +#endif } AllocBlockData; /* @@ -467,7 +469,7 @@ AllocSetContextCreateInternal(MemoryContext parent, * the context header and its block header follows that. */ set = (AllocSet) malloc(firstBlockSize); - if (set == NULL) + if (unlikely(set == NULL)) { if (TopMemoryContext) MemoryContextStats(TopMemoryContext); @@ -485,11 +487,13 @@ AllocSetContextCreateInternal(MemoryContext parent, /* Fill in the initial block's block header */ block = (AllocBlock) (((char *) set) + MAXALIGN(sizeof(AllocSetContext))); - block->aset = set; block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ; block->endptr = ((char *) set) + firstBlockSize; block->prev = NULL; block->next = NULL; +#ifdef MEMORY_CONTEXT_CHECKING + block->aset = set; +#endif /* Mark unallocated space NOACCESS; leave the block header alone. */ VALGRIND_MAKE_MEM_NOACCESS(block->freeptr, block->endptr - block->freeptr); @@ -738,17 +742,18 @@ AllocSetAlloc(MemoryContext context, Size size) chunk_size = MAXALIGN(size); blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ; block = (AllocBlock) malloc(blksize); - if (block == NULL) + if (unlikely(block == NULL)) return NULL; - context->mem_allocated += blksize; - - block->aset = set; block->freeptr = block->endptr = ((char *) block) + blksize; +#ifdef MEMORY_CONTEXT_CHECKING + block->aset = set; +#endif chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ); - chunk->aset = set; chunk->size = chunk_size; + chunk->aset = set; + #ifdef MEMORY_CONTEXT_CHECKING chunk->requested_size = size; /* set mark to catch clobber of "unused" space */ @@ -779,6 +784,8 @@ AllocSetAlloc(MemoryContext context, Size size) set->blocks = block; } + context->mem_allocated += blksize; + /* Ensure any padding bytes are marked NOACCESS. */ VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size, chunk_size - size); @@ -931,14 +938,14 @@ AllocSetAlloc(MemoryContext context, Size size) block = (AllocBlock) malloc(blksize); } - if (block == NULL) + if (unlikely(block == NULL)) return NULL; - context->mem_allocated += blksize; - - block->aset = set; block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ; block->endptr = ((char *) block) + blksize; +#ifdef MEMORY_CONTEXT_CHECKING + block->aset = set; +#endif /* Mark unallocated space NOACCESS. */ VALGRIND_MAKE_MEM_NOACCESS(block->freeptr, @@ -948,7 +955,9 @@ AllocSetAlloc(MemoryContext context, Size size) block->next = set->blocks; if (block->next) block->next->prev = block; + set->blocks = block; + context->mem_allocated += blksize; } /* @@ -964,6 +973,7 @@ AllocSetAlloc(MemoryContext context, Size size) chunk->aset = (void *) set; chunk->size = chunk_size; + #ifdef MEMORY_CONTEXT_CHECKING chunk->requested_size = size; /* set mark to catch clobber of "unused" space */ @@ -1019,8 +1029,7 @@ AllocSetFree(MemoryContext context, void *pointer) * reference the correct aset, and freeptr and endptr should point * just past the chunk. */ - if (block->aset != set || - block->freeptr != block->endptr || + if (block->freeptr != block->endptr || block->freeptr != ((char *) block) + (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ)) elog(ERROR, "could not find block containing chunk %p", chunk); @@ -1108,8 +1117,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) * reference the correct aset, and freeptr and endptr should point * just past the chunk. */ - if (block->aset != set || - block->freeptr != block->endptr || + if (block->freeptr != block->endptr || block->freeptr != ((char *) block) + (oldsize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ)) elog(ERROR, "could not find block containing chunk %p", chunk); @@ -1128,17 +1136,13 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) oldblksize = block->endptr - ((char *) block); block = (AllocBlock) realloc(block, blksize); - if (block == NULL) + if (unlikely(block == NULL)) { /* Disallow external access to private part of chunk header. */ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN); return NULL; } - /* updated separately, not to underflow when (oldblksize > blksize) */ - context->mem_allocated -= oldblksize; - context->mem_allocated += blksize; - block->freeptr = block->endptr = ((char *) block) + blksize; /* Update pointers since block has likely been moved */ @@ -1186,6 +1190,10 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize); #endif + /* updated separately, not to underflow when (oldblksize > blksize) */ + context->mem_allocated -= oldblksize; + context->mem_allocated += blksize; + /* Ensure any padding bytes are marked NOACCESS. */ VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size, chksize - size); @@ -1263,7 +1271,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) newPointer = AllocSetAlloc((MemoryContext) set, size); /* leave immediately if request was not completed */ - if (newPointer == NULL) + if (unlikely(newPointer == NULL)) { /* Disallow external access to private part of chunk header. */ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);