diff options
| author | Paul Eggert | 2020-05-25 23:06:07 -0700 |
|---|---|---|
| committer | Paul Eggert | 2020-05-25 23:06:41 -0700 |
| commit | 92278640babbfe1383ebba3baf3bc10278a01050 (patch) | |
| tree | adb7c8dabf882ab9e6677517d254d8e3ab5ae116 /src | |
| parent | 3abf76da564ff8526bbcba6b92dfb7b97cb87779 (diff) | |
| download | emacs-92278640babbfe1383ebba3baf3bc10278a01050.tar.gz emacs-92278640babbfe1383ebba3baf3bc10278a01050.zip | |
Further fix for aborts due to GC losing pseudovectors
* src/alloc.c (MALLOC_ALIGNMENT_BOUND): Remove.
(LISP_ALIGNMENT): Go back to yesterday’s version, except use
union emacs_align_type instead of max_align_t.
(MALLOC_IS_LISP_ALIGNED): Go back to yesterday’s version.
(maybe_lisp_pointer): Check against GCALIGNMENT, not LISP_ALIGNMENT.
* src/lisp.h (union emacs_align_type): Bring back.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 34 | ||||
| -rw-r--r-- | src/lisp.h | 43 |
2 files changed, 58 insertions, 19 deletions
diff --git a/src/alloc.c b/src/alloc.c index 89fe96a2349..77d5d2839a2 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -655,24 +655,22 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 655 | #define COMMON_MULTIPLE(a, b) \ | 655 | #define COMMON_MULTIPLE(a, b) \ |
| 656 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | 656 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) |
| 657 | 657 | ||
| 658 | /* A lower bound on the alignment of malloc. Although this bound is | 658 | /* Alignment needed for memory blocks that are allocated via malloc |
| 659 | incorrect for some buggy malloc implementations (e.g., MinGW circa | 659 | and that contain Lisp objects. On typical hosts malloc already |
| 660 | 2020), the bugs should not matter for the way this bound is used | 660 | aligns sufficiently, but extra work is needed on oddball hosts |
| 661 | since the correct bound is also a multiple of LISP_ALIGNMENT on the | 661 | where Emacs would crash if malloc returned a non-GCALIGNED pointer. */ |
| 662 | buggy platforms. */ | 662 | enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x; |
| 663 | enum { MALLOC_ALIGNMENT_BOUND = alignof (max_align_t) }; | 663 | GCALIGNED_UNION_MEMBER }) }; |
| 664 | 664 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); | |
| 665 | /* A lower bound on the alignment of Lisp objects allocated on the heap. | ||
| 666 | All such objects must have an address that is a multiple of LISP_ALIGNMENT; | ||
| 667 | otherwise maybe_lisp_pointer can issue false negatives, causing crashes. | ||
| 668 | On all practical Emacs targets, sizeof (struct Lisp_Float) == 8 and | ||
| 669 | since GCALIGNMENT also equals 8 there's little point to optimizing | ||
| 670 | for impractical targets. */ | ||
| 671 | enum { LISP_ALIGNMENT = GCALIGNMENT }; | ||
| 672 | 665 | ||
| 673 | /* True if malloc (N) is known to return storage suitably aligned for | 666 | /* True if malloc (N) is known to return storage suitably aligned for |
| 674 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. */ | 667 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In |
| 675 | enum { MALLOC_IS_LISP_ALIGNED = MALLOC_ALIGNMENT_BOUND % LISP_ALIGNMENT == 0 }; | 668 | practice this is true whenever alignof (max_align_t) is also a |
| 669 | multiple of LISP_ALIGNMENT. This works even for buggy platforms | ||
| 670 | like MinGW circa 2020, where alignof (max_align_t) is 16 even though | ||
| 671 | the malloc alignment is only 8, and where Emacs still works because | ||
| 672 | it never does anything that requires an alignment of 16. */ | ||
| 673 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | ||
| 676 | 674 | ||
| 677 | /* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol | 675 | /* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol |
| 678 | BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. | 676 | BLOCK_INPUT_IN_MEMORY_ALLOCATORS that is visible to the debugger. |
| @@ -4653,12 +4651,12 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts) | |||
| 4653 | collected, and false otherwise (i.e., false if it is easy to see | 4651 | collected, and false otherwise (i.e., false if it is easy to see |
| 4654 | that P cannot point to Lisp data that can be garbage collected). | 4652 | that P cannot point to Lisp data that can be garbage collected). |
| 4655 | Symbols are implemented via offsets not pointers, but the offsets | 4653 | Symbols are implemented via offsets not pointers, but the offsets |
| 4656 | are also multiples of LISP_ALIGNMENT. */ | 4654 | are also multiples of GCALIGNMENT. */ |
| 4657 | 4655 | ||
| 4658 | static bool | 4656 | static bool |
| 4659 | maybe_lisp_pointer (void *p) | 4657 | maybe_lisp_pointer (void *p) |
| 4660 | { | 4658 | { |
| 4661 | return (uintptr_t) p % LISP_ALIGNMENT == 0; | 4659 | return (uintptr_t) p % GCALIGNMENT == 0; |
| 4662 | } | 4660 | } |
| 4663 | 4661 | ||
| 4664 | /* If P points to Lisp data, mark that as live if it isn't already | 4662 | /* If P points to Lisp data, mark that as live if it isn't already |
diff --git a/src/lisp.h b/src/lisp.h index 85bdc172b20..937052f6df8 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -277,7 +277,8 @@ error !; | |||
| 277 | allocation in a containing union that has GCALIGNED_UNION_MEMBER) | 277 | allocation in a containing union that has GCALIGNED_UNION_MEMBER) |
| 278 | and does not contain a GC-aligned struct or union, putting | 278 | and does not contain a GC-aligned struct or union, putting |
| 279 | GCALIGNED_STRUCT after its closing '}' can help the compiler | 279 | GCALIGNED_STRUCT after its closing '}' can help the compiler |
| 280 | generate better code. | 280 | generate better code. Also, such structs should be added to the |
| 281 | emacs_align_type union. | ||
| 281 | 282 | ||
| 282 | Although these macros are reasonably portable, they are not | 283 | Although these macros are reasonably portable, they are not |
| 283 | guaranteed on non-GCC platforms, as C11 does not require support | 284 | guaranteed on non-GCC platforms, as C11 does not require support |
| @@ -5059,6 +5060,46 @@ maybe_gc (void) | |||
| 5059 | maybe_garbage_collect (); | 5060 | maybe_garbage_collect (); |
| 5060 | } | 5061 | } |
| 5061 | 5062 | ||
| 5063 | /* A type with alignment at least as large as any object that Emacs | ||
| 5064 | allocates. This is not max_align_t because some platforms (e.g., | ||
| 5065 | mingw) have buggy malloc implementations that do not align for | ||
| 5066 | max_align_t. This union contains types of all GCALIGNED_STRUCT | ||
| 5067 | components visible here. */ | ||
| 5068 | union emacs_align_type | ||
| 5069 | { | ||
| 5070 | struct Lisp_Bool_Vector Lisp_Bool_Vector; | ||
| 5071 | struct Lisp_Char_Table Lisp_Char_Table; | ||
| 5072 | struct Lisp_CondVar Lisp_CondVar; | ||
| 5073 | struct Lisp_Finalizer Lisp_Finalizer; | ||
| 5074 | struct Lisp_Float Lisp_Float; | ||
| 5075 | struct Lisp_Hash_Table Lisp_Hash_Table; | ||
| 5076 | struct Lisp_Marker Lisp_Marker; | ||
| 5077 | struct Lisp_Misc_Ptr Lisp_Misc_Ptr; | ||
| 5078 | struct Lisp_Mutex Lisp_Mutex; | ||
| 5079 | struct Lisp_Overlay Lisp_Overlay; | ||
| 5080 | struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table; | ||
| 5081 | struct Lisp_Subr Lisp_Subr; | ||
| 5082 | struct Lisp_User_Ptr Lisp_User_Ptr; | ||
| 5083 | struct Lisp_Vector Lisp_Vector; | ||
| 5084 | struct thread_state thread_state; | ||
| 5085 | |||
| 5086 | /* Omit the following since they would require including bignum.h, | ||
| 5087 | frame.h etc., and in practice their alignments never exceed that | ||
| 5088 | of the structs already listed. */ | ||
| 5089 | #if 0 | ||
| 5090 | struct frame frame; | ||
| 5091 | struct Lisp_Bignum Lisp_Bignum; | ||
| 5092 | struct Lisp_Module_Function Lisp_Module_Function; | ||
| 5093 | struct Lisp_Process Lisp_Process; | ||
| 5094 | struct save_window_data save_window_data; | ||
| 5095 | struct scroll_bar scroll_bar; | ||
| 5096 | struct terminal terminal; | ||
| 5097 | struct window window; | ||
| 5098 | struct xwidget xwidget; | ||
| 5099 | struct xwidget_view xwidget_view; | ||
| 5100 | #endif | ||
| 5101 | }; | ||
| 5102 | |||
| 5062 | INLINE_HEADER_END | 5103 | INLINE_HEADER_END |
| 5063 | 5104 | ||
| 5064 | #endif /* EMACS_LISP_H */ | 5105 | #endif /* EMACS_LISP_H */ |