Split MemSet into three parts to constant comparisons can be optimized
authorBruce Momjian <bruce@momjian.us>
Wed, 13 Nov 2002 00:37:06 +0000 (00:37 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 13 Nov 2002 00:37:06 +0000 (00:37 +0000)
away by the compiler;  used by palloc0.

src/backend/utils/mmgr/mcxt.c
src/include/c.h
src/include/utils/palloc.h

index d2432c0068880c48045b8eb3993f1afe6db01580..313a6ad56dd98c8f7650b890a6ed5c52be46ebd4 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.35 2002/11/10 02:17:25 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.36 2002/11/13 00:37:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -453,14 +453,14 @@ MemoryContextAlloc(MemoryContext context, Size size)
 }
 
 /*
- * MemoryContextAllocZero
+ * MemoryContextAllocPalloc0
  *     Like MemoryContextAlloc, but clears allocated memory
  *
  * We could just call MemoryContextAlloc then clear the memory, but this
  * function is called too many times, so we have a separate version.
  */
 void *
-MemoryContextAllocZero(MemoryContext context, Size size)
+MemoryContextAllocPalloc0(MemoryContext context, Size size)
 {
    void *ret;
 
@@ -471,7 +471,7 @@ MemoryContextAllocZero(MemoryContext context, Size size)
             (unsigned long) size);
 
    ret = (*context->methods->alloc) (context, size);
-   MemSet(ret, 0, size);
+   MemSetLoop(ret, 0, size);
    return ret;
 }
 
index 2dfdca4c0136e71f33723490ae56a9a4fcbbc96b..4e538111ce85f7e9a0c493955ca5ba9bef760143 100644 (file)
@@ -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.131 2002/11/11 03:02:19 momjian Exp $
+ * $Id: c.h,v 1.132 2002/11/13 00:37:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -577,26 +577,36 @@ 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); \
+#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)); \
 \
-       if ((( ((long) _start) | _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)
+   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
 
index 89b5c151a2c58d19ab1adf4224fd02237c90eb10..093764d5ebc2ea39c8b1fd96e4465bb27c95a0cc 100644 (file)
@@ -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.22 2002/11/10 02:17:25 momjian Exp $
+ * $Id: palloc.h,v 1.23 2002/11/13 00:37:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,11 +46,15 @@ extern DLLIMPORT MemoryContext CurrentMemoryContext;
  * Fundamental memory-allocation operations (more are in utils/memutils.h)
  */
 extern void *MemoryContextAlloc(MemoryContext context, Size size);
-extern void *MemoryContextAllocZero(MemoryContext context, Size size);
+extern void *MemoryContextAllocPalloc0(MemoryContext context, Size size);
 
 #define palloc(sz) MemoryContextAlloc(CurrentMemoryContext, (sz))
 
-#define palloc0(sz)    MemoryContextAllocZero(CurrentMemoryContext, (sz))
+/* We assume palloc() is already int-aligned */
+#define palloc0(sz)    \
+   ( MemSetTest(0, (sz)) ? \
+       MemoryContextAllocPalloc0(CurrentMemoryContext, (sz)) : \
+       memset(palloc(sz), 0, (sz)))
 
 extern void pfree(void *pointer);