v0-0001-Add-bitspace-for-more-memory-context-types-in-Mem.patch.txt
text/plain
Filename: v0-0001-Add-bitspace-for-more-memory-context-types-in-Mem.patch.txt
Type: text/plain
Part: 0
From 4c0b4b1af98fcfecf80a30ea1834668b59d543a5 Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
Date: Thu, 4 Apr 2024 21:34:46 +0200
Subject: [PATCH v0] Add bitspace for more memory context types in
MemoryChunk's hdrmask
Assuming we don't want to use patterns from unused memory, common
glibc malloc patterns, and wipe_mem-ed memory, we now have 18 new IDs
to work with again, from 0.
In passing, simplify/clean up initialization of unused memory contexts
in the mcxt_methods array.
Inspiration: https://postgr.es/m/CAApHDvqGSpCU95TmM%3DBp%3D6xjL_nLys4zdZOpfNyWBk97Xrdj2w%40mail.gmail.com
---
src/backend/utils/mmgr/mcxt.c | 55 +++++++++++++++---------
src/include/utils/memutils_internal.h | 35 ++++++++++++---
src/include/utils/memutils_memorychunk.h | 15 ++++---
3 files changed, 73 insertions(+), 32 deletions(-)
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 5d426795d9..9373f782ce 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -102,26 +102,41 @@ static const MemoryContextMethods mcxt_methods[] = {
* seems sufficient to provide routines for the methods that might get
* invoked from inspection of a chunk (see MCXT_METHOD calls below).
*/
-
- [MCTX_UNUSED1_ID].free_p = BogusFree,
- [MCTX_UNUSED1_ID].realloc = BogusRealloc,
- [MCTX_UNUSED1_ID].get_chunk_context = BogusGetChunkContext,
- [MCTX_UNUSED1_ID].get_chunk_space = BogusGetChunkSpace,
-
- [MCTX_UNUSED2_ID].free_p = BogusFree,
- [MCTX_UNUSED2_ID].realloc = BogusRealloc,
- [MCTX_UNUSED2_ID].get_chunk_context = BogusGetChunkContext,
- [MCTX_UNUSED2_ID].get_chunk_space = BogusGetChunkSpace,
-
- [MCTX_UNUSED3_ID].free_p = BogusFree,
- [MCTX_UNUSED3_ID].realloc = BogusRealloc,
- [MCTX_UNUSED3_ID].get_chunk_context = BogusGetChunkContext,
- [MCTX_UNUSED3_ID].get_chunk_space = BogusGetChunkSpace,
-
- [MCTX_UNUSED4_ID].free_p = BogusFree,
- [MCTX_UNUSED4_ID].realloc = BogusRealloc,
- [MCTX_UNUSED4_ID].get_chunk_context = BogusGetChunkContext,
- [MCTX_UNUSED4_ID].get_chunk_space = BogusGetChunkSpace,
+#define BOGUS_MCTX(id) \
+ [id].free_p = BogusFree, \
+ [id].realloc = BogusRealloc, \
+ [id].get_chunk_context = BogusGetChunkContext, \
+ [id].get_chunk_space = BogusGetChunkSpace
+
+ BOGUS_MCTX(MCTX_UNUSED1_ID),
+ BOGUS_MCTX(MCTX_UNUSED2_ID),
+ BOGUS_MCTX(MCTX_UNUSED3_ID),
+ BOGUS_MCTX(MCTX_UNUSED4_ID),
+ BOGUS_MCTX(MCTX_UNUSED5_ID),
+ BOGUS_MCTX(MCTX_UNUSED6_ID),
+ BOGUS_MCTX(MCTX_UNUSED7_ID),
+ BOGUS_MCTX(MCTX_UNUSED8_ID),
+ BOGUS_MCTX(MCTX_UNUSED9_ID),
+ BOGUS_MCTX(MCTX_UNUSED10_ID),
+ BOGUS_MCTX(MCTX_UNUSED11_ID),
+ BOGUS_MCTX(MCTX_UNUSED12_ID),
+ BOGUS_MCTX(MCTX_UNUSED13_ID),
+ BOGUS_MCTX(MCTX_UNUSED14_ID),
+ BOGUS_MCTX(MCTX_UNUSED15_ID),
+ BOGUS_MCTX(MCTX_UNUSED16_ID),
+ BOGUS_MCTX(MCTX_UNUSED17_ID),
+ BOGUS_MCTX(MCTX_UNUSED18_ID),
+ BOGUS_MCTX(MCTX_UNUSED19_ID),
+ BOGUS_MCTX(MCTX_UNUSED20_ID),
+ BOGUS_MCTX(MCTX_UNUSED21_ID),
+ BOGUS_MCTX(MCTX_UNUSED22_ID),
+ BOGUS_MCTX(MCTX_UNUSED23_ID),
+ BOGUS_MCTX(MCTX_UNUSED24_ID),
+ BOGUS_MCTX(MCTX_UNUSED25_ID),
+ BOGUS_MCTX(MCTX_UNUSED26_ID),
+ BOGUS_MCTX(MCTX_UNUSED27_ID),
+ BOGUS_MCTX(MCTX_UNUSED28_ID)
+#undef BOGUS_MCTX
};
/*
diff --git a/src/include/utils/memutils_internal.h b/src/include/utils/memutils_internal.h
index ad1048fd82..fbf5ecd111 100644
--- a/src/include/utils/memutils_internal.h
+++ b/src/include/utils/memutils_internal.h
@@ -104,21 +104,46 @@ extern Size AlignedAllocGetChunkSpace(void *pointer);
*/
typedef enum MemoryContextMethodID
{
- MCTX_UNUSED1_ID, /* 000 occurs in never-used memory */
- MCTX_UNUSED2_ID, /* glibc malloc'd chunks usually match 001 */
- MCTX_UNUSED3_ID, /* glibc malloc'd chunks > 128kB match 010 */
+ MCTX_UNUSED1_ID, /* 00000 occurs in never-used memory */
+ MCTX_UNUSED2_ID, /* glibc malloc'd chunks usually match XX001 */
+ MCTX_UNUSED3_ID, /* glibc malloc'd chunks > 128kB match XX010 */
MCTX_ASET_ID,
MCTX_GENERATION_ID,
MCTX_SLAB_ID,
MCTX_ALIGNED_REDIRECT_ID,
- MCTX_UNUSED4_ID, /* 111 occurs in wipe_mem'd memory */
+ MCTX_UNUSED4_ID, /* 00111 */
+ MCTX_UNUSED5_ID, /* 01000 */
+ MCTX_UNUSED6_ID, /* glibc malloc'd chunks usually match XX001 */
+ MCTX_UNUSED7_ID, /* glibc malloc'd chunks > 128kB match XX010 */
+ MCTX_UNUSED8_ID, /* 01011 */
+ MCTX_UNUSED9_ID, /* 01100 */
+ MCTX_UNUSED10_ID, /* 01101 */
+ MCTX_UNUSED11_ID, /* 01110 */
+ MCTX_UNUSED12_ID, /* 01111 */
+ MCTX_UNUSED13_ID, /* 10000 */
+ MCTX_UNUSED14_ID, /* glibc malloc'd chunks usually match XX001 */
+ MCTX_UNUSED15_ID, /* glibc malloc'd chunks > 128kB match XX010 */
+ MCTX_UNUSED16_ID, /* 10011 */
+ MCTX_UNUSED17_ID, /* 10100 */
+ MCTX_UNUSED18_ID, /* 10101 */
+ MCTX_UNUSED19_ID, /* 10110 */
+ MCTX_UNUSED20_ID, /* 10111 */
+ MCTX_UNUSED21_ID, /* 11000 */
+ MCTX_UNUSED22_ID, /* glibc malloc'd chunks usually match XX001 */
+ MCTX_UNUSED23_ID, /* glibc malloc'd chunks > 128kB match XX010 */
+ MCTX_UNUSED24_ID, /* 11011 */
+ MCTX_UNUSED25_ID, /* 11100 */
+ MCTX_UNUSED26_ID, /* 11101 */
+ MCTX_UNUSED27_ID, /* 11110 */
+ MCTX_UNUSED28_ID /* 11111 occurs in wipe_mem'd memory (0x7F) */
+#define MaxMemoryContextMethodID (MCTX_UNUSED28_ID)
} MemoryContextMethodID;
/*
* The number of bits that 8-byte memory chunk headers can use to encode the
* MemoryContextMethodID.
*/
-#define MEMORY_CONTEXT_METHODID_BITS 3
+#define MEMORY_CONTEXT_METHODID_BITS 5
#define MEMORY_CONTEXT_METHODID_MASK \
((((uint64) 1) << MEMORY_CONTEXT_METHODID_BITS) - 1)
diff --git a/src/include/utils/memutils_memorychunk.h b/src/include/utils/memutils_memorychunk.h
index 38296abe1b..86ed28afab 100644
--- a/src/include/utils/memutils_memorychunk.h
+++ b/src/include/utils/memutils_memorychunk.h
@@ -25,14 +25,14 @@
* used to encode 4 separate pieces of information. Starting with the least
* significant bits of 'hdrmask', the bit space is reserved as follows:
*
- * 1. 3-bits to indicate the MemoryContextMethodID as defined by
+ * 1. 5-bits to indicate the MemoryContextMethodID as defined by
* MEMORY_CONTEXT_METHODID_MASK
* 2. 1-bit to denote an "external" chunk (see below)
* 3. 30-bits reserved for the MemoryContext to use for anything it
* requires. Most MemoryContext likely want to store the size of the
* chunk here.
- * 4. 30-bits for the number of bytes that must be subtracted from the chunk
- * to obtain the address of the block that the chunk is stored on.
+ * 4. 28-bits for the multiple of 4 bytes that must be subtracted from the
+ * chunk to obtain the address of the block that the chunk is stored on.
*
* In some cases, for example when memory allocations become large, it's
* possible fields 3 and 4 above are not large enough to store the values
@@ -91,7 +91,7 @@
* The maximum distance in bytes that a MemoryChunk can be offset from the
* block that is storing the chunk. Must be 1 less than a power of 2.
*/
-#define MEMORYCHUNK_MAX_BLOCKOFFSET UINT64CONST(0x3FFFFFFF)
+#define MEMORYCHUNK_MAX_BLOCKOFFSET UINT64CONST(0xFFFFFFF)
/* define the least significant base-0 bit of each portion of the hdrmask */
#define MEMORYCHUNK_EXTERNAL_BASEBIT MEMORY_CONTEXT_METHODID_BITS
@@ -135,7 +135,7 @@ typedef struct MemoryChunk
* optimize out the & MEMORYCHUNK_MAX_BLOCKOFFSET.
*/
#define HdrMaskBlockOffset(hdrmask) \
- (((hdrmask) >> MEMORYCHUNK_BLOCKOFFSET_BASEBIT) & MEMORYCHUNK_MAX_BLOCKOFFSET)
+ ((((hdrmask) >> MEMORYCHUNK_BLOCKOFFSET_BASEBIT) & MEMORYCHUNK_MAX_BLOCKOFFSET) * 4)
/* For external chunks only, check the magic number matches */
#define HdrMaskCheckMagic(hdrmask) \
@@ -157,11 +157,12 @@ MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block,
Size blockoffset = (char *) chunk - (char *) block;
Assert((char *) chunk >= (char *) block);
- Assert(blockoffset <= MEMORYCHUNK_MAX_BLOCKOFFSET);
+ Assert((blockoffset % 4) == 0);
+ Assert((blockoffset / 4) <= MEMORYCHUNK_MAX_BLOCKOFFSET);
Assert(value <= MEMORYCHUNK_MAX_VALUE);
Assert((int) methodid <= MEMORY_CONTEXT_METHODID_MASK);
- chunk->hdrmask = (((uint64) blockoffset) << MEMORYCHUNK_BLOCKOFFSET_BASEBIT) |
+ chunk->hdrmask = (((uint64) (blockoffset / 4)) << MEMORYCHUNK_BLOCKOFFSET_BASEBIT) |
(((uint64) value) << MEMORYCHUNK_VALUE_BASEBIT) |
methodid;
}
--
2.40.1