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.
This commit is contained in:
parent
b5385551e3
commit
e3fb2efb80
3 changed files with 37 additions and 28 deletions
|
@ -1,3 +1,12 @@
|
|||
2012-04-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <eggert@cs.ucla.edu>
|
||||
|
||||
Fix typo that broke non-Windows builds.
|
||||
|
|
53
src/alloc.c
53
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,9 +146,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|| 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 { \
|
||||
|
|
Loading…
Add table
Reference in a new issue