Fix alignment-related core dump during GC.
* 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.
This commit is contained in:
parent
21ce824514
commit
7c5ee88ecb
4 changed files with 34 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
37
src/alloc.c
37
src/alloc.c
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue