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:
parent
3abf76da56
commit
92278640ba
2 changed files with 58 additions and 19 deletions
34
src/alloc.c
34
src/alloc.c
|
@ -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
|
||||
|
|
43
src/lisp.h
43
src/lisp.h
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue