0002-Modify-aset.c-to-store-the-chunk-size-in-the-hdr.patch.txt

text/plain

Filename: 0002-Modify-aset.c-to-store-the-chunk-size-in-the-hdr.patch.txt
Type: text/plain
Part: 0
Message: Re: Add bump memory context type and use it for tuplesorts
From 3980d35a11d7f27d18c57586a7f7539d86dafae3 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Tue, 26 Mar 2024 00:06:55 +1300
Subject: [PATCH 2/2] Modify aset.c to store the chunk size in the hdr

---
 src/backend/utils/mmgr/aset.c | 51 +++++++++++++----------------------
 1 file changed, 19 insertions(+), 32 deletions(-)

diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index c683e2a928..27006662c4 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -772,7 +772,7 @@ AllocSetAllocLarge(MemoryContext context, Size size, int flags)
  */
 static inline void *
 AllocSetAllocChunkFromBlock(MemoryContext context, AllocBlock block,
-							Size size, Size chunk_size, int fidx)
+							Size size, Size chunk_size)
 {
 	MemoryChunk *chunk;
 
@@ -785,7 +785,7 @@ AllocSetAllocChunkFromBlock(MemoryContext context, AllocBlock block,
 	Assert(block->freeptr <= block->endptr);
 
 	/* store the free list index in the value field */
-	MemoryChunkSetHdrMask(chunk, block, fidx, MCTX_ASET_ID);
+	MemoryChunkSetHdrMask(chunk, block, chunk_size, MCTX_ASET_ID);
 
 #ifdef MEMORY_CONTEXT_CHECKING
 	chunk->requested_size = size;
@@ -817,14 +817,13 @@ AllocSetAllocChunkFromBlock(MemoryContext context, AllocBlock block,
 pg_noinline
 static void *
 AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
-						  int fidx)
+						  Size chunk_size)
 {
 	AllocSet	set = (AllocSet) context;
 	AllocBlock	block;
 	Size		availspace;
 	Size		blksize;
 	Size		required_size;
-	Size		chunk_size;
 
 	/* due to the keeper block set->blocks should always be valid */
 	Assert(set->blocks != NULL);
@@ -869,7 +868,7 @@ AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
 		availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
 
 		/* store the freelist index in the value field */
-		MemoryChunkSetHdrMask(chunk, block, a_fidx, MCTX_ASET_ID);
+		MemoryChunkSetHdrMask(chunk, block, availchunk, MCTX_ASET_ID);
 #ifdef MEMORY_CONTEXT_CHECKING
 		chunk->requested_size = InvalidAllocSize;	/* mark it free */
 #endif
@@ -892,8 +891,6 @@ AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
 	if (set->nextBlockSize > set->maxBlockSize)
 		set->nextBlockSize = set->maxBlockSize;
 
-	/* Choose the actual chunk size to allocate */
-	chunk_size = GetChunkSizeFromFreeListIdx(fidx);
 	Assert(chunk_size >= size);
 
 	/*
@@ -938,7 +935,7 @@ AllocSetAllocFromNewBlock(MemoryContext context, Size size, int flags,
 		block->next->prev = block;
 	set->blocks = block;
 
-	return AllocSetAllocChunkFromBlock(context, block, size, chunk_size, fidx);
+	return AllocSetAllocChunkFromBlock(context, block, size, chunk_size);
 }
 
 /*
@@ -969,7 +966,9 @@ AllocSetAlloc(MemoryContext context, Size size, int flags)
 	AllocSet	set = (AllocSet) context;
 	AllocBlock	block;
 	MemoryChunk *chunk;
+#ifdef ALLOCSET_USE_FREELIST
 	int			fidx;
+#endif
 	Size		chunk_size;
 	Size		availspace;
 
@@ -985,6 +984,7 @@ AllocSetAlloc(MemoryContext context, Size size, int flags)
 	if (size > set->allocChunkLimit)
 		return AllocSetAllocLarge(context, size, flags);
 
+#ifdef ALLOCSET_USE_FREELIST
 	/*
 	 * Request is small enough to be treated as a chunk.  Look in the
 	 * corresponding free list to see if there is a free chunk we could reuse.
@@ -998,7 +998,6 @@ AllocSetAlloc(MemoryContext context, Size size, int flags)
 	 * doubling the memory requirements for such allocations.
 	 */
 	fidx = AllocSetFreeIndex(size);
-#ifdef ALLOCSET_USE_FREELIST
 	chunk = set->freelist[fidx];
 	if (chunk != NULL)
 	{
@@ -1007,7 +1006,7 @@ AllocSetAlloc(MemoryContext context, Size size, int flags)
 		/* Allow access to the chunk header. */
 		VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
 
-		Assert(fidx == MemoryChunkGetValue(chunk));
+		Assert(fidx == AllocSetFreeIndex(MemoryChunkGetValue(chunk)));
 
 		/* pop this chunk off the freelist */
 		VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
@@ -1039,7 +1038,7 @@ AllocSetAlloc(MemoryContext context, Size size, int flags)
 	/*
 	 * Choose the actual chunk size to allocate.
 	 */
-	chunk_size = GetChunkSizeFromFreeListIdx(fidx);
+	chunk_size = GetChunkSizeFromFreeListIdx(AllocSetFreeIndex(size));
 	Assert(chunk_size >= size);
 
 	block = set->blocks;
@@ -1050,10 +1049,10 @@ AllocSetAlloc(MemoryContext context, Size size, int flags)
 	 * chunk into that block.  Else must start a new one.
 	 */
 	if (unlikely(availspace < (chunk_size + ALLOC_CHUNKHDRSZ)))
-		return AllocSetAllocFromNewBlock(context, size, flags, fidx);
+		return AllocSetAllocFromNewBlock(context, size, flags, chunk_size);
 
 	/* There's enough space on the current block, so allocate from that */
-	return AllocSetAllocChunkFromBlock(context, block, size, chunk_size, fidx);
+	return AllocSetAllocChunkFromBlock(context, block, size, chunk_size);
 }
 
 /*
@@ -1113,6 +1112,7 @@ AllocSetFree(void *pointer)
 		AllocBlock	block = MemoryChunkGetBlock(chunk);
 		int			fidx;
 		AllocFreeListLink *link;
+		Size		chunk_size;
 
 		/*
 		 * In this path, for speed reasons we just Assert that the referenced
@@ -1123,13 +1123,14 @@ AllocSetFree(void *pointer)
 		Assert(AllocBlockIsValid(block));
 		set = block->aset;
 
-		fidx = MemoryChunkGetValue(chunk);
+		chunk_size = MemoryChunkGetValue(chunk);
+		fidx = AllocSetFreeIndex(chunk_size);
 		Assert(FreeListIdxIsValid(fidx));
 		link = GetFreeListLink(chunk);
 
 #ifdef MEMORY_CONTEXT_CHECKING
 		/* Test for someone scribbling on unused space in chunk */
-		if (chunk->requested_size < GetChunkSizeFromFreeListIdx(fidx))
+		if (chunk->requested_size < chunk_size)
 			if (!sentinel_ok(pointer, chunk->requested_size))
 				elog(WARNING, "detected write past chunk end in %s %p",
 					 set->header.name, chunk);
@@ -1174,7 +1175,6 @@ AllocSetRealloc(void *pointer, Size size, int flags)
 	AllocSet	set;
 	MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
 	Size		oldchksize;
-	int			fidx;
 
 	/* Allow access to the chunk header. */
 	VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
@@ -1313,9 +1313,7 @@ AllocSetRealloc(void *pointer, Size size, int flags)
 	Assert(AllocBlockIsValid(block));
 	set = block->aset;
 
-	fidx = MemoryChunkGetValue(chunk);
-	Assert(FreeListIdxIsValid(fidx));
-	oldchksize = GetChunkSizeFromFreeListIdx(fidx);
+	oldchksize = MemoryChunkGetValue(chunk);
 
 #ifdef MEMORY_CONTEXT_CHECKING
 	/* Test for someone scribbling on unused space in chunk */
@@ -1464,7 +1462,6 @@ Size
 AllocSetGetChunkSpace(void *pointer)
 {
 	MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
-	int			fidx;
 
 	/* Allow access to the chunk header. */
 	VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
@@ -1481,13 +1478,10 @@ AllocSetGetChunkSpace(void *pointer)
 		return block->endptr - (char *) chunk;
 	}
 
-	fidx = MemoryChunkGetValue(chunk);
-	Assert(FreeListIdxIsValid(fidx));
-
 	/* Disallow access to the chunk header. */
 	VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
 
-	return GetChunkSizeFromFreeListIdx(fidx) + ALLOC_CHUNKHDRSZ;
+	return MemoryChunkGetValue(chunk) + ALLOC_CHUNKHDRSZ;
 }
 
 /*
@@ -1554,7 +1548,6 @@ AllocSetStats(MemoryContext context,
 
 			/* Allow access to the chunk header. */
 			VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
-			Assert(MemoryChunkGetValue(chunk) == fidx);
 			VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
 
 			freechunks++;
@@ -1665,13 +1658,7 @@ AllocSetCheck(MemoryContext context)
 			}
 			else
 			{
-				int			fidx = MemoryChunkGetValue(chunk);
-
-				if (!FreeListIdxIsValid(fidx))
-					elog(WARNING, "problem in alloc set %s: bad chunk size for chunk %p in block %p",
-						 name, chunk, block);
-
-				chsize = GetChunkSizeFromFreeListIdx(fidx); /* aligned chunk size */
+				chsize = MemoryChunkGetValue(chunk); /* aligned chunk size */
 
 				/*
 				 * Check the stored block offset correctly references this
-- 
2.40.1.windows.1