]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Adjust MemSet macro to use size_t rather than long
authorDavid Rowley <drowley@postgresql.org>
Sun, 16 Nov 2025 23:27:00 +0000 (12:27 +1300)
committerDavid Rowley <drowley@postgresql.org>
Sun, 16 Nov 2025 23:27:00 +0000 (12:27 +1300)
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

src/include/c.h

index 757dfff47825d2a043b72147960ab2cd34e18aad..cb8a38669bedbaba00956026f56e9c42e7f2fbf0 100644 (file)
@@ -1007,29 +1007,29 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
 #define Min(x, y)              ((x) < (y) ? (x) : (y))
 
 
-/* Get a bit mask of the bits set in non-long aligned addresses */
-#define LONG_ALIGN_MASK (sizeof(long) - 1)
+/* Get a bit mask of the bits set in non-size_t aligned addresses */
+#define SIZE_T_ALIGN_MASK (sizeof(size_t) - 1)
 
 /*
  * MemSet
  *     Exactly the same as standard library function memset(), but considerably
- *     faster for zeroing small word-aligned structures (such as parsetree nodes).
- *     This has to be a macro because the main point is to avoid function-call
- *     overhead.   However, we have also found that the loop is faster than
- *     native libc memset() on some platforms, even those with assembler
- *     memset() functions.  More research needs to be done, perhaps with
- *     MEMSET_LOOP_LIMIT tests in configure.
+ *     faster for zeroing small size_t-aligned structures (such as parsetree
+ *     nodes).  This has to be a macro because the main point is to avoid
+ *     function-call overhead.  However, we have also found that the loop is
+ *     faster than native libc memset() on some platforms, even those with
+ *     assembler memset() functions.  More research needs to be done, perhaps
+ *     with MEMSET_LOOP_LIMIT tests in configure.
  */
 #define MemSet(start, val, len) \
        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); \
                int             _val = (val); \
                Size    _len = (len); \
 \
-               if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
-                       (_len & LONG_ALIGN_MASK) == 0 && \
+               if ((((uintptr_t) _vstart) & SIZE_T_ALIGN_MASK) == 0 && \
+                       (_len & SIZE_T_ALIGN_MASK) == 0 && \
                        _val == 0 && \
                        _len <= MEMSET_LOOP_LIMIT && \
                        /* \
@@ -1038,8 +1038,8 @@ pg_noreturn extern void ExceptionalCondition(const char *conditionName,
                         */ \
                        MEMSET_LOOP_LIMIT != 0) \
                { \
-                       long *_start = (long *) _vstart; \
-                       long *_stop = (long *) ((char *) _start + _len); \
+                       size_t *_start = (size_t *) _vstart; \
+                       size_t *_stop = (size_t *) ((char *) _start + _len); \
                        while (_start < _stop) \
                                *_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
- * "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).
+ * "start" is size_t-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 \
        { \
-               long   *_start = (long *) (start); \
+               size_t *_start = (size_t *) (start); \
                int             _val = (val); \
                Size    _len = (len); \
 \
-               if ((_len & LONG_ALIGN_MASK) == 0 && \
+               if ((_len & SIZE_T_ALIGN_MASK) == 0 && \
                        _val == 0 && \
                        _len <= MEMSET_LOOP_LIMIT && \
                        MEMSET_LOOP_LIMIT != 0) \
                { \
-                       long *_stop = (long *) ((char *) _start + _len); \
+                       size_t *_stop = (size_t *) ((char *) _start + _len); \
                        while (_start < _stop) \
                                *_start++ = 0; \
                } \