From: Paul Eggert Date: Sat, 7 Apr 2012 19:18:52 +0000 (-0700) Subject: Avoid unnecessary pointer scanning in garbage collection (Bug#10780). X-Git-Tag: emacs-24.2.90~471^2~388 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e3fb2efb80ee8beebf7963228c4508496ebf24fa;p=emacs.git Avoid unnecessary pointer scanning in garbage collection (Bug#10780). * alloc.c (POINTERS_MIGHT_HIDE_IN_OBJECTS): New macro. (mark_memory): Mark Lisp_Objects only if pointers might hide in objects, as mark_maybe_pointer will catch them otherwise. (GC_LISP_OBJECT_ALIGNMENT): Remove; no longer needed. * s/gnu-linux.h (GC_LISP_OBJECT_ALIGNMENT) [__mc68000__]: Likewise. --- diff --git a/src/ChangeLog b/src/ChangeLog index 042048a96a3..d4a031baab3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2012-04-07 Paul Eggert + + Avoid unnecessary pointer scanning in garbage collection (Bug#10780). + * alloc.c (POINTERS_MIGHT_HIDE_IN_OBJECTS): New macro. + (mark_memory): Mark Lisp_Objects only if pointers might hide in + objects, as mark_maybe_pointer will catch them otherwise. + (GC_LISP_OBJECT_ALIGNMENT): Remove; no longer needed. + * s/gnu-linux.h (GC_LISP_OBJECT_ALIGNMENT) [__mc68000__]: Likewise. + 2012-04-07 Paul Eggert Fix typo that broke non-Windows builds. diff --git a/src/alloc.c b/src/alloc.c index f85661415cd..4cb0ae04664 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4251,23 +4251,38 @@ mark_maybe_pointer (void *p) } -/* Alignment of Lisp_Object and pointer values. Use offsetof, as it - sometimes returns a smaller alignment than GCC's __alignof__ and - mark_memory might miss objects if __alignof__ were used. For - example, on x86 with WIDE_EMACS_INT, __alignof__ (Lisp_Object) is 8 - but GC_LISP_OBJECT_ALIGNMENT should be 4. */ -#ifndef GC_LISP_OBJECT_ALIGNMENT -# define GC_LISP_OBJECT_ALIGNMENT offsetof (struct {char a; Lisp_Object b;}, b) -#endif +/* Alignment of pointer values. Use offsetof, as it sometimes returns + a smaller alignment than GCC's __alignof__ and mark_memory might + miss objects if __alignof__ were used. */ #define GC_POINTER_ALIGNMENT offsetof (struct {char a; void *b;}, b) +/* Define POINTERS_MIGHT_HIDE_IN_OBJECTS to 1 if marking via C pointers does + not suffice, which is the typical case. A host where a Lisp_Object is + wider than a pointer might allocate a Lisp_Object in non-adjacent halves. + If USE_LSB_TAG, the bottom half is not a valid pointer, but it should + suffice to widen it to to a Lisp_Object and check it that way. */ +#if defined USE_LSB_TAG || UINTPTR_MAX >> VALBITS != 0 +# if !defined USE_LSB_TAG && UINTPTR_MAX >> VALBITS >> GCTYPEBITS != 0 + /* If tag bits straddle pointer-word boundaries, neither mark_maybe_pointer + nor mark_maybe_object can follow the pointers. This should not occur on + any practical porting target. */ +# error "MSB type bits straddle pointer-word boundaries" +# endif + /* Marking via C pointers does not suffice, because Lisp_Objects contain + pointer words that hold pointers ORed with type bits. */ +# define POINTERS_MIGHT_HIDE_IN_OBJECTS 1 +#else + /* Marking via C pointers suffices, because Lisp_Objects contain pointer + words that hold unmodified pointers. */ +# define POINTERS_MIGHT_HIDE_IN_OBJECTS 0 +#endif + /* Mark Lisp objects referenced from the address range START+OFFSET..END or END+OFFSET..START. */ static void mark_memory (void *start, void *end) { - Lisp_Object *p; void **pp; int i; @@ -4284,11 +4299,6 @@ mark_memory (void *start, void *end) end = tem; } - /* Mark Lisp_Objects. */ - 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 only a pointer to them remains. Example: @@ -4310,17 +4320,10 @@ mark_memory (void *start, void *end) for (pp = start; (void *) pp < end; pp++) for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT) { - void *w = *(void **) ((char *) pp + i); - mark_maybe_pointer (w); - -#ifdef USE_LSB_TAG - /* A host where a Lisp_Object is wider than a pointer might - allocate a Lisp_Object in non-adjacent halves. If - USE_LSB_TAG, the bottom half is not a valid pointer, so - widen it to to a Lisp_Object and check it that way. */ - if (sizeof w < sizeof (Lisp_Object)) - mark_maybe_object (widen_to_Lisp_Object (w)); -#endif + void *p = *(void **) ((char *) pp + i); + mark_maybe_pointer (p); + if (POINTERS_MIGHT_HIDE_IN_OBJECTS) + mark_maybe_object (widen_to_Lisp_Object (p)); } } diff --git a/src/s/gnu-linux.h b/src/s/gnu-linux.h index b54bd985e6b..c1233c0e6ce 100644 --- a/src/s/gnu-linux.h +++ b/src/s/gnu-linux.h @@ -146,9 +146,6 @@ along with GNU Emacs. If not, see . */ || defined __ia64__ || defined __sh__ #define GC_SETJMP_WORKS 1 #define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS -#ifdef __mc68000__ -#define GC_LISP_OBJECT_ALIGNMENT 2 -#endif #ifdef __ia64__ #define GC_MARK_SECONDARY_STACK() \ do { \