v1-0004-Demote-MemoryContextContains-to-MEMORY_CONTEXT_CH.patch

text/plain

Filename: v1-0004-Demote-MemoryContextContains-to-MEMORY_CONTEXT_CH.patch
Type: text/plain
Part: 3
Message: Re: Reducing the chunk header sizes on all memory context types

Patch

Format: format-patch
Series: patch v1-0004
Subject: Demote MemoryContextContains to MEMORY_CONTEXT_CHECKING builds only
File+
src/backend/executor/nodeAgg.c 2 4
src/backend/executor/nodeWindowAgg.c 1 2
src/backend/utils/mmgr/aset.c 2 0
src/backend/utils/mmgr/generation.c 3 0
src/backend/utils/mmgr/mcxt.c 6 4
src/backend/utils/mmgr/slab.c 2 0
src/include/nodes/memnodes.h 1 1
src/include/utils/memutils.h 1 1
src/include/utils/memutils_internal.h 3 3
From 28f287cdd32f4d3bdde0fd803c9357646e904a17 Mon Sep 17 00:00:00 2001
From: David Rowley <dgrowley@gmail.com>
Date: Fri, 9 Sep 2022 16:19:13 +1200
Subject: [PATCH v1 4/4] Demote MemoryContextContains to
 MEMORY_CONTEXT_CHECKING builds only

Making MemoryContextContains work like it did prior to c6e0fe1f2 required
making it perform a loop over each block that the MemoryContext had
allocated and check if the pointer is in the address-space range of that
block.  This was far too expensive to be used as a general-purpose
function.

Here we instead opt to use GetMemoryChunkContext().  Previously we
couldn't use that function as it only works when given a pointer as it was
returned by palloc and co.  For some use cases of MemoryContextContains
they could receive a pointer into a tuple (as was the case for lead/lag
window functions, and a pointer to a field in an internal aggregate state,
as was the case for int2int4_sum().
---
 src/backend/executor/nodeAgg.c        |  6 ++----
 src/backend/executor/nodeWindowAgg.c  |  3 +--
 src/backend/utils/mmgr/aset.c         |  2 ++
 src/backend/utils/mmgr/generation.c   |  3 +++
 src/backend/utils/mmgr/mcxt.c         | 10 ++++++----
 src/backend/utils/mmgr/slab.c         |  2 ++
 src/include/nodes/memnodes.h          |  2 +-
 src/include/utils/memutils.h          |  2 +-
 src/include/utils/memutils_internal.h |  6 +++---
 9 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 933c304901..323ae94938 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1122,8 +1122,7 @@ finalize_aggregate(AggState *aggstate,
 	 * If result is pass-by-ref, make sure it is in the right context.
 	 */
 	if (!peragg->resulttypeByVal && !*resultIsNull &&
-		!MemoryContextContains(CurrentMemoryContext,
-							   DatumGetPointer(*resultVal)))
+		GetMemoryChunkContext(DatumGetPointer(*resultVal)) != CurrentMemoryContext)
 		*resultVal = datumCopy(*resultVal,
 							   peragg->resulttypeByVal,
 							   peragg->resulttypeLen);
@@ -1184,8 +1183,7 @@ finalize_partialaggregate(AggState *aggstate,
 
 	/* If result is pass-by-ref, make sure it is in the right context. */
 	if (!peragg->resulttypeByVal && !*resultIsNull &&
-		!MemoryContextContains(CurrentMemoryContext,
-							   DatumGetPointer(*resultVal)))
+		GetMemoryChunkContext(DatumGetPointer(*resultVal)) != CurrentMemoryContext)
 		*resultVal = datumCopy(*resultVal,
 							   peragg->resulttypeByVal,
 							   peragg->resulttypeLen);
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index ba119046f4..2820044cd0 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -639,8 +639,7 @@ finalize_windowaggregate(WindowAggState *winstate,
 	 * If result is pass-by-ref, make sure it is in the right context.
 	 */
 	if (!peraggstate->resulttypeByVal && !*isnull &&
-		!MemoryContextContains(CurrentMemoryContext,
-							   DatumGetPointer(*result)))
+		GetMemoryChunkContext(DatumGetPointer(*result)) != CurrentMemoryContext)
 		*result = datumCopy(*result,
 							peraggstate->resulttypeByVal,
 							peraggstate->resulttypeLen);
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index b435624d8f..3a6f12be32 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -1333,6 +1333,7 @@ AllocSetGetChunkContext(void *pointer)
 	return &set->header;
 }
 
+#ifdef MEMORY_CONTEXT_CHECKING
 /*
  * AllocSetContains
  *		Attempt to determine if 'pointer' is memory which was allocated by
@@ -1374,6 +1375,7 @@ AllocSetContains(MemoryContext context, void *pointer)
 	}
 	return false;
 }
+#endif							/* MEMORY_CONTEXT_CHECKING */
 
 /*
  * AllocSetGetChunkSpace
diff --git a/src/backend/utils/mmgr/generation.c b/src/backend/utils/mmgr/generation.c
index f6a3a01912..9c0d04de08 100644
--- a/src/backend/utils/mmgr/generation.c
+++ b/src/backend/utils/mmgr/generation.c
@@ -848,6 +848,8 @@ GenerationGetChunkContext(void *pointer)
 	return &block->context->header;
 }
 
+
+#ifdef MEMORY_CONTEXT_CHECKING
 /*
  * GenerationContains
  *		Attempt to determine if 'pointer' is memory which was allocated by
@@ -892,6 +894,7 @@ GenerationContains(MemoryContext context, void *pointer)
 	}
 	return false;
 }
+#endif							/* MEMORY_CONTEXT_CHECKING */
 
 /*
  * GenerationGetChunkSpace
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index 3615a83d53..1097c1129c 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -44,12 +44,12 @@ static const MemoryContextMethods mcxt_methods[] = {
 	[MCTX_ASET_ID].reset = AllocSetReset,
 	[MCTX_ASET_ID].delete_context = AllocSetDelete,
 	[MCTX_ASET_ID].get_chunk_context = AllocSetGetChunkContext,
-	[MCTX_ASET_ID].contains = AllocSetContains,
 	[MCTX_ASET_ID].get_chunk_space = AllocSetGetChunkSpace,
 	[MCTX_ASET_ID].is_empty = AllocSetIsEmpty,
 	[MCTX_ASET_ID].stats = AllocSetStats,
 #ifdef MEMORY_CONTEXT_CHECKING
 	[MCTX_ASET_ID].check = AllocSetCheck,
+	[MCTX_ASET_ID].contains = AllocSetContains,
 #endif
 
 	/* generation.c */
@@ -59,12 +59,12 @@ static const MemoryContextMethods mcxt_methods[] = {
 	[MCTX_GENERATION_ID].reset = GenerationReset,
 	[MCTX_GENERATION_ID].delete_context = GenerationDelete,
 	[MCTX_GENERATION_ID].get_chunk_context = GenerationGetChunkContext,
-	[MCTX_GENERATION_ID].contains = GenerationContains,
 	[MCTX_GENERATION_ID].get_chunk_space = GenerationGetChunkSpace,
 	[MCTX_GENERATION_ID].is_empty = GenerationIsEmpty,
 	[MCTX_GENERATION_ID].stats = GenerationStats,
 #ifdef MEMORY_CONTEXT_CHECKING
 	[MCTX_GENERATION_ID].check = GenerationCheck,
+	[MCTX_GENERATION_ID].contains = GenerationContains,
 #endif
 
 	/* slab.c */
@@ -74,12 +74,12 @@ static const MemoryContextMethods mcxt_methods[] = {
 	[MCTX_SLAB_ID].reset = SlabReset,
 	[MCTX_SLAB_ID].delete_context = SlabDelete,
 	[MCTX_SLAB_ID].get_chunk_context = SlabGetChunkContext,
-	[MCTX_SLAB_ID].contains = SlabContains,
 	[MCTX_SLAB_ID].get_chunk_space = SlabGetChunkSpace,
 	[MCTX_SLAB_ID].is_empty = SlabIsEmpty,
 	[MCTX_SLAB_ID].stats = SlabStats
 #ifdef MEMORY_CONTEXT_CHECKING
-	,[MCTX_SLAB_ID].check = SlabCheck
+	,[MCTX_SLAB_ID].check = SlabCheck,
+	[MCTX_SLAB_ID].contains = SlabContains
 #endif
 };
 
@@ -816,6 +816,7 @@ MemoryContextCheck(MemoryContext context)
 }
 #endif
 
+#ifdef MEMORY_CONTEXT_CHECKING
 /*
  * MemoryContextContains
  *		Detect whether an allocated chunk of memory belongs to a given
@@ -843,6 +844,7 @@ MemoryContextContains(MemoryContext context, void *pointer)
 
 	return context->methods->contains(context, pointer);
 }
+#endif							/* MEMORY_CONTEXT_CHECKING */
 
 /*
  * MemoryContextCreate
diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c
index b5c801eb01..e46f3611ac 100644
--- a/src/backend/utils/mmgr/slab.c
+++ b/src/backend/utils/mmgr/slab.c
@@ -567,6 +567,7 @@ SlabGetChunkContext(void *pointer)
 	return &slab->header;
 }
 
+#ifdef MEMORY_CONTEXT_CHECKING
 /*
  * SlabContains
  *		Attempt to determine if 'pointer' is memory which was allocated by
@@ -610,6 +611,7 @@ SlabContains(MemoryContext context, void *pointer)
 	}
 	return false;
 }
+#endif							/* MEMORY_CONTEXT_CHECKING */
 
 /*
  * SlabGetChunkSpace
diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h
index 6a8d4f4e4e..6929cc8739 100644
--- a/src/include/nodes/memnodes.h
+++ b/src/include/nodes/memnodes.h
@@ -64,7 +64,6 @@ typedef struct MemoryContextMethods
 	void		(*reset) (MemoryContext context);
 	void		(*delete_context) (MemoryContext context);
 	MemoryContext (*get_chunk_context) (void *pointer);
-	bool		(*contains) (MemoryContext context, void *pointer);
 	Size		(*get_chunk_space) (void *pointer);
 	bool		(*is_empty) (MemoryContext context);
 	void		(*stats) (MemoryContext context,
@@ -73,6 +72,7 @@ typedef struct MemoryContextMethods
 						  bool print_to_stderr);
 #ifdef MEMORY_CONTEXT_CHECKING
 	void		(*check) (MemoryContext context);
+	bool		(*contains) (MemoryContext context, void *pointer);
 #endif
 } MemoryContextMethods;
 
diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h
index 52bc41ec53..d7144d7307 100644
--- a/src/include/utils/memutils.h
+++ b/src/include/utils/memutils.h
@@ -95,8 +95,8 @@ extern void MemoryContextAllowInCriticalSection(MemoryContext context,
 
 #ifdef MEMORY_CONTEXT_CHECKING
 extern void MemoryContextCheck(MemoryContext context);
-#endif
 extern bool MemoryContextContains(MemoryContext context, void *pointer);
+#endif
 
 /* Handy macro for copying and assigning context ID ... but note double eval */
 #define MemoryContextCopyAndSetIdentifier(cxt, id) \
diff --git a/src/include/utils/memutils_internal.h b/src/include/utils/memutils_internal.h
index ebc1d60393..b767982896 100644
--- a/src/include/utils/memutils_internal.h
+++ b/src/include/utils/memutils_internal.h
@@ -25,7 +25,6 @@ extern void *AllocSetRealloc(void *pointer, Size size);
 extern void AllocSetReset(MemoryContext context);
 extern void AllocSetDelete(MemoryContext context);
 extern MemoryContext AllocSetGetChunkContext(void *pointer);
-extern bool AllocSetContains(MemoryContext context, void *pointer);
 extern Size AllocSetGetChunkSpace(void *pointer);
 extern bool AllocSetIsEmpty(MemoryContext context);
 extern void AllocSetStats(MemoryContext context,
@@ -34,6 +33,7 @@ extern void AllocSetStats(MemoryContext context,
 						  bool print_to_stderr);
 #ifdef MEMORY_CONTEXT_CHECKING
 extern void AllocSetCheck(MemoryContext context);
+extern bool AllocSetContains(MemoryContext context, void *pointer);
 #endif
 
 /* These functions implement the MemoryContext API for Generation context. */
@@ -43,7 +43,6 @@ extern void *GenerationRealloc(void *pointer, Size size);
 extern void GenerationReset(MemoryContext context);
 extern void GenerationDelete(MemoryContext context);
 extern MemoryContext GenerationGetChunkContext(void *pointer);
-extern bool GenerationContains(MemoryContext context, void *pointer);
 extern Size GenerationGetChunkSpace(void *pointer);
 extern bool GenerationIsEmpty(MemoryContext context);
 extern void GenerationStats(MemoryContext context,
@@ -52,6 +51,7 @@ extern void GenerationStats(MemoryContext context,
 							bool print_to_stderr);
 #ifdef MEMORY_CONTEXT_CHECKING
 extern void GenerationCheck(MemoryContext context);
+extern bool GenerationContains(MemoryContext context, void *pointer);
 #endif
 
 
@@ -62,7 +62,6 @@ extern void *SlabRealloc(void *pointer, Size size);
 extern void SlabReset(MemoryContext context);
 extern void SlabDelete(MemoryContext context);
 extern MemoryContext SlabGetChunkContext(void *pointer);
-extern bool SlabContains(MemoryContext context, void *pointer);
 extern Size SlabGetChunkSpace(void *pointer);
 extern bool SlabIsEmpty(MemoryContext context);
 extern void SlabStats(MemoryContext context,
@@ -71,6 +70,7 @@ extern void SlabStats(MemoryContext context,
 					  bool print_to_stderr);
 #ifdef MEMORY_CONTEXT_CHECKING
 extern void SlabCheck(MemoryContext context);
+extern bool SlabContains(MemoryContext context, void *pointer);
 #endif
 
 /*
-- 
2.34.1