diff options
| author | Paul Eggert | 2025-12-07 15:21:46 -0800 |
|---|---|---|
| committer | Paul Eggert | 2025-12-07 15:45:20 -0800 |
| commit | 0d43f2a562c84ff440da978a9275fc44e6f5d9da (patch) | |
| tree | 641ca54e5cce525471cf65ba3fb3952b0176469c | |
| parent | f766e8a36b47c55946e577af3dd70f43ebf05a93 (diff) | |
| download | emacs-0d43f2a562c84ff440da978a9275fc44e6f5d9da.tar.gz emacs-0d43f2a562c84ff440da978a9275fc44e6f5d9da.zip | |
Align config.h better to src/lisp.h
This is mostly a cleanup patch to fix growing discrepancies
between src/lisp.h and configure.ac in terms of how they deduce
how EMACS_INT aligns. The patch includes a static check that the
two methods now agree. It also speeds up ‘configure’ a bit.
* configure.ac (ALIGNOF_INT, ALIGNOF_LONG, ALIGNOF_LONG_LONG):
Remove; no longer used.
(ALIGNOF_EMACS_INT): New macro.
(system_malloc): Set to 'no' more consistently with what’s
in src/lisp.h.
* src/lisp.h (ALIGNOF_EMACS_INT): Do not define here, as config.h
defines it now. Check that config.h’s definition equals the
actual alignof (EMACS_INT).
(USE_USB_TAG): Set more consistently with what’s in configure.ac.
(alignas): Don’t second-guess Gnulib.
| -rw-r--r-- | configure.ac | 78 | ||||
| -rw-r--r-- | src/lisp.h | 31 |
2 files changed, 51 insertions, 58 deletions
diff --git a/configure.ac b/configure.ac index f567c3a7163..2c29633a6a9 100644 --- a/configure.ac +++ b/configure.ac | |||
| @@ -3227,8 +3227,13 @@ to configure.]) | |||
| 3227 | fi | 3227 | fi |
| 3228 | 3228 | ||
| 3229 | # Configure gnulib. | 3229 | # Configure gnulib. |
| 3230 | # Although this does not affect CFLAGS or LIBS permanently. | 3230 | # |
| 3231 | # it temporarily reverts them to their pre-pkg-config values, | 3231 | # Do this after any CC or CFLAGS changes that affect Gnulib, |
| 3232 | # and before any tests that depend on gnulib tests, | ||
| 3233 | # e.g., the system_malloc=no test below. | ||
| 3234 | # | ||
| 3235 | # Do not affect CFLAGS or LIBS permanently. | ||
| 3236 | # Instead, temporarily revert them to their pre-pkg-config values, | ||
| 3232 | # because gnulib needs to work with both src (which uses the | 3237 | # because gnulib needs to work with both src (which uses the |
| 3233 | # pkg-config stuff) and lib-src (which does not). For example, gnulib | 3238 | # pkg-config stuff) and lib-src (which does not). For example, gnulib |
| 3234 | # may need to determine whether CLOCK_TIME_LIB should contain -lrt, | 3239 | # may need to determine whether CLOCK_TIME_LIB should contain -lrt, |
| @@ -3266,9 +3271,19 @@ AC_CACHE_CHECK( | |||
| 3266 | fi]) | 3271 | fi]) |
| 3267 | doug_lea_malloc=$emacs_cv_var_doug_lea_malloc | 3272 | doug_lea_malloc=$emacs_cv_var_doug_lea_malloc |
| 3268 | 3273 | ||
| 3269 | AC_CHECK_ALIGNOF([int]) | 3274 | AC_CHECK_ALIGNOF([EMACS_INT], |
| 3270 | AC_CHECK_ALIGNOF([long]) | 3275 | [[#include <limits.h> |
| 3271 | AC_CHECK_ALIGNOF([long long]) | 3276 | #include <stddef.h> |
| 3277 | #include <stdint.h> | ||
| 3278 | #if INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT | ||
| 3279 | typedef int EMACS_INT; | ||
| 3280 | #elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT | ||
| 3281 | typedef long int EMACS_INT; | ||
| 3282 | #elif INTPTR_MAX <= LLONG_MAX | ||
| 3283 | typedef long long int EMACS_INT; | ||
| 3284 | #endif | ||
| 3285 | ]]) | ||
| 3286 | |||
| 3272 | AC_CHECK_SIZEOF([long]) | 3287 | AC_CHECK_SIZEOF([long]) |
| 3273 | 3288 | ||
| 3274 | AC_CACHE_CHECK([for struct alignment], | 3289 | AC_CACHE_CHECK([for struct alignment], |
| @@ -3293,40 +3308,27 @@ system_malloc=yes | |||
| 3293 | # adequately positioned memory, enable the GNU malloc, which more | 3308 | # adequately positioned memory, enable the GNU malloc, which more |
| 3294 | # consistently provides allocations at low addresses, as is required for | 3309 | # consistently provides allocations at low addresses, as is required for |
| 3295 | # the pdumper to load dump files at a representable location. | 3310 | # the pdumper to load dump files at a representable location. |
| 3296 | AS_IF([test "$with_pdumper" = "yes" && test "$with_wide_int" != "yes"], | 3311 | AS_CASE([$emacs_cv_struct_alignment%$gl_cv_header_working_stdalign_h%$with_wide_int%$ac_cv_alignof_EMACS_INT%$with_pdumper], |
| 3297 | AC_CHECK_HEADERS([stdalign.h]) | 3312 | [*%*%*%*%*%*], |
| 3298 | [AC_CACHE_CHECK([whether alignas is required yet unavailable], | 3313 | [AC_MSG_ERROR([configuration values cannot contain '%'])], |
| 3299 | [emacs_cv_alignas_unavailable], | 3314 | |
| 3300 | [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ | 3315 | dnl There is no problem in most situations, i.e.: |
| 3301 | #ifdef HAVE_STDALIGN_H | 3316 | [dnl if emacs_cv_struct_alignment |
| 3302 | #include <stdalign.h> | 3317 | yes%* \ |
| 3303 | #endif | 3318 | dnl or if gl_cv_header_working_stdalign_h |
| 3304 | #include <limits.h> | 3319 | | *%yes*%*%*%* \ |
| 3305 | ]], [[ | 3320 | dnl or if with_wide_int (as in practice tag bits are high-order) |
| 3306 | #define IDEAL_GCALIGNMENT 8 | 3321 | | *%*%yes%*%* \ |
| 3307 | #if INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT | 3322 | dnl or if EMACS_INT's alignment is at least 8. |
| 3308 | # define ALIGNOF_EMACS_INT ALIGNOF_INT | 3323 | | *%*%*%8%* | *%*%*%[1-9]?*%*], |
| 3309 | # elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT | 3324 | [], |
| 3310 | # define ALIGNOF_EMACS_INT ALIGNOF_LONG | ||
| 3311 | # elif INTPTR_MAX <= LLONG_MAX | ||
| 3312 | # define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG | ||
| 3313 | # else | ||
| 3314 | # error "INTPTR_MAX too large" | ||
| 3315 | #endif | ||
| 3316 | 3325 | ||
| 3317 | #if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \ | 3326 | dnl Otherwise, if using the portable dumper, enable GNU malloc. |
| 3318 | && !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED \ | 3327 | [*%yes], |
| 3319 | && !defined __alignas_is_defined \ | 3328 | [system_malloc=no |
| 3320 | && __STDC_VERSION__ < 202311 && __cplusplus < 201103) | 3329 | AC_MSG_WARN([The GNU memory manager will be enabled as your system |
| 3321 | #error "!USE_LSB_TAG required" | 3330 | does not guarantee that the portable dumper can allocate memory |
| 3322 | #endif | 3331 | at a suitably low address.])]) |
| 3323 | ]])], [emacs_cv_alignas_unavailable=no], | ||
| 3324 | [emacs_cv_alignas_unavailable=yes])]) | ||
| 3325 | AS_IF([test "$emacs_cv_alignas_unavailable" = "yes"], | ||
| 3326 | [system_malloc=no | ||
| 3327 | AC_MSG_WARN([The GNU memory manager will be enabled as your system | ||
| 3328 | does not guarantee that the portable dumper can allocate memory at a suitably | ||
| 3329 | low address.])])]) | ||
| 3330 | 3332 | ||
| 3331 | dnl This must be before the test of $ac_cv_func_sbrk below. | 3333 | dnl This must be before the test of $ac_cv_func_sbrk below. |
| 3332 | AC_CHECK_FUNCS_ONCE([sbrk]) | 3334 | AC_CHECK_FUNCS_ONCE([sbrk]) |
diff --git a/src/lisp.h b/src/lisp.h index 47442a29f50..e63019cc088 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -90,21 +90,18 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS) | |||
| 90 | typedef int EMACS_INT; | 90 | typedef int EMACS_INT; |
| 91 | typedef unsigned int EMACS_UINT; | 91 | typedef unsigned int EMACS_UINT; |
| 92 | enum { EMACS_INT_WIDTH = INT_WIDTH, EMACS_UINT_WIDTH = UINT_WIDTH }; | 92 | enum { EMACS_INT_WIDTH = INT_WIDTH, EMACS_UINT_WIDTH = UINT_WIDTH }; |
| 93 | # define ALIGNOF_EMACS_INT ALIGNOF_INT | ||
| 94 | # define EMACS_INT_MAX INT_MAX | 93 | # define EMACS_INT_MAX INT_MAX |
| 95 | # define pI "" | 94 | # define pI "" |
| 96 | # elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT | 95 | # elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT |
| 97 | typedef long int EMACS_INT; | 96 | typedef long int EMACS_INT; |
| 98 | typedef unsigned long EMACS_UINT; | 97 | typedef unsigned long EMACS_UINT; |
| 99 | enum { EMACS_INT_WIDTH = LONG_WIDTH, EMACS_UINT_WIDTH = ULONG_WIDTH }; | 98 | enum { EMACS_INT_WIDTH = LONG_WIDTH, EMACS_UINT_WIDTH = ULONG_WIDTH }; |
| 100 | # define ALIGNOF_EMACS_INT ALIGNOF_LONG | ||
| 101 | # define EMACS_INT_MAX LONG_MAX | 99 | # define EMACS_INT_MAX LONG_MAX |
| 102 | # define pI "l" | 100 | # define pI "l" |
| 103 | # elif INTPTR_MAX <= LLONG_MAX | 101 | # elif INTPTR_MAX <= LLONG_MAX |
| 104 | typedef long long int EMACS_INT; | 102 | typedef long long int EMACS_INT; |
| 105 | typedef unsigned long long int EMACS_UINT; | 103 | typedef unsigned long long int EMACS_UINT; |
| 106 | enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH }; | 104 | enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH }; |
| 107 | # define ALIGNOF_EMACS_INT ALIGNOF_LONG_LONG | ||
| 108 | # define EMACS_INT_MAX LLONG_MAX | 105 | # define EMACS_INT_MAX LLONG_MAX |
| 109 | /* MinGW supports %lld only if __USE_MINGW_ANSI_STDIO is non-zero, | 106 | /* MinGW supports %lld only if __USE_MINGW_ANSI_STDIO is non-zero, |
| 110 | which is arranged by config.h, and (for mingw.org) if GCC is 6.0 or | 107 | which is arranged by config.h, and (for mingw.org) if GCC is 6.0 or |
| @@ -123,6 +120,7 @@ enum { EMACS_INT_WIDTH = LLONG_WIDTH, EMACS_UINT_WIDTH = ULLONG_WIDTH }; | |||
| 123 | # error "INTPTR_MAX too large" | 120 | # error "INTPTR_MAX too large" |
| 124 | # endif | 121 | # endif |
| 125 | #endif | 122 | #endif |
| 123 | static_assert (alignof (EMACS_INT) == ALIGNOF_EMACS_INT); | ||
| 126 | 124 | ||
| 127 | /* Number of bits to put in each character in the internal representation | 125 | /* Number of bits to put in each character in the internal representation |
| 128 | of bool vectors. This should not vary across implementations. */ | 126 | of bool vectors. This should not vary across implementations. */ |
| @@ -252,15 +250,13 @@ DEFINE_GDB_SYMBOL_END (INTTYPEBITS) | |||
| 252 | b. slower, because it typically requires extra masking. | 250 | b. slower, because it typically requires extra masking. |
| 253 | So, USE_LSB_TAG is true only on hosts where it might be useful. */ | 251 | So, USE_LSB_TAG is true only on hosts where it might be useful. */ |
| 254 | DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) | 252 | DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) |
| 255 | #if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT && !defined alignas \ | 253 | #if (ALIGNOF_EMACS_INT < IDEAL_GCALIGNMENT \ |
| 256 | && ! (__GNUC__ || 4 <= __clang_major__) \ | 254 | && !HAVE_C_ALIGNASOF && !defined alignas \ |
| 257 | && __STDC_VERSION__ < 202311 && __cplusplus < 201103) \ | 255 | && !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED) |
| 258 | && !defined WIDE_EMACS_INT \ | 256 | # define USE_LSB_TAG false |
| 259 | && !defined HAVE_STRUCT_ATTRIBUTE_ALIGNED | 257 | #else |
| 260 | #define USE_LSB_TAG 0 | 258 | # define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX) |
| 261 | #else /* ALIGNOF_EMACS_INT >= IDEAL_GCALIGNMENT || defined alignas ... */ | 259 | #endif |
| 262 | #define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX) | ||
| 263 | #endif /* ALIGNOF_EMACS_INT >= IDEAL_GCALIGNMENT || defined alignas ... */ | ||
| 264 | DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) | 260 | DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) |
| 265 | 261 | ||
| 266 | /* Mask for the value (as opposed to the type bits) of a Lisp object. */ | 262 | /* Mask for the value (as opposed to the type bits) of a Lisp object. */ |
| @@ -268,14 +264,9 @@ DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) | |||
| 268 | # define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) | 264 | # define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) |
| 269 | DEFINE_GDB_SYMBOL_END (VALMASK) | 265 | DEFINE_GDB_SYMBOL_END (VALMASK) |
| 270 | 266 | ||
| 271 | /* Support 'alignas (A)' if possible, where A is an integer constant. */ | 267 | /* Ignore 'alignas' on compilers lacking it. */ |
| 272 | #ifndef alignas | 268 | #if !HAVE_C_ALIGNASOF && !defined alignas |
| 273 | # if __GNUC__ || 4 <= __clang_major__ | 269 | # define alignas(a) /* not supported */ |
| 274 | /* This is more reliable than the alignas operator, in GCC 14. */ | ||
| 275 | # define alignas(a) __attribute__ ((__aligned__ (a))) | ||
| 276 | # elif __STDC_VERSION__ < 202311 && __cplusplus < 201103 | ||
| 277 | # define alignas(a) /* not supported */ | ||
| 278 | # endif | ||
| 279 | #endif | 270 | #endif |
| 280 | 271 | ||
| 281 | /* The minimum alignment requirement for Lisp objects that is imposed by the | 272 | /* The minimum alignment requirement for Lisp objects that is imposed by the |