mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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
This commit is contained in:
		@@ -139,39 +139,18 @@ 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__
 | 
			
		||||
static inline Node *
 | 
			
		||||
newNode(size_t size, NodeTag tag)
 | 
			
		||||
{
 | 
			
		||||
	Node	   *result;
 | 
			
		||||
 | 
			
		||||
/* 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;
 | 
			
		||||
 | 
			
		||||
#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))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user