diff options
| author | Paul Eggert | 2017-11-02 13:06:38 -0700 |
|---|---|---|
| committer | Paul Eggert | 2017-11-02 13:21:33 -0700 |
| commit | 6b08ad5263bc063c79666ffe2bd5ed9ab77a00a0 (patch) | |
| tree | c31fb8bdc9d639cc96982aa4718d74f4cc0e0397 | |
| parent | a9f8706fa8fba5289e910fd55841b0952410d558 (diff) | |
| download | emacs-6b08ad5263bc063c79666ffe2bd5ed9ab77a00a0.tar.gz emacs-6b08ad5263bc063c79666ffe2bd5ed9ab77a00a0.zip | |
Fix alignment portability problems
Do not assume that the natural alignment of Lisp objects is a
multiple of GCALIGNMENT. This improves on the portability of the
recent fix for Bug#29040.
* lib-src/make-docfile.c (close_emacs_globals):
* src/buffer.c (buffer_defaults, buffer_local_symbols):
* src/lisp.h (DEFUN):
* src/thread.c (main_thread):
Use GCALIGNED, not alignas (GCALIGNMENT).
* src/alloc.c (COMMON_MULTIPLE):
Move back here from lisp.h, since it is no longer used elsewhere.
* src/lisp.h (GCALIGNMENT): No longer a macro, since we need not
worry about MSVC. Omit no-longer-needed consistency check.
* src/thread.c (THREAD_ALIGNMENT): Remove.
| -rw-r--r-- | lib-src/make-docfile.c | 2 | ||||
| -rw-r--r-- | src/alloc.c | 6 | ||||
| -rw-r--r-- | src/buffer.c | 4 | ||||
| -rw-r--r-- | src/lisp.h | 25 | ||||
| -rw-r--r-- | src/thread.c | 4 |
5 files changed, 18 insertions, 23 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 69c7f37a17a..0ea3f7b6b6a 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -668,7 +668,7 @@ close_emacs_globals (ptrdiff_t num_symbols) | |||
| 668 | "extern\n" | 668 | "extern\n" |
| 669 | "#endif\n" | 669 | "#endif\n" |
| 670 | "struct {\n" | 670 | "struct {\n" |
| 671 | " struct Lisp_Symbol alignas (GCALIGNMENT) s;\n" | 671 | " struct Lisp_Symbol GCALIGNED s;\n" |
| 672 | "} lispsym[%td];\n"), | 672 | "} lispsym[%td];\n"), |
| 673 | num_symbols); | 673 | num_symbols); |
| 674 | } | 674 | } |
diff --git a/src/alloc.c b/src/alloc.c index ff93956109b..0fc79fe68ac 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -621,6 +621,12 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 621 | #endif | 621 | #endif |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | /* A common multiple of the positive integers A and B. Ideally this | ||
| 625 | would be the least common multiple, but there's no way to do that | ||
| 626 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 627 | #define COMMON_MULTIPLE(a, b) \ | ||
| 628 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 629 | |||
| 624 | #ifndef XMALLOC_OVERRUN_CHECK | 630 | #ifndef XMALLOC_OVERRUN_CHECK |
| 625 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 | 631 | #define XMALLOC_OVERRUN_CHECK_OVERHEAD 0 |
| 626 | #else | 632 | #else |
diff --git a/src/buffer.c b/src/buffer.c index 9635733fcff..15735a298ad 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -61,7 +61,7 @@ struct buffer *all_buffers; | |||
| 61 | Setting the default value also goes through the alist of buffers | 61 | Setting the default value also goes through the alist of buffers |
| 62 | and stores into each buffer that does not say it has a local value. */ | 62 | and stores into each buffer that does not say it has a local value. */ |
| 63 | 63 | ||
| 64 | struct buffer alignas (GCALIGNMENT) buffer_defaults; | 64 | struct buffer GCALIGNED buffer_defaults; |
| 65 | 65 | ||
| 66 | /* This structure marks which slots in a buffer have corresponding | 66 | /* This structure marks which slots in a buffer have corresponding |
| 67 | default values in buffer_defaults. | 67 | default values in buffer_defaults. |
| @@ -84,7 +84,7 @@ struct buffer buffer_local_flags; | |||
| 84 | /* This structure holds the names of symbols whose values may be | 84 | /* This structure holds the names of symbols whose values may be |
| 85 | buffer-local. It is indexed and accessed in the same way as the above. */ | 85 | buffer-local. It is indexed and accessed in the same way as the above. */ |
| 86 | 86 | ||
| 87 | struct buffer alignas (GCALIGNMENT) buffer_local_symbols; | 87 | struct buffer GCALIGNED buffer_local_symbols; |
| 88 | 88 | ||
| 89 | /* Return the symbol of the per-buffer variable at offset OFFSET in | 89 | /* Return the symbol of the per-buffer variable at offset OFFSET in |
| 90 | the buffer structure. */ | 90 | the buffer structure. */ |
diff --git a/src/lisp.h b/src/lisp.h index 43b3ec618f0..bf9db591bd5 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -228,14 +228,12 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; | |||
| 228 | 228 | ||
| 229 | USE_LSB_TAG not only requires the least 3 bits of pointers returned by | 229 | USE_LSB_TAG not only requires the least 3 bits of pointers returned by |
| 230 | malloc to be 0 but also needs to be able to impose a mult-of-8 alignment | 230 | malloc to be 0 but also needs to be able to impose a mult-of-8 alignment |
| 231 | on the few static Lisp_Objects used: lispsym, all the defsubr, and | 231 | on the few static Lisp_Objects used, all of which are aligned via |
| 232 | the two special buffers buffer_defaults and buffer_local_symbols. */ | 232 | the GCALIGN macro defined below. */ |
| 233 | 233 | ||
| 234 | enum Lisp_Bits | 234 | enum Lisp_Bits |
| 235 | { | 235 | { |
| 236 | /* 2**GCTYPEBITS. This must be a macro that expands to a literal | 236 | GCALIGNMENT = 1 << GCTYPEBITS, |
| 237 | integer constant, for MSVC. */ | ||
| 238 | #define GCALIGNMENT 8 | ||
| 239 | 237 | ||
| 240 | /* Number of bits in a Lisp_Object value, not counting the tag. */ | 238 | /* Number of bits in a Lisp_Object value, not counting the tag. */ |
| 241 | VALBITS = EMACS_INT_WIDTH - GCTYPEBITS, | 239 | VALBITS = EMACS_INT_WIDTH - GCTYPEBITS, |
| @@ -247,10 +245,6 @@ enum Lisp_Bits | |||
| 247 | FIXNUM_BITS = VALBITS + 1 | 245 | FIXNUM_BITS = VALBITS + 1 |
| 248 | }; | 246 | }; |
| 249 | 247 | ||
| 250 | #if GCALIGNMENT != 1 << GCTYPEBITS | ||
| 251 | # error "GCALIGNMENT and GCTYPEBITS are inconsistent" | ||
| 252 | #endif | ||
| 253 | |||
| 254 | /* The maximum value that can be stored in a EMACS_INT, assuming all | 248 | /* The maximum value that can be stored in a EMACS_INT, assuming all |
| 255 | bits other than the type bits contribute to a nonnegative signed value. | 249 | bits other than the type bits contribute to a nonnegative signed value. |
| 256 | This can be used in #if, e.g., '#if USE_LSB_TAG' below expands to an | 250 | This can be used in #if, e.g., '#if USE_LSB_TAG' below expands to an |
| @@ -277,18 +271,15 @@ DEFINE_GDB_SYMBOL_END (VALMASK) | |||
| 277 | error !; | 271 | error !; |
| 278 | #endif | 272 | #endif |
| 279 | 273 | ||
| 274 | /* Declare an object to have an address that is a multiple of | ||
| 275 | GCALIGNMENT. alignas is not suitable here, as it fails if the | ||
| 276 | object's natural alignment exceeds GCALIGNMENT. */ | ||
| 280 | #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED | 277 | #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED |
| 281 | # define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) | 278 | # define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) |
| 282 | #else | 279 | #else |
| 283 | # define GCALIGNED /* empty */ | 280 | # define GCALIGNED /* empty */ |
| 284 | #endif | 281 | #endif |
| 285 | 282 | ||
| 286 | /* A common multiple of the positive integers A and B. Ideally this | ||
| 287 | would be the least common multiple, but there's no way to do that | ||
| 288 | as a constant expression in C, so do the best that we can easily do. */ | ||
| 289 | #define COMMON_MULTIPLE(a, b) \ | ||
| 290 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | ||
| 291 | |||
| 292 | /* Some operations are so commonly executed that they are implemented | 283 | /* Some operations are so commonly executed that they are implemented |
| 293 | as macros, not functions, because otherwise runtime performance would | 284 | as macros, not functions, because otherwise runtime performance would |
| 294 | suffer too much when compiling with GCC without optimization. | 285 | suffer too much when compiling with GCC without optimization. |
| @@ -2946,7 +2937,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) | |||
| 2946 | #ifdef _MSC_VER | 2937 | #ifdef _MSC_VER |
| 2947 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ | 2938 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ |
| 2948 | Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ | 2939 | Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ |
| 2949 | static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ | 2940 | static struct Lisp_Subr GCALIGNED sname = \ |
| 2950 | { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ | 2941 | { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ |
| 2951 | | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ | 2942 | | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ |
| 2952 | { (Lisp_Object (__cdecl *)(void))fnname }, \ | 2943 | { (Lisp_Object (__cdecl *)(void))fnname }, \ |
| @@ -2954,7 +2945,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) | |||
| 2954 | Lisp_Object fnname | 2945 | Lisp_Object fnname |
| 2955 | #else /* not _MSC_VER */ | 2946 | #else /* not _MSC_VER */ |
| 2956 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ | 2947 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ |
| 2957 | static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ | 2948 | static struct Lisp_Subr GCALIGNED sname = \ |
| 2958 | { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ | 2949 | { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ |
| 2959 | { .a ## maxargs = fnname }, \ | 2950 | { .a ## maxargs = fnname }, \ |
| 2960 | minargs, maxargs, lname, intspec, 0}; \ | 2951 | minargs, maxargs, lname, intspec, 0}; \ |
diff --git a/src/thread.c b/src/thread.c index 7a670ba410b..03f5b31855e 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -26,9 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 26 | #include "coding.h" | 26 | #include "coding.h" |
| 27 | #include "syssignal.h" | 27 | #include "syssignal.h" |
| 28 | 28 | ||
| 29 | #define THREAD_ALIGNMENT COMMON_MULTIPLE (alignof (max_align_t), GCALIGNMENT) | 29 | static struct thread_state GCALIGNED main_thread; |
| 30 | |||
| 31 | static struct thread_state alignas (THREAD_ALIGNMENT) main_thread; | ||
| 32 | 30 | ||
| 33 | struct thread_state *current_thread = &main_thread; | 31 | struct thread_state *current_thread = &main_thread; |
| 34 | 32 | ||