From 2c666d44df2a3e8d599cafc33af1a06cc59562e3 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Tue, 4 Mar 2025 13:21:35 -0800 Subject: [PATCH] Inline MemoryContextMemAllocated(). Suggested-by: David Rowley Discussion: https://postgr.es/m/CAApHDvpN4v3t_sdz4dvrv1Fx_ZPw=twSnxuTEytRYP7LFz5K9A@mail.gmail.com --- src/backend/executor/nodeAgg.c | 8 ++-- src/backend/utils/mmgr/mcxt.c | 68 ---------------------------------- src/include/nodes/memnodes.h | 68 ++++++++++++++++++++++++++++++++++ src/include/utils/memutils.h | 1 - 4 files changed, 72 insertions(+), 73 deletions(-) diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index f83fc16c5c8e..f2c0e535b8f5 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -1868,9 +1868,9 @@ hash_agg_check_limits(AggState *aggstate) { uint64 ngroups = aggstate->hash_ngroups_current; Size meta_mem = MemoryContextMemAllocated(aggstate->hash_metacxt, - true); + false); Size entry_mem = MemoryContextMemAllocated(aggstate->hash_tablecxt, - true); + false); Size tval_mem = MemoryContextMemAllocated(aggstate->hashcontext->ecxt_per_tuple_memory, true); Size total_mem = meta_mem + entry_mem + tval_mem; @@ -1957,10 +1957,10 @@ hash_agg_update_metrics(AggState *aggstate, bool from_tape, int npartitions) return; /* memory for the hash table itself */ - meta_mem = MemoryContextMemAllocated(aggstate->hash_metacxt, true); + meta_mem = MemoryContextMemAllocated(aggstate->hash_metacxt, false); /* memory for hash entries */ - entry_mem = MemoryContextMemAllocated(aggstate->hash_tablecxt, true); + entry_mem = MemoryContextMemAllocated(aggstate->hash_tablecxt, false); /* memory for byref transition states */ hashkey_mem = MemoryContextMemAllocated(aggstate->hashcontext->ecxt_per_tuple_memory, true); diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index d98ae9db6bec..07b54d3c5bf1 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -232,50 +232,6 @@ GetMemoryChunkHeader(const void *pointer) return header; } -/* - * MemoryContextTraverseNext - * Helper function to traverse all descendants of a memory context - * without recursion. - * - * Recursion could lead to out-of-stack errors with deep context hierarchies, - * which would be unpleasant in error cleanup code paths. - * - * To process 'context' and all its descendants, use a loop like this: - * - * - * for (MemoryContext curr = context->firstchild; - * curr != NULL; - * curr = MemoryContextTraverseNext(curr, context)) - * { - * - * } - * - * This visits all the contexts in pre-order, that is a node is visited - * before its children. - */ -static MemoryContext -MemoryContextTraverseNext(MemoryContext curr, MemoryContext top) -{ - /* After processing a node, traverse to its first child if any */ - if (curr->firstchild != NULL) - return curr->firstchild; - - /* - * After processing a childless node, traverse to its next sibling if - * there is one. If there isn't, traverse back up to the parent (which - * has already been visited, and now so have all its descendants). We're - * done if that is "top", otherwise traverse to its next sibling if any, - * otherwise repeat moving up. - */ - while (curr->nextchild == NULL) - { - curr = curr->parent; - if (curr == top) - return NULL; - } - return curr->nextchild; -} - /* * Support routines to trap use of invalid memory context method IDs * (from calling pfree or the like on a bogus pointer). As a possible @@ -754,30 +710,6 @@ MemoryContextIsEmpty(MemoryContext context) return context->methods->is_empty(context); } -/* - * Find the memory allocated to blocks for this memory context. If recurse is - * true, also include children. - */ -Size -MemoryContextMemAllocated(MemoryContext context, bool recurse) -{ - Size total = context->mem_allocated; - - Assert(MemoryContextIsValid(context)); - - if (recurse) - { - for (MemoryContext curr = context->firstchild; - curr != NULL; - curr = MemoryContextTraverseNext(curr, context)) - { - total += curr->mem_allocated; - } - } - - return total; -} - /* * Return the memory consumption statistics about the given context and its * children. diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h index 5807ef805bd8..969b4d6ef33f 100644 --- a/src/include/nodes/memnodes.h +++ b/src/include/nodes/memnodes.h @@ -149,4 +149,72 @@ typedef struct MemoryContextData IsA((context), GenerationContext) || \ IsA((context), BumpContext))) +/* + * MemoryContextTraverseNext + * Helper function to traverse all descendants of a memory context + * without recursion. + * + * Recursion could lead to out-of-stack errors with deep context hierarchies, + * which would be unpleasant in error cleanup code paths. + * + * To process 'context' and all its descendants, use a loop like this: + * + * + * for (MemoryContext curr = context->firstchild; + * curr != NULL; + * curr = MemoryContextTraverseNext(curr, context)) + * { + * + * } + * + * This visits all the contexts in pre-order, that is a node is visited + * before its children. + */ +static inline MemoryContext +MemoryContextTraverseNext(MemoryContext curr, MemoryContext top) +{ + /* After processing a node, traverse to its first child if any */ + if (curr->firstchild != NULL) + return curr->firstchild; + + /* + * After processing a childless node, traverse to its next sibling if + * there is one. If there isn't, traverse back up to the parent (which + * has already been visited, and now so have all its descendants). We're + * done if that is "top", otherwise traverse to its next sibling if any, + * otherwise repeat moving up. + */ + while (curr->nextchild == NULL) + { + curr = curr->parent; + if (curr == top) + return NULL; + } + return curr->nextchild; +} + +/* + * Find the memory allocated to blocks for this memory context. If recurse is + * true, also include children. + */ +static inline Size +MemoryContextMemAllocated(MemoryContext context, bool recurse) +{ + Size total = context->mem_allocated; + + Assert(MemoryContextIsValid(context)); + + if (recurse) + { + for (MemoryContext curr = context->firstchild; + curr != NULL; + curr = MemoryContextTraverseNext(curr, context)) + { + total += curr->mem_allocated; + } + } + + return total; +} + #endif /* MEMNODES_H */ diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index 8abc26abce27..4f153d0e0679 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -83,7 +83,6 @@ extern MemoryContext GetMemoryChunkContext(void *pointer); extern Size GetMemoryChunkSpace(void *pointer); extern MemoryContext MemoryContextGetParent(MemoryContext context); extern bool MemoryContextIsEmpty(MemoryContext context); -extern Size MemoryContextMemAllocated(MemoryContext context, bool recurse); extern void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed); extern void MemoryContextStats(MemoryContext context);