mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-26 07:33:47 +00:00
* src/alloc.c: Avoid O(N²) complexity when unchaining markers (bug#24548).
Unchain all dead markers with a single scan of the markers list, instead of calling the O(N) 'unchain_marker' N times. (unchain_dead_markers): New function. (sweep_buffers): Use it. (gc_sweep): Sweep buffers before markers. (sweep_misc): Check that markers have been unchained when reclaiming them.
This commit is contained in:
parent
6695c1be51
commit
cf3164523b
24
src/alloc.c
24
src/alloc.c
@ -7095,7 +7095,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 +7144,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 +7179,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 +7199,8 @@ gc_sweep (void)
|
||||
sweep_floats ();
|
||||
sweep_intervals ();
|
||||
sweep_symbols ();
|
||||
sweep_misc ();
|
||||
sweep_buffers ();
|
||||
sweep_misc ();
|
||||
sweep_vectors ();
|
||||
check_string_bytes (!noninteractive);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user