]> code.delx.au - gnu-emacs/commitdiff
Fix alignment-related core dump during GC.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 7 Oct 2011 07:23:44 +0000 (00:23 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 7 Oct 2011 07:23:44 +0000 (00:23 -0700)
* configure.in (GC_LISP_OBJECT_ALIGNMENT): Remove.
This is now done by src/alloc.c.
* src/alloc.c (GC_LISP_OBJECT_ALIGNMENT): Use offsetof, not __alignof__
or sizeof.  __alignof__ gives the wrong answer on Fedora x86-64
with GCC 4.6.1 when configured with CC='gcc -m32' --with-wide-int;
this makes Emacs dump core during garbage collection on rare
occasions.  sizeof is obviously inferior to offsetof here, so
stick with offsetof.
(GC_POINTER_ALIGNMENT): New macro.
(mark_memory): Omit 3rd (offset) arg; caller changed.
Don't assume EMACS_INT alignment is the same as pointer alignment.

ChangeLog
configure.in
src/ChangeLog
src/alloc.c

index 6f17289a6142b8979eb8bab01155ab46e76e1a9b..bdccef5941cb9ad3dd67c0df0a6791f35072dfa9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-10-07  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * configure.in (GC_LISP_OBJECT_ALIGNMENT): Remove.
+       This is now done by src/alloc.c.
+
 2011-10-02  Richard Stallman  <rms@gnu.org>
 
        * configure.in: Rename xlinux_first_failure to xgnu_linux_first_failure
index b8de80baf5d02fd0bece200a399a7c1db4a46482..57cc4dcded8d88af0aa2389c53a4c16588e9410c 100644 (file)
@@ -3663,9 +3663,6 @@ AH_BOTTOM([
   /* GC_SETJMP_WORKS is nearly always appropriate for GCC.  */
 #    define GC_SETJMP_WORKS 1
 #  endif
-#  ifndef GC_LISP_OBJECT_ALIGNMENT
-#    define GC_LISP_OBJECT_ALIGNMENT (__alignof__ (Lisp_Object))
-#  endif
 #endif
 
 #endif /* EMACS_CONFIG_H */
index b697ee433769a60cb547c3e0701c22b90334e5cd..d2c069b7351ed0cfccc4e72a9ab04a65328d8b3a 100644 (file)
@@ -1,3 +1,15 @@
+2011-10-07  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * alloc.c (GC_LISP_OBJECT_ALIGNMENT): Use offsetof, not __alignof__
+       or sizeof.  __alignof__ gives the wrong answer on Fedora x86-64
+       with GCC 4.6.1 when configured with CC='gcc -m32' --with-wide-int;
+       this makes Emacs dump core during garbage collection on rare
+       occasions.  sizeof is obviously inferior to offsetof here, so
+       stick with offsetof.
+       (GC_POINTER_ALIGNMENT): New macro.
+       (mark_memory): Omit 3rd (offset) arg; caller changed.
+       Don't assume EMACS_INT alignment is the same as pointer alignment.
+
 2011-10-03  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * keyboard.c (read_key_sequence_remapped): New var.
index ead5c8a8ca4bb3818f49ae08d417e75de3aea7bf..f4db3abbd9358a9bc4dc03c926954eb4a7c53705 100644 (file)
@@ -393,7 +393,7 @@ static int live_symbol_p (struct mem_node *, void *);
 static int live_float_p (struct mem_node *, void *);
 static int live_misc_p (struct mem_node *, void *);
 static void mark_maybe_object (Lisp_Object);
-static void mark_memory (void *, void *, int);
+static void mark_memory (void *, void *);
 static void mem_init (void);
 static struct mem_node *mem_insert (void *, void *, enum mem_type);
 static void mem_insert_fixup (struct mem_node *);
@@ -4235,14 +4235,20 @@ mark_maybe_pointer (void *p)
 }
 
 
+#ifndef GC_LISP_OBJECT_ALIGNMENT
+# define GC_LISP_OBJECT_ALIGNMENT offsetof (struct {char a; Lisp_Object b;}, b)
+#endif
+#define GC_POINTER_ALIGNMENT offsetof (struct {char a; void *b;}, b)
+
 /* Mark Lisp objects referenced from the address range START+OFFSET..END
    or END+OFFSET..START. */
 
 static void
-mark_memory (void *start, void *end, int offset)
+mark_memory (void *start, void *end)
 {
   Lisp_Object *p;
   void **pp;
+  int i;
 
 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
   nzombies = 0;
@@ -4258,8 +4264,9 @@ mark_memory (void *start, void *end, int offset)
     }
 
   /* Mark Lisp_Objects.  */
-  for (p = (Lisp_Object *) ((char *) start + offset); (void *) p < end; ++p)
-    mark_maybe_object (*p);
+  for (p = start; (void *) p < end; p++)
+    for (i = 0; i < sizeof *p; i += GC_LISP_OBJECT_ALIGNMENT)
+      mark_maybe_object (*(Lisp_Object *) ((char *) p + i));
 
   /* Mark Lisp data pointed to.  This is necessary because, in some
      situations, the C compiler optimizes Lisp objects away, so that
@@ -4279,8 +4286,9 @@ mark_memory (void *start, void *end, int offset)
      away.  The only reference to the life string is through the
      pointer `s'.  */
 
-  for (pp = (void **) ((char *) start + offset); (void *) pp < end; ++pp)
-    mark_maybe_pointer (*pp);
+  for (pp = start; (void *) pp < end; pp++)
+    for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT)
+      mark_maybe_pointer (*(void **) ((char *) pp + i));
 }
 
 /* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in
@@ -4454,15 +4462,11 @@ dump_zombies (void)
    pass starting at the start of the stack + 2.  Likewise, if the
    minimal alignment of Lisp_Objects on the stack is 1, four passes
    would be necessary, each one starting with one byte more offset
-   from the stack start.
-
-   The current code assumes by default that Lisp_Objects are aligned
-   equally on the stack.  */
+   from the stack start.  */
 
 static void
 mark_stack (void)
 {
-  int i;
   void *end;
 
 #ifdef HAVE___BUILTIN_UNWIND_INIT
@@ -4520,15 +4524,8 @@ mark_stack (void)
   /* This assumes that the stack is a contiguous region in memory.  If
      that's not the case, something has to be done here to iterate
      over the stack segments.  */
-#ifndef GC_LISP_OBJECT_ALIGNMENT
-#ifdef __GNUC__
-#define GC_LISP_OBJECT_ALIGNMENT __alignof__ (Lisp_Object)
-#else
-#define GC_LISP_OBJECT_ALIGNMENT sizeof (Lisp_Object)
-#endif
-#endif
-  for (i = 0; i < sizeof (Lisp_Object); i += GC_LISP_OBJECT_ALIGNMENT)
-    mark_memory (stack_base, end, i);
+  mark_memory (stack_base, end);
+
   /* Allow for marking a secondary stack, like the register stack on the
      ia64.  */
 #ifdef GC_MARK_SECONDARY_STACK