[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#24548: 25.2.50; Long GC delays with many non-detached markers (PATCH
From: |
Stefan Monnier |
Subject: |
bug#24548: 25.2.50; Long GC delays with many non-detached markers (PATCH) |
Date: |
Fri, 23 Mar 2018 10:22:18 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) |
> But if we call unchain_collected_markers from within the sweep phase
> (e.g. on every buffer we find), `gcmarkbit` should be
> sufficient/reliable. Or am I missing something?
At least the patch below seems to work as well.
Stefan
diff --git a/src/alloc.c b/src/alloc.c
index da01173fba..369592d70e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7095,7 +7091,9 @@ sweep_misc (void)
if (!mblk->markers[i].m.u_any.gcmarkbit)
{
if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker)
- unchain_marker (&mblk->markers[i].m.u_marker);
+ /* Make sure markers have been unchained from their buffer
+ in sweep_buffer before we collect them. */
+ eassert (!mblk->markers[i].m.u_marker.buffer);
else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Finalizer)
unchain_finalizer (&mblk->markers[i].m.u_finalizer);
#ifdef HAVE_MODULES
@@ -7142,6 +7140,23 @@ sweep_misc (void)
total_free_markers = num_free;
}
+/* Remove BUFFER's markers that are due to be swept. This is needed since
+ we treat BUF_MARKERS and markers's `next' field as weak pointers. */
+static void
+unchain_dead_markers (struct buffer *buffer)
+{
+ struct Lisp_Marker *this, **prev = &BUF_MARKERS (buffer);
+
+ while ((this = *prev))
+ if (this->gcmarkbit)
+ prev = &this->next;
+ else
+ {
+ this->buffer = NULL;
+ *prev = this->next;
+ }
+}
+
NO_INLINE /* For better stack traces */
static void
sweep_buffers (void)
@@ -7160,6 +7175,7 @@ sweep_buffers (void)
VECTOR_UNMARK (buffer);
/* Do not use buffer_(set|get)_intervals here. */
buffer->text->intervals = balance_intervals (buffer->text->intervals);
+ unchain_dead_markers (buffer);
total_buffers++;
bprev = &buffer->next;
}
@@ -7179,8 +7195,8 @@ gc_sweep (void)
sweep_floats ();
sweep_intervals ();
sweep_symbols ();
- sweep_misc ();
sweep_buffers ();
+ sweep_misc ();
sweep_vectors ();
check_string_bytes (!noninteractive);
}