From f6472cc8e2fdcfd7365240783f34e101fe44142b Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 11 Jul 2021 00:54:32 -0700 Subject: [PATCH 2/2] Make pdumper-marking pickier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent some false-positives in conservative GC marking. This doesn’t fix any correctness bugs; it’s merely to reclaim some memory instead of keeping it unnecessarily. * src/alloc.c (mark_maybe_pointer): New arg SYMBOL_ONLY. All callers changed. Check that the pointer’s tag, if any, matches the pdumper-reported type. --- src/alloc.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/alloc.c b/src/alloc.c index 752eaec135..b3668d2131 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -4740,7 +4740,7 @@ live_small_vector_p (struct mem_node *m, void *p) marked. */ static void -mark_maybe_pointer (void *p) +mark_maybe_pointer (void *p, bool symbol_only) { struct mem_node *m; @@ -4765,15 +4765,21 @@ mark_maybe_pointer (void *p) this problem, the pdumper code should grok non-initial addresses, as the non-pdumper code does. */ uintptr_t mask = VALMASK; - p = (void *) ((uintptr_t) p & mask); + void *po = (void *) ((uintptr_t) p & mask); + char *cp = p; + char *cpo = po; /* Don't use pdumper_object_p_precise here! It doesn't check the tag bits. OBJ here might be complete garbage, so we need to verify both the pointer and the tag. */ - int type = pdumper_find_object_type (p); - if (pdumper_valid_object_type_p (type)) - mark_object (type == Lisp_Symbol - ? make_lisp_symbol (p) - : make_lisp_ptr (p, type)); + int type = pdumper_find_object_type (po); + if (pdumper_valid_object_type_p (type) + && (!USE_LSB_TAG || p == po || cp - cpo == type)) + { + if (type == Lisp_Symbol) + mark_object (make_lisp_symbol (po)); + else if (!symbol_only) + mark_object (make_lisp_ptr (po, type)); + } return; } @@ -4791,6 +4797,8 @@ mark_maybe_pointer (void *p) case MEM_TYPE_CONS: { + if (symbol_only) + return; struct Lisp_Cons *h = live_cons_holding (m, p); if (!h) return; @@ -4800,6 +4808,8 @@ mark_maybe_pointer (void *p) case MEM_TYPE_STRING: { + if (symbol_only) + return; struct Lisp_String *h = live_string_holding (m, p); if (!h) return; @@ -4818,6 +4828,8 @@ mark_maybe_pointer (void *p) case MEM_TYPE_FLOAT: { + if (symbol_only) + return; struct Lisp_Float *h = live_float_holding (m, p); if (!h) return; @@ -4827,6 +4839,8 @@ mark_maybe_pointer (void *p) case MEM_TYPE_VECTORLIKE: { + if (symbol_only) + return; struct Lisp_Vector *h = live_large_vector_holding (m, p); if (!h) return; @@ -4836,6 +4850,8 @@ mark_maybe_pointer (void *p) case MEM_TYPE_VECTOR_BLOCK: { + if (symbol_only) + return; struct Lisp_Vector *h = live_small_vector_holding (m, p); if (!h) return; @@ -4897,7 +4913,7 @@ mark_memory (void const *start, void const *end) for (pp = start; (void const *) pp < end; pp += GC_POINTER_ALIGNMENT) { void *p = *(void *const *) pp; - mark_maybe_pointer (p); + mark_maybe_pointer (p, false); /* Unmask any struct Lisp_Symbol pointer that make_lisp_symbol previously disguised by adding the address of 'lispsym'. @@ -4906,7 +4922,7 @@ mark_memory (void const *start, void const *end) non-adjacent words and P might be the low-order word's value. */ intptr_t ip; INT_ADD_WRAPV ((intptr_t) p, (intptr_t) lispsym, &ip); - mark_maybe_pointer ((void *) ip); + mark_maybe_pointer ((void *) ip, true); } } -- 2.31.1