[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master cf95bb0 3/6: Avoid some false matches in mark_maybe_pointer
From: |
Paul Eggert |
Subject: |
master cf95bb0 3/6: Avoid some false matches in mark_maybe_pointer |
Date: |
Mon, 31 Aug 2020 03:06:04 -0400 (EDT) |
branch: master
commit cf95bb0213908a4caab65dccfa67b4f1572babe2
Author: Paul Eggert <eggert@cs.ucla.edu>
Commit: Paul Eggert <eggert@cs.ucla.edu>
Avoid some false matches in mark_maybe_pointer
This lets Emacs avoid marking some garbage as if it were in use.
On one test platform (RHEL 7.8, Intel Xeon Silver 4116) it
sped up ‘cd lisp; make compile-always’ by a bit over 1%.
* src/alloc.c (live_string_holding, live_cons_holding)
(live_symbol_holding, live_large_vector_holding)
(live_small_vector_holding):
Count only pointers that point to a struct component,
or are a tagged pointer to the start of the struct.
Exception: for non-bool-vector pseudovectors,
count any pointer past the header, since it’s too much
of a pain to write code for every pseudovector.
(live_vector_pointer): New function.
---
src/alloc.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 70 insertions(+), 14 deletions(-)
diff --git a/src/alloc.c b/src/alloc.c
index e057107..5453c54 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4457,9 +4457,17 @@ live_string_holding (struct mem_node *m, void *p)
must not be on the free-list. */
if (0 <= offset && offset < sizeof b->strings)
{
- struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0];
- if (s->u.s.data)
- return s;
+ ptrdiff_t off = offset % sizeof b->strings[0];
+ if (off == Lisp_String
+ || off == 0
+ || off == offsetof (struct Lisp_String, u.s.size_byte)
+ || off == offsetof (struct Lisp_String, u.s.intervals)
+ || off == offsetof (struct Lisp_String, u.s.data))
+ {
+ struct Lisp_String *s = p = cp -= off;
+ if (s->u.s.data)
+ return s;
+ }
}
return NULL;
}
@@ -4489,9 +4497,15 @@ live_cons_holding (struct mem_node *m, void *p)
&& (b != cons_block
|| offset / sizeof b->conses[0] < cons_block_index))
{
- struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
- if (!deadp (s->u.s.car))
- return s;
+ ptrdiff_t off = offset % sizeof b->conses[0];
+ if (off == Lisp_Cons
+ || off == 0
+ || off == offsetof (struct Lisp_Cons, u.s.u.cdr))
+ {
+ struct Lisp_Cons *s = p = cp -= off;
+ if (!deadp (s->u.s.car))
+ return s;
+ }
}
return NULL;
}
@@ -4522,9 +4536,23 @@ live_symbol_holding (struct mem_node *m, void *p)
&& (b != symbol_block
|| offset / sizeof b->symbols[0] < symbol_block_index))
{
- struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
- if (!deadp (s->u.s.function))
- return s;
+ ptrdiff_t off = offset % sizeof b->symbols[0];
+ if (off == Lisp_Symbol
+
+ /* Use u's offset since '|| off == 0' would run afoul of gcc
+ -Wlogical-op, as Lisp_Symbol happens to be zero. */
+ || off == offsetof (struct Lisp_Symbol, u)
+
+ || off == offsetof (struct Lisp_Symbol, u.s.name)
+ || off == offsetof (struct Lisp_Symbol, u.s.val)
+ || off == offsetof (struct Lisp_Symbol, u.s.function)
+ || off == offsetof (struct Lisp_Symbol, u.s.plist)
+ || off == offsetof (struct Lisp_Symbol, u.s.next))
+ {
+ struct Lisp_Symbol *s = p = cp -= off;
+ if (!deadp (s->u.s.function))
+ return s;
+ }
}
return NULL;
}
@@ -4571,6 +4599,37 @@ live_float_p (struct mem_node *m, void *p)
return live_float_holding (m, p) == p;
}
+/* Return VECTOR if P points within it, NULL otherwise. */
+
+static struct Lisp_Vector *
+live_vector_pointer (struct Lisp_Vector *vector, void *p)
+{
+ void *vvector = vector;
+ char *cvector = vvector;
+ char *cp = p;
+ ptrdiff_t offset = cp - cvector;
+ return ((offset == Lisp_Vectorlike
+ || offset == 0
+ || (sizeof vector->header <= offset
+ && offset < vector_nbytes (vector)
+ && (! (vector->header.size & PSEUDOVECTOR_FLAG)
+ ? (offsetof (struct Lisp_Vector, contents) <= offset
+ && (((offset - offsetof (struct Lisp_Vector, contents))
+ % word_size)
+ == 0))
+ /* For non-bool-vector pseudovectors, treat any pointer
+ past the header as valid since it's too much of a pain
+ to write special-case code for every pseudovector. */
+ : (! PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BOOL_VECTOR)
+ || offset == offsetof (struct Lisp_Bool_Vector, size)
+ || (offsetof (struct Lisp_Bool_Vector, data) <= offset
+ && (((offset
+ - offsetof (struct Lisp_Bool_Vector, data))
+ % sizeof (bits_word))
+ == 0))))))
+ ? vector : NULL);
+}
+
/* If P is a pointer to a live, large vector-like object, return the object.
Otherwise, return nil.
M is a pointer to the mem_block for P. */
@@ -4579,10 +4638,7 @@ static struct Lisp_Vector *
live_large_vector_holding (struct mem_node *m, void *p)
{
eassert (m->type == MEM_TYPE_VECTORLIKE);
- struct Lisp_Vector *vp = p;
- struct Lisp_Vector *vector = large_vector_vec (m->start);
- struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector));
- return vector <= vp && vp < next ? vector : NULL;
+ return live_vector_pointer (large_vector_vec (m->start), p);
}
static bool
@@ -4612,7 +4668,7 @@ live_small_vector_holding (struct mem_node *m, void *p)
{
struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector));
if (vp < next && !PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE))
- return vector;
+ return live_vector_pointer (vector, vp);
vector = next;
}
return NULL;
- master updated (886ba06 -> 416195f), Paul Eggert, 2020/08/31
- master 2ff930d 1/6: Fix GC bug with Lisp floats and --with-wide-int, Paul Eggert, 2020/08/31
- master 7e2f6f8 4/6: Remove mark_maybe_object, Paul Eggert, 2020/08/31
- master cf95bb0 3/6: Avoid some false matches in mark_maybe_pointer,
Paul Eggert <=
- master aa1b586 2/6: Omit no-longer-needed stack mark_maybe_object, Paul Eggert, 2020/08/31
- master 89350d4 5/6: Use mark_objects elsewhere too, Paul Eggert, 2020/08/31
- master 416195f 6/6: * src/lisp.h (lisp_h_XPL, XPL): Remove; unused., Paul Eggert, 2020/08/31