mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Adjust MemSet macro to use size_t rather than long
Likewise for MemSetAligned. "long" wasn't the most suitable type for these macros as with MSVC in 64-bit builds, sizeof(long) == 4, which is narrower than the processor's word size, therefore these macros had to perform twice as many loops as they otherwise might. Author: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Discussion: https://postgr.es/m/CAApHDvoGFjSA3aNyVQ3ivbyc4ST=CC5L-_VjEUQ92HbE2Cxovg@mail.gmail.com
This commit is contained in:
@@ -1007,29 +1007,29 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
|
|||||||
#define Min(x, y) ((x) < (y) ? (x) : (y))
|
#define Min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
|
||||||
|
|
||||||
/* Get a bit mask of the bits set in non-long aligned addresses */
|
/* Get a bit mask of the bits set in non-size_t aligned addresses */
|
||||||
#define LONG_ALIGN_MASK (sizeof(long) - 1)
|
#define SIZE_T_ALIGN_MASK (sizeof(size_t) - 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MemSet
|
* MemSet
|
||||||
* Exactly the same as standard library function memset(), but considerably
|
* Exactly the same as standard library function memset(), but considerably
|
||||||
* faster for zeroing small word-aligned structures (such as parsetree nodes).
|
* faster for zeroing small size_t-aligned structures (such as parsetree
|
||||||
* This has to be a macro because the main point is to avoid function-call
|
* nodes). This has to be a macro because the main point is to avoid
|
||||||
* overhead. However, we have also found that the loop is faster than
|
* function-call overhead. However, we have also found that the loop is
|
||||||
* native libc memset() on some platforms, even those with assembler
|
* faster than native libc memset() on some platforms, even those with
|
||||||
* memset() functions. More research needs to be done, perhaps with
|
* assembler memset() functions. More research needs to be done, perhaps
|
||||||
* MEMSET_LOOP_LIMIT tests in configure.
|
* with MEMSET_LOOP_LIMIT tests in configure.
|
||||||
*/
|
*/
|
||||||
#define MemSet(start, val, len) \
|
#define MemSet(start, val, len) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
/* must be void* because we don't know if it is integer aligned yet */ \
|
/* must be void* because we don't know if it is size_t aligned yet */ \
|
||||||
void *_vstart = (void *) (start); \
|
void *_vstart = (void *) (start); \
|
||||||
int _val = (val); \
|
int _val = (val); \
|
||||||
Size _len = (len); \
|
Size _len = (len); \
|
||||||
\
|
\
|
||||||
if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
|
if ((((uintptr_t) _vstart) & SIZE_T_ALIGN_MASK) == 0 && \
|
||||||
(_len & LONG_ALIGN_MASK) == 0 && \
|
(_len & SIZE_T_ALIGN_MASK) == 0 && \
|
||||||
_val == 0 && \
|
_val == 0 && \
|
||||||
_len <= MEMSET_LOOP_LIMIT && \
|
_len <= MEMSET_LOOP_LIMIT && \
|
||||||
/* \
|
/* \
|
||||||
@@ -1038,8 +1038,8 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
|
|||||||
*/ \
|
*/ \
|
||||||
MEMSET_LOOP_LIMIT != 0) \
|
MEMSET_LOOP_LIMIT != 0) \
|
||||||
{ \
|
{ \
|
||||||
long *_start = (long *) _vstart; \
|
size_t *_start = (size_t *) _vstart; \
|
||||||
long *_stop = (long *) ((char *) _start + _len); \
|
size_t *_stop = (size_t *) ((char *) _start + _len); \
|
||||||
while (_start < _stop) \
|
while (_start < _stop) \
|
||||||
*_start++ = 0; \
|
*_start++ = 0; \
|
||||||
} \
|
} \
|
||||||
@@ -1049,23 +1049,23 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* MemSetAligned is the same as MemSet except it omits the test to see if
|
* 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
|
* "start" is size_t-aligned. This is okay to use if the caller knows
|
||||||
* that the pointer is suitably aligned (typically, because he just got it
|
* a-priori that the pointer is suitably aligned (typically, because he just
|
||||||
* from palloc(), which always delivers a max-aligned pointer).
|
* got it from palloc(), which always delivers a max-aligned pointer).
|
||||||
*/
|
*/
|
||||||
#define MemSetAligned(start, val, len) \
|
#define MemSetAligned(start, val, len) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
long *_start = (long *) (start); \
|
size_t *_start = (size_t *) (start); \
|
||||||
int _val = (val); \
|
int _val = (val); \
|
||||||
Size _len = (len); \
|
Size _len = (len); \
|
||||||
\
|
\
|
||||||
if ((_len & LONG_ALIGN_MASK) == 0 && \
|
if ((_len & SIZE_T_ALIGN_MASK) == 0 && \
|
||||||
_val == 0 && \
|
_val == 0 && \
|
||||||
_len <= MEMSET_LOOP_LIMIT && \
|
_len <= MEMSET_LOOP_LIMIT && \
|
||||||
MEMSET_LOOP_LIMIT != 0) \
|
MEMSET_LOOP_LIMIT != 0) \
|
||||||
{ \
|
{ \
|
||||||
long *_stop = (long *) ((char *) _start + _len); \
|
size_t *_stop = (size_t *) ((char *) _start + _len); \
|
||||||
while (_start < _stop) \
|
while (_start < _stop) \
|
||||||
*_start++ = 0; \
|
*_start++ = 0; \
|
||||||
} \
|
} \
|
||||||
|
|||||||
Reference in New Issue
Block a user