- Remove MemoryContextAllocZeroAligned(). It was supposed to be a
faster version of MemoryContextAllocZero(), but modern compilers turn
the MemSetLoop() into a call to memset() anyway, making it more or
less identical to MemoryContextAllocZero(). That was the only user of
MemSetTest, MemSetLoop, so remove those too, as well as palloc0fast().
- Convert newNode() to a static inline function. When this was
originally originally written, it was written as a macro because
testing showed that gcc didn't inline the size check as we
intended. Modern compiler versions do, and now that it just calls
palloc0() there is no size-check to inline anyway.
One nice effect is that the palloc0() takes one less argument than
MemoryContextAllocZeroAligned(), which saves a few instructions in the
callers of newNode().
Reviewed-by: Peter Eisentraut, Tom Lane, John Naylor, Thomas Munro
Discussion: https://www.postgresql.org/message-id/
b51f1fa7-7e6a-4ecc-936d-
90a8a1659e7c@iki.fi
makefuncs.o \
multibitmapset.o \
nodeFuncs.o \
- nodes.o \
outfuncs.o \
params.o \
print.o \
'makefuncs.c',
'multibitmapset.c',
'nodeFuncs.c',
- 'nodes.c',
'params.c',
'print.c',
'read.c',
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * nodes.c
- * support code for nodes (now that we have removed the home-brew
- * inheritance system, our support code for nodes is much simpler)
- *
- * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * src/backend/nodes/nodes.c
- *
- * HISTORY
- * Andrew Yu Oct 20, 1994 file creation
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "nodes/nodes.h"
-
-/*
- * Support for newNode() macro
- *
- * In a GCC build there is no need for the global variable newNodeMacroHolder.
- * However, we create it anyway, to support the case of a non-GCC-built
- * loadable module being loaded into a GCC-built backend.
- */
-
-Node *newNodeMacroHolder;
return ret;
}
-/*
- * MemoryContextAllocZeroAligned
- * MemoryContextAllocZero where length is suitable for MemSetLoop
- *
- * This might seem overly specialized, but it's not because newNode()
- * is so often called with compile-time-constant sizes.
- */
-void *
-MemoryContextAllocZeroAligned(MemoryContext context, Size size)
-{
- void *ret;
-
- Assert(MemoryContextIsValid(context));
- AssertNotInCriticalSection(context);
-
- if (!AllocSizeIsValid(size))
- elog(ERROR, "invalid memory alloc request size %zu", size);
-
- context->isReset = false;
-
- ret = context->methods->alloc(context, size);
- if (unlikely(ret == NULL))
- {
- MemoryContextStats(TopMemoryContext);
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory"),
- errdetail("Failed on request of size %zu in memory context \"%s\".",
- size, context->name)));
- }
-
- VALGRIND_MEMPOOL_ALLOC(context, ret, size);
-
- MemSetLoop(ret, 0, size);
-
- return ret;
-}
-
/*
* MemoryContextAllocExtended
* Allocate space within the specified context using the given flags.
} while (0)
-/*
- * MemSetTest/MemSetLoop are a variant version that allow all the tests in
- * MemSet to be done at compile time in cases where "val" and "len" are
- * constants *and* we know the "start" pointer must be word-aligned.
- * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use
- * MemSetAligned. Beware of multiple evaluations of the arguments when using
- * this approach.
- */
-#define MemSetTest(val, len) \
- ( ((len) & LONG_ALIGN_MASK) == 0 && \
- (len) <= MEMSET_LOOP_LIMIT && \
- MEMSET_LOOP_LIMIT != 0 && \
- (val) == 0 )
-
-#define MemSetLoop(start, val, len) \
- do \
- { \
- long * _start = (long *) (start); \
- long * _stop = (long *) ((char *) _start + (Size) (len)); \
- \
- while (_start < _stop) \
- *_start++ = 0; \
- } while (0)
-
/*
* Macros for range-checking float values before converting to integer.
* We must be careful here that the boundary values are expressed exactly
*
* !WARNING!: Avoid using newNode directly. You should be using the
* macro makeNode. eg. to create a Query node, use makeNode(Query)
- *
- * Note: the size argument should always be a compile-time constant, so the
- * apparent risk of multiple evaluation doesn't matter in practice.
- */
-#ifdef __GNUC__
-
-/* With GCC, we can use a compound statement within an expression */
-#define newNode(size, tag) \
-({ Node *_result; \
- AssertMacro((size) >= sizeof(Node)); /* need the tag, at least */ \
- _result = (Node *) palloc0fast(size); \
- _result->type = (tag); \
- _result; \
-})
-#else
-
-/*
- * There is no way to dereference the palloc'ed pointer to assign the
- * tag, and also return the pointer itself, so we need a holder variable.
- * Fortunately, this macro isn't recursive so we just define
- * a global variable for this purpose.
*/
-extern PGDLLIMPORT Node *newNodeMacroHolder;
+static inline Node *
+newNode(size_t size, NodeTag tag)
+{
+ Node *result;
-#define newNode(size, tag) \
-( \
- AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \
- newNodeMacroHolder = (Node *) palloc0fast(size), \
- newNodeMacroHolder->type = (tag), \
- newNodeMacroHolder \
-)
-#endif /* __GNUC__ */
+ Assert(size >= sizeof(Node)); /* need the tag, at least */
+ result = (Node *) palloc0(size);
+ result->type = tag;
+ return result;
+}
#define makeNode(_type_) ((_type_ *) newNode(sizeof(_type_),T_##_type_))
#define NodeSetTag(nodeptr,t) (((Node*)(nodeptr))->type = (t))
*/
extern void *MemoryContextAlloc(MemoryContext context, Size size);
extern void *MemoryContextAllocZero(MemoryContext context, Size size);
-extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
extern void *MemoryContextAllocExtended(MemoryContext context,
Size size, int flags);
extern void *MemoryContextAllocAligned(MemoryContext context,
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count)))
-/*
- * The result of palloc() is always word-aligned, so we can skip testing
- * alignment of the pointer when deciding which MemSet variant to use.
- * Note that this variant does not offer any advantage, and should not be
- * used, unless its "sz" argument is a compile-time constant; therefore, the
- * issue that it evaluates the argument multiple times isn't a problem in
- * practice.
- */
-#define palloc0fast(sz) \
- ( MemSetTest(0, sz) ? \
- MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \
- MemoryContextAllocZero(CurrentMemoryContext, sz) )
-
/* Higher-limit allocators. */
extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
extern pg_nodiscard void *repalloc_huge(void *pointer, Size size);