diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/c.h | 90 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 16 | ||||
-rw-r--r-- | src/include/utils/memutils.h | 3 | ||||
-rw-r--r-- | src/include/utils/palloc.h | 24 |
4 files changed, 95 insertions, 38 deletions
diff --git a/src/include/c.h b/src/include/c.h index e5d7d641610..040a211a8f1 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: c.h,v 1.133 2002/12/05 04:04:48 momjian Exp $ + * $Id: c.h,v 1.134 2002/12/16 16:22:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -579,38 +579,78 @@ typedef NameData *Name; * memset() functions. More research needs to be done, perhaps with * platform-specific MEMSET_LOOP_LIMIT values or tests in configure. * - * MemSet has been split into two parts so MemSetTest can be optimized - * away for constant 'val' and 'len'. This is used by palloc0(). - * - * Note, arguments are evaluated more than once. - * * bjm 2002-10-08 */ +#define MemSet(start, val, len) \ + do \ + { \ + int32 * _start = (int32 *) (start); \ + int _val = (val); \ + Size _len = (len); \ +\ + if ((((long) _start) & INT_ALIGN_MASK) == 0 && \ + (_len & INT_ALIGN_MASK) == 0 && \ + _val == 0 && \ + _len <= MEMSET_LOOP_LIMIT) \ + { \ + int32 * _stop = (int32 *) ((char *) _start + _len); \ + while (_start < _stop) \ + *_start++ = 0; \ + } \ + else \ + memset((char *) _start, _val, _len); \ + } while (0) + +#define MEMSET_LOOP_LIMIT 1024 + +/* + * MemSetAligned is the same as MemSet except it omits the test to see if + * "start" is word-aligned. This is okay to use if the caller knows a-priori + * that the pointer is suitably aligned (typically, because he just got it + * from palloc(), which always delivers a max-aligned pointer). + */ +#define MemSetAligned(start, val, len) \ + do \ + { \ + int32 * _start = (int32 *) (start); \ + int _val = (val); \ + Size _len = (len); \ +\ + if ((_len & INT_ALIGN_MASK) == 0 && \ + _val == 0 && \ + _len <= MEMSET_LOOP_LIMIT) \ + { \ + int32 * _stop = (int32 *) ((char *) _start + _len); \ + while (_start < _stop) \ + *_start++ = 0; \ + } \ + else \ + memset((char *) _start, _val, _len); \ + } 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) & INT_ALIGN_MASK) == 0 && \ (len) <= MEMSET_LOOP_LIMIT && \ (val) == 0 ) #define MemSetLoop(start, val, len) \ -do \ -{ \ - int32 * _start = (int32 *) (start); \ - int32 * _stop = (int32 *) ((char *) _start + (len)); \ -\ - while (_start < _stop) \ - *_start++ = 0; \ -} while (0) - -#define MemSet(start, val, len) \ -do \ -{ \ - if (MemSetTest(val, len) && ((long)(start) & INT_ALIGN_MASK) == 0 ) \ - MemSetLoop(start, val, len); \ - else \ - memset((char *)(start), (val), (len)); \ -} while (0) - -#define MEMSET_LOOP_LIMIT 1024 + do \ + { \ + int32 * _start = (int32 *) (start); \ + int32 * _stop = (int32 *) ((char *) _start + (Size) (len)); \ + \ + while (_start < _stop) \ + *_start++ = 0; \ + } while (0) /* ---------------------------------------------------------------- diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 5f628168738..f119b5111db 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.133 2002/12/14 00:17:59 tgl Exp $ + * $Id: nodes.h,v 1.134 2002/12/16 16:22:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -293,9 +293,16 @@ typedef struct Node #define nodeTag(nodeptr) (((Node*)(nodeptr))->type) /* + * newNode - + * create a new node of the specified size and tag the node with the + * specified tag. + * + * !WARNING!: Avoid using newNode directly. You should be using the + * macro makeNode. eg. to create a Query node, use makeNode(Query) + * * There is no way to dereference the palloc'ed pointer to assign the - * tag, and return the pointer itself, so we need a holder variable. - * Fortunately, this function isn't recursive so we just define + * 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 Node *newNodeMacroHolder; @@ -303,8 +310,7 @@ extern Node *newNodeMacroHolder; #define newNode(size, tag) \ ( \ AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \ -\ - newNodeMacroHolder = (Node *) palloc0(size), \ + newNodeMacroHolder = (Node *) palloc0fast(size), \ newNodeMacroHolder->type = (tag), \ newNodeMacroHolder \ ) diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index 94578b8fb6f..09198d1c6e6 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: memutils.h,v 1.49 2002/12/15 21:01:34 tgl Exp $ + * $Id: memutils.h,v 1.50 2002/12/16 16:22:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -83,6 +83,7 @@ extern void MemoryContextResetChildren(MemoryContext context); extern void MemoryContextDeleteChildren(MemoryContext context); extern void MemoryContextResetAndDeleteChildren(MemoryContext context); extern Size GetMemoryChunkSpace(void *pointer); +extern MemoryContext GetMemoryChunkContext(void *pointer); extern void MemoryContextStats(MemoryContext context); #ifdef MEMORY_CONTEXT_CHECKING diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 093764d5ebc..7dabc52f318 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -21,7 +21,7 @@ * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: palloc.h,v 1.23 2002/11/13 00:37:06 momjian Exp $ + * $Id: palloc.h,v 1.24 2002/12/16 16:22:46 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -46,15 +46,25 @@ extern DLLIMPORT MemoryContext CurrentMemoryContext; * Fundamental memory-allocation operations (more are in utils/memutils.h) */ extern void *MemoryContextAlloc(MemoryContext context, Size size); -extern void *MemoryContextAllocPalloc0(MemoryContext context, Size size); +extern void *MemoryContextAllocZero(MemoryContext context, Size size); +extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); #define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz)) -/* We assume palloc() is already int-aligned */ -#define palloc0(sz) \ - ( MemSetTest(0, (sz)) ? \ - MemoryContextAllocPalloc0(CurrentMemoryContext, (sz)) : \ - memset(palloc(sz), 0, (sz))) +#define palloc0(sz) MemoryContextAllocZero(CurrentMemoryContext, (sz)) + +/* + * 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) ) extern void pfree(void *pointer); |