emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 9227864: Further fix for aborts due to GC losing pseudovectors


From: Paul Eggert
Subject: master 9227864: Further fix for aborts due to GC losing pseudovectors
Date: Tue, 26 May 2020 02:06:46 -0400 (EDT)

branch: master
commit 92278640babbfe1383ebba3baf3bc10278a01050
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/alloc.c | 34 ++++++++++++++++------------------
 src/lisp.h  | 43 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index 89fe96a..77d5d28 100644
--- a/src/alloc.c
+++ b/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
diff --git a/src/lisp.h b/src/lisp.h
index 85bdc17..937052f 100644
--- a/src/lisp.h
+++ b/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 */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]