diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index 2fe36c7505b..693c68c3a81 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -166,6 +166,7 @@ typedef struct AllocSetContext uint32 maxBlockSize; /* maximum block size */ uint32 nextBlockSize; /* next block size to allocate */ uint32 allocChunkLimit; /* effective chunk size limit */ + uint32 expectedChunkLimit; /* debug only: limit for current maxBlockSize */ /* freelist this context could be put in, or -1 if not a candidate: */ int freeListIndex; /* index in context_freelists[], or -1 */ } AllocSetContext; @@ -412,6 +413,20 @@ AllocSetContextCreateInternal(MemoryContext parent, freelist->first_free = (AllocSet) set->header.nextchild; freelist->num_free--; + if (set->maxBlockSize != maxBlockSize) + { + Size expectedChunkLimit = ALLOC_CHUNK_LIMIT; + + while (expectedChunkLimit + ALLOC_CHUNKHDRSZ > + (maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION) + expectedChunkLimit >>= 1; + set->expectedChunkLimit = expectedChunkLimit; + + elog(LOG, "EVAN: recycling AllocSet context \"%s\": maxBlockSize %zu -> %zu, allocChunkLimit retained %zu, expected %zu", + name, (Size) set->maxBlockSize, maxBlockSize, + (Size) set->allocChunkLimit, expectedChunkLimit); + } + /* Update its maxBlockSize; everything else should be OK */ set->maxBlockSize = maxBlockSize; @@ -517,6 +532,7 @@ AllocSetContextCreateInternal(MemoryContext parent, while ((Size) (set->allocChunkLimit + ALLOC_CHUNKHDRSZ) > (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION)) set->allocChunkLimit >>= 1; + set->expectedChunkLimit = set->allocChunkLimit; /* Finally, do the type-independent part of context creation */ MemoryContextCreate((MemoryContext) set, @@ -1028,7 +1044,19 @@ AllocSetAlloc(MemoryContext context, Size size, int flags) * AllocSetAllocLarge(). */ if (size > set->allocChunkLimit) + { + if (size <= set->expectedChunkLimit) + elog(LOG, "EVAN: AllocSet context \"%s\": allocation size %zu wrongly takes malloc path; allocChunkLimit retained %zu, expected %zu", + set->header.name, size, (Size) set->allocChunkLimit, + (Size) set->expectedChunkLimit); + return AllocSetAllocLarge(context, size, flags); + } + + if (size > set->expectedChunkLimit) + elog(LOG, "EVAN: AllocSet context \"%s\": allocation size %zu wrongly takes pooled chunk path; allocChunkLimit retained %zu, expected %zu", + set->header.name, size, (Size) set->allocChunkLimit, + (Size) set->expectedChunkLimit); /* * Request is small enough to be treated as a chunk. Look in the