From aaa3a0caa6c3e4dacd950e2dc3c1691222c50965 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 13 Nov 2002 00:37:06 +0000 Subject: [PATCH] Split MemSet into three parts to constant comparisons can be optimized away by the compiler; used by palloc0. --- src/backend/utils/mmgr/mcxt.c | 8 +++--- src/include/c.h | 46 +++++++++++++++++++++-------------- src/include/utils/palloc.h | 10 +++++--- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index d2432c0068..313a6ad56d 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -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; } diff --git a/src/include/c.h b/src/include/c.h index 2dfdca4c01..4e538111ce 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.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 diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 89b5c151a2..093764d5eb 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.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);