summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-08-29 22:49:07 +0000
committerTom Lane2008-08-29 22:49:07 +0000
commit92658945afe9054afb790d0d8d79b341ec2a14f0 (patch)
tree1fb959d55c292375fbdf9e93af2ea7c0ba075bd5
parentd4768ab301b2ed2b2c81bb060db8f27693a465bf (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.c4
-rw-r--r--src/include/nodes/nodes.h19
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))