diff options
author | Tom Lane | 2008-08-29 22:49:07 +0000 |
---|---|---|
committer | Tom Lane | 2008-08-29 22:49:07 +0000 |
commit | 92658945afe9054afb790d0d8d79b341ec2a14f0 (patch) | |
tree | 1fb959d55c292375fbdf9e93af2ea7c0ba075bd5 | |
parent | d4768ab301b2ed2b2c81bb060db8f27693a465bf (diff) |
In GCC-based builds, use a better newNode() macro that relies on GCC-specific
syntax to avoid a useless store into a global variable. Per experimentation,
this works better than my original thought of trying to push the code into
an out-of-line subroutine.
-rw-r--r-- | src/backend/nodes/nodes.c | 4 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 19 |
2 files changed, 23 insertions, 0 deletions
diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c index e81a7d5364..b843d2081a 100644 --- a/src/backend/nodes/nodes.c +++ b/src/backend/nodes/nodes.c @@ -22,6 +22,10 @@ /* * 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; diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 745aae482d..f365eacdbb 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -384,6 +384,23 @@ typedef struct Node * !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 @@ -399,6 +416,8 @@ extern PGDLLIMPORT Node *newNodeMacroHolder; newNodeMacroHolder \ ) +#endif /* __GNUC__ */ + #define makeNode(_type_) ((_type_ *) newNode(sizeof(_type_),T_##_type_)) #define NodeSetTag(nodeptr,t) (((Node*)(nodeptr))->type = (t)) |