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.
This commit is contained in:
Paul Eggert 2020-05-25 23:06:07 -07:00
parent 3abf76da56
commit 92278640ba
2 changed files with 58 additions and 19 deletions

View file

@ -655,24 +655,22 @@ buffer_memory_full (ptrdiff_t nbytes)
#define COMMON_MULTIPLE(a, b) \
((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b))
/* A lower bound on the alignment of malloc. Although this bound is
incorrect for some buggy malloc implementations (e.g., MinGW circa
2020), the bugs should not matter for the way this bound is used
since the correct bound is also a multiple of LISP_ALIGNMENT on the
buggy platforms. */
enum { MALLOC_ALIGNMENT_BOUND = alignof (max_align_t) };
/* A lower bound on the alignment of Lisp objects allocated on the heap.
All such objects must have an address that is a multiple of LISP_ALIGNMENT;
otherwise maybe_lisp_pointer can issue false negatives, causing crashes.
On all practical Emacs targets, sizeof (struct Lisp_Float) == 8 and
since GCALIGNMENT also equals 8 there's little point to optimizing
for impractical targets. */
enum { LISP_ALIGNMENT = GCALIGNMENT };
/* Alignment needed for memory blocks that are allocated via malloc
and that contain Lisp objects. On typical hosts malloc already
aligns sufficiently, but extra work is needed on oddball hosts
where Emacs would crash if malloc returned a non-GCALIGNED pointer. */
enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x;
GCALIGNED_UNION_MEMBER }) };
verify (LISP_ALIGNMENT % GCALIGNMENT == 0);
/* True if malloc (N) is known to return storage suitably aligned for
Lisp objects whenever N is a multiple of LISP_ALIGNMENT. */
enum { MALLOC_IS_LISP_ALIGNED = MALLOC_ALIGNMENT_BOUND % LISP_ALIGNMENT == 0 };
Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In
practice this is true whenever alignof (max_align_t) is also a
multiple of LISP_ALIGNMENT. This works even for buggy platforms
like MinGW circa 2020, where alignof (max_align_t) is 16 even though
the malloc alignment is only 8, and where Emacs still works because
it never does anything that requires an alignment of 16. */
enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 };
/* If compiled with XMALLOC_BLOCK_INPUT_CHECK, define a symbol
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)
collected, and false otherwise (i.e., false if it is easy to see
that P cannot point to Lisp data that can be garbage collected).
Symbols are implemented via offsets not pointers, but the offsets
are also multiples of LISP_ALIGNMENT. */
are also multiples of GCALIGNMENT. */
static bool
maybe_lisp_pointer (void *p)
{
return (uintptr_t) p % LISP_ALIGNMENT == 0;
return (uintptr_t) p % GCALIGNMENT == 0;
}
/* If P points to Lisp data, mark that as live if it isn't already

View file

@ -277,7 +277,8 @@ error !;
allocation in a containing union that has GCALIGNED_UNION_MEMBER)
and does not contain a GC-aligned struct or union, putting
GCALIGNED_STRUCT after its closing '}' can help the compiler
generate better code.
generate better code. Also, such structs should be added to the
emacs_align_type union.
Although these macros are reasonably portable, they are not
guaranteed on non-GCC platforms, as C11 does not require support
@ -5059,6 +5060,46 @@ maybe_gc (void)
maybe_garbage_collect ();
}
/* A type with alignment at least as large as any object that Emacs
allocates. This is not max_align_t because some platforms (e.g.,
mingw) have buggy malloc implementations that do not align for
max_align_t. This union contains types of all GCALIGNED_STRUCT
components visible here. */
union emacs_align_type
{
struct Lisp_Bool_Vector Lisp_Bool_Vector;
struct Lisp_Char_Table Lisp_Char_Table;
struct Lisp_CondVar Lisp_CondVar;
struct Lisp_Finalizer Lisp_Finalizer;
struct Lisp_Float Lisp_Float;
struct Lisp_Hash_Table Lisp_Hash_Table;
struct Lisp_Marker Lisp_Marker;
struct Lisp_Misc_Ptr Lisp_Misc_Ptr;
struct Lisp_Mutex Lisp_Mutex;
struct Lisp_Overlay Lisp_Overlay;
struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table;
struct Lisp_Subr Lisp_Subr;
struct Lisp_User_Ptr Lisp_User_Ptr;
struct Lisp_Vector Lisp_Vector;
struct thread_state thread_state;
/* Omit the following since they would require including bignum.h,
frame.h etc., and in practice their alignments never exceed that
of the structs already listed. */
#if 0
struct frame frame;
struct Lisp_Bignum Lisp_Bignum;
struct Lisp_Module_Function Lisp_Module_Function;
struct Lisp_Process Lisp_Process;
struct save_window_data save_window_data;
struct scroll_bar scroll_bar;
struct terminal terminal;
struct window window;
struct xwidget xwidget;
struct xwidget_view xwidget_view;
#endif
};
INLINE_HEADER_END
#endif /* EMACS_LISP_H */