Skip to content

Commit 3c080fb

Browse files
committed
Simplify newNode() by removing special cases
- 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
1 parent 2084701 commit 3c080fb

File tree

7 files changed

+9
-139
lines changed

7 files changed

+9
-139
lines changed

src/backend/nodes/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ OBJS = \
2323
makefuncs.o \
2424
multibitmapset.o \
2525
nodeFuncs.o \
26-
nodes.o \
2726
outfuncs.o \
2827
params.o \
2928
print.o \

src/backend/nodes/meson.build

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ backend_sources += files(
77
'makefuncs.c',
88
'multibitmapset.c',
99
'nodeFuncs.c',
10-
'nodes.c',
1110
'params.c',
1211
'print.c',
1312
'read.c',

src/backend/nodes/nodes.c

Lines changed: 0 additions & 31 deletions
This file was deleted.

src/backend/utils/mmgr/mcxt.c

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,44 +1091,6 @@ MemoryContextAllocZero(MemoryContext context, Size size)
10911091
return ret;
10921092
}
10931093

1094-
/*
1095-
* MemoryContextAllocZeroAligned
1096-
* MemoryContextAllocZero where length is suitable for MemSetLoop
1097-
*
1098-
* This might seem overly specialized, but it's not because newNode()
1099-
* is so often called with compile-time-constant sizes.
1100-
*/
1101-
void *
1102-
MemoryContextAllocZeroAligned(MemoryContext context, Size size)
1103-
{
1104-
void *ret;
1105-
1106-
Assert(MemoryContextIsValid(context));
1107-
AssertNotInCriticalSection(context);
1108-
1109-
if (!AllocSizeIsValid(size))
1110-
elog(ERROR, "invalid memory alloc request size %zu", size);
1111-
1112-
context->isReset = false;
1113-
1114-
ret = context->methods->alloc(context, size);
1115-
if (unlikely(ret == NULL))
1116-
{
1117-
MemoryContextStats(TopMemoryContext);
1118-
ereport(ERROR,
1119-
(errcode(ERRCODE_OUT_OF_MEMORY),
1120-
errmsg("out of memory"),
1121-
errdetail("Failed on request of size %zu in memory context \"%s\".",
1122-
size, context->name)));
1123-
}
1124-
1125-
VALGRIND_MEMPOOL_ALLOC(context, ret, size);
1126-
1127-
MemSetLoop(ret, 0, size);
1128-
1129-
return ret;
1130-
}
1131-
11321094
/*
11331095
* MemoryContextAllocExtended
11341096
* Allocate space within the specified context using the given flags.

src/include/c.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,30 +1060,6 @@ extern void ExceptionalCondition(const char *conditionName,
10601060
} while (0)
10611061

10621062

1063-
/*
1064-
* MemSetTest/MemSetLoop are a variant version that allow all the tests in
1065-
* MemSet to be done at compile time in cases where "val" and "len" are
1066-
* constants *and* we know the "start" pointer must be word-aligned.
1067-
* If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use
1068-
* MemSetAligned. Beware of multiple evaluations of the arguments when using
1069-
* this approach.
1070-
*/
1071-
#define MemSetTest(val, len) \
1072-
( ((len) & LONG_ALIGN_MASK) == 0 && \
1073-
(len) <= MEMSET_LOOP_LIMIT && \
1074-
MEMSET_LOOP_LIMIT != 0 && \
1075-
(val) == 0 )
1076-
1077-
#define MemSetLoop(start, val, len) \
1078-
do \
1079-
{ \
1080-
long * _start = (long *) (start); \
1081-
long * _stop = (long *) ((char *) _start + (Size) (len)); \
1082-
\
1083-
while (_start < _stop) \
1084-
*_start++ = 0; \
1085-
} while (0)
1086-
10871063
/*
10881064
* Macros for range-checking float values before converting to integer.
10891065
* We must be careful here that the boundary values are expressed exactly

src/include/nodes/nodes.h

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -139,39 +139,18 @@ typedef struct Node
139139
*
140140
* !WARNING!: Avoid using newNode directly. You should be using the
141141
* macro makeNode. eg. to create a Query node, use makeNode(Query)
142-
*
143-
* Note: the size argument should always be a compile-time constant, so the
144-
* apparent risk of multiple evaluation doesn't matter in practice.
145-
*/
146-
#ifdef __GNUC__
147-
148-
/* With GCC, we can use a compound statement within an expression */
149-
#define newNode(size, tag) \
150-
({ Node *_result; \
151-
AssertMacro((size) >= sizeof(Node)); /* need the tag, at least */ \
152-
_result = (Node *) palloc0fast(size); \
153-
_result->type = (tag); \
154-
_result; \
155-
})
156-
#else
157-
158-
/*
159-
* There is no way to dereference the palloc'ed pointer to assign the
160-
* tag, and also return the pointer itself, so we need a holder variable.
161-
* Fortunately, this macro isn't recursive so we just define
162-
* a global variable for this purpose.
163142
*/
164-
extern PGDLLIMPORT Node *newNodeMacroHolder;
143+
static inline Node *
144+
newNode(size_t size, NodeTag tag)
145+
{
146+
Node *result;
165147

166-
#define newNode(size, tag) \
167-
( \
168-
AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \
169-
newNodeMacroHolder = (Node *) palloc0fast(size), \
170-
newNodeMacroHolder->type = (tag), \
171-
newNodeMacroHolder \
172-
)
173-
#endif /* __GNUC__ */
148+
Assert(size >= sizeof(Node)); /* need the tag, at least */
149+
result = (Node *) palloc0(size);
150+
result->type = tag;
174151

152+
return result;
153+
}
175154

176155
#define makeNode(_type_) ((_type_ *) newNode(sizeof(_type_),T_##_type_))
177156
#define NodeSetTag(nodeptr,t) (((Node*)(nodeptr))->type = (t))

src/include/utils/palloc.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ extern PGDLLIMPORT MemoryContext CurrentMemoryContext;
7070
*/
7171
extern void *MemoryContextAlloc(MemoryContext context, Size size);
7272
extern void *MemoryContextAllocZero(MemoryContext context, Size size);
73-
extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size);
7473
extern void *MemoryContextAllocExtended(MemoryContext context,
7574
Size size, int flags);
7675
extern void *MemoryContextAllocAligned(MemoryContext context,
@@ -109,19 +108,6 @@ extern void pfree(void *pointer);
109108
#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count)))
110109
#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count)))
111110

112-
/*
113-
* The result of palloc() is always word-aligned, so we can skip testing
114-
* alignment of the pointer when deciding which MemSet variant to use.
115-
* Note that this variant does not offer any advantage, and should not be
116-
* used, unless its "sz" argument is a compile-time constant; therefore, the
117-
* issue that it evaluates the argument multiple times isn't a problem in
118-
* practice.
119-
*/
120-
#define palloc0fast(sz) \
121-
( MemSetTest(0, sz) ? \
122-
MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \
123-
MemoryContextAllocZero(CurrentMemoryContext, sz) )
124-
125111
/* Higher-limit allocators. */
126112
extern void *MemoryContextAllocHuge(MemoryContext context, Size size);
127113
extern pg_nodiscard void *repalloc_huge(void *pointer, Size size);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy