From 35d50e6108c6edbac93e80aa1b9998dc6ac19054 Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Sat, 30 May 2020 13:23:24 +0000 Subject: [PATCH] Be more aggressive in marking objects during GC (bug#41321) * src/alloc.c (maybe_lisp_pointer): Remove. (mark_memory): Mark 32-bit words that might be the only reference to a Lisp_Symbol. --- src/alloc.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 1c6b664b22..3938cdf054 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4585,18 +4585,6 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts) mark_maybe_object (*array); } -/* Return true if P might point to Lisp data that can be garbage - 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. */ - -static bool -maybe_lisp_pointer (void *p) -{ - return (uintptr_t) p % LISP_ALIGNMENT == 0; -} - /* If P points to Lisp data, mark that as live if it isn't already marked. */ @@ -4609,9 +4597,6 @@ mark_maybe_pointer (void *p) VALGRIND_MAKE_MEM_DEFINED (&p, sizeof (p)); #endif - if (!maybe_lisp_pointer (p)) - return; - if (pdumper_object_p (p)) { int type = pdumper_find_object_type (p); @@ -4715,12 +4700,22 @@ mark_memory (void const *start, void const *end) for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) { - mark_maybe_pointer (*(void *const *) pp); - - verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0); - if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT - || (uintptr_t) pp % alignof (Lisp_Object) == 0) - mark_maybe_object (*(Lisp_Object const *) pp); + uintptr_t offset = (uintptr_t) *(void *const *) pp; + mark_maybe_pointer ((void *) offset); + /* On 32-bit --with-wide-int systems, the two halves of a + Lisp_Object may be stored non-contiguously. Therefore, we + need to recognize the lower 32 bits of a Lisp_Object encoding + a symbol, and since Qnil is binary zero, that requires adding + &lispsym. */ + if (GC_POINTER_ALIGNMENT < sizeof (Lisp_Object)) + mark_maybe_pointer ((void *) (offset + (uintptr_t) &lispsym)); + else + { + verify (alignof (Lisp_Object) % GC_POINTER_ALIGNMENT == 0); + if (alignof (Lisp_Object) == GC_POINTER_ALIGNMENT + || (uintptr_t) pp % alignof (Lisp_Object) == 0) + mark_maybe_object (*(Lisp_Object const *) pp); + } } } -- 2.27.0.rc0