From d17337e501a189c1d46f758e10c6c2842cafff17 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 19 Jul 2012 07:55:59 +0400 Subject: [PATCH] New macro to iterate over all buffers, miscellaneous cleanups. * lisp.h (all_buffers): Remove declaration. * buffer.h (all_buffers): Add declaration, with comment. (for_each_buffer): New macro. * alloc.c (Fgarbage_collect, mark_object): Use it. * buffer.c (Fkill_buffer, Fbuffer_swap_text, Fset_buffer_multibyte) (init_buffer): Likewise. * data.c (Fset_default): Likewise. * coding.c (code_conversion_restore): Remove redundant check for dead buffer. * buffer.c (Fkill_buffer): Likewise. Remove obsolete comment. --- src/ChangeLog | 15 +++++- src/alloc.c | 146 +++++++++++++++++++++++--------------------------- src/buffer.c | 12 ++--- src/buffer.h | 9 ++++ src/coding.c | 2 +- src/data.c | 2 +- src/lisp.h | 1 - 7 files changed, 98 insertions(+), 89 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 5a7a981926..73632c26bf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2012-07-19 Dmitry Antipov + + New macro to iterate over all buffers, miscellaneous cleanups. + * lisp.h (all_buffers): Remove declaration. + * buffer.h (all_buffers): Add declaration, with comment. + (for_each_buffer): New macro. + * alloc.c (Fgarbage_collect, mark_object): Use it. + * buffer.c (Fkill_buffer, Fbuffer_swap_text, Fset_buffer_multibyte) + (init_buffer): Likewise. + * data.c (Fset_default): Likewise. + * coding.c (code_conversion_restore): Remove redundant check + for dead buffer. + * buffer.c (Fkill_buffer): Likewise. Remove obsolete comment. + 2012-07-18 Andreas Schwab Fix bug that created negative-length intervals. @@ -110,7 +124,6 @@ * gnutls.c (emacs_gnutls_handshake): Only retry if GNUTLS_E_INTERRUPTED. -2012-07-17 Eli Zaretskii 2012-07-17 Dmitry Antipov Cleanup and convert miscellaneous checks to eassert. diff --git a/src/alloc.c b/src/alloc.c index a6980e867a..166f5b7244 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -5392,6 +5392,7 @@ See Info node `(elisp)Garbage Collection'. */) (void) { register struct specbinding *bind; + register struct buffer *nextb; char stack_top_variable; ptrdiff_t i; int message_p; @@ -5411,40 +5412,34 @@ See Info node `(elisp)Garbage Collection'. */) /* Don't keep undo information around forever. Do this early on, so it is no problem if the user quits. */ - { - register struct buffer *nextb = all_buffers; - - while (nextb) - { - /* If a buffer's undo list is Qt, that means that undo is - turned off in that buffer. Calling truncate_undo_list on - Qt tends to return NULL, which effectively turns undo back on. - So don't call truncate_undo_list if undo_list is Qt. */ - if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name)) - && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) - truncate_undo_list (nextb); - - /* Shrink buffer gaps, but skip indirect and dead buffers. */ - if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name)) - && ! nextb->text->inhibit_shrinking) - { - /* If a buffer's gap size is more than 10% of the buffer - size, or larger than 2000 bytes, then shrink it - accordingly. Keep a minimum size of 20 bytes. */ - int size = min (2000, max (20, (nextb->text->z_byte / 10))); - - if (nextb->text->gap_size > size) - { - struct buffer *save_current = current_buffer; - current_buffer = nextb; - make_gap (-(nextb->text->gap_size - size)); - current_buffer = save_current; - } - } + for_each_buffer (nextb) + { + /* If a buffer's undo list is Qt, that means that undo is + turned off in that buffer. Calling truncate_undo_list on + Qt tends to return NULL, which effectively turns undo back on. + So don't call truncate_undo_list if undo_list is Qt. */ + if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name)) + && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) + truncate_undo_list (nextb); + + /* Shrink buffer gaps, but skip indirect and dead buffers. */ + if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name)) + && ! nextb->text->inhibit_shrinking) + { + /* If a buffer's gap size is more than 10% of the buffer + size, or larger than 2000 bytes, then shrink it + accordingly. Keep a minimum size of 20 bytes. */ + int size = min (2000, max (20, (nextb->text->z_byte / 10))); - nextb = nextb->header.next.buffer; - } - } + if (nextb->text->gap_size > size) + { + struct buffer *save_current = current_buffer; + current_buffer = nextb; + make_gap (-(nextb->text->gap_size - size)); + current_buffer = save_current; + } + } + } t1 = current_emacs_time (); @@ -5558,48 +5553,42 @@ See Info node `(elisp)Garbage Collection'. */) Look thru every buffer's undo list for elements that update markers that were not marked, and delete them. */ - { - register struct buffer *nextb = all_buffers; - - while (nextb) - { - /* If a buffer's undo list is Qt, that means that undo is - turned off in that buffer. Calling truncate_undo_list on - Qt tends to return NULL, which effectively turns undo back on. - So don't call truncate_undo_list if undo_list is Qt. */ - if (! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) - { - Lisp_Object tail, prev; - tail = nextb->BUFFER_INTERNAL_FIELD (undo_list); - prev = Qnil; - while (CONSP (tail)) - { - if (CONSP (XCAR (tail)) - && MARKERP (XCAR (XCAR (tail))) - && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) - { - if (NILP (prev)) - nextb->BUFFER_INTERNAL_FIELD (undo_list) = tail = XCDR (tail); - else - { - tail = XCDR (tail); - XSETCDR (prev, tail); - } - } - else - { - prev = tail; - tail = XCDR (tail); - } - } - } - /* Now that we have stripped the elements that need not be in the - undo_list any more, we can finally mark the list. */ - mark_object (nextb->BUFFER_INTERNAL_FIELD (undo_list)); - - nextb = nextb->header.next.buffer; - } - } + for_each_buffer (nextb) + { + /* If a buffer's undo list is Qt, that means that undo is + turned off in that buffer. Calling truncate_undo_list on + Qt tends to return NULL, which effectively turns undo back on. + So don't call truncate_undo_list if undo_list is Qt. */ + if (! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) + { + Lisp_Object tail, prev; + tail = nextb->BUFFER_INTERNAL_FIELD (undo_list); + prev = Qnil; + while (CONSP (tail)) + { + if (CONSP (XCAR (tail)) + && MARKERP (XCAR (XCAR (tail))) + && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) + { + if (NILP (prev)) + nextb->BUFFER_INTERNAL_FIELD (undo_list) = tail = XCDR (tail); + else + { + tail = XCDR (tail); + XSETCDR (prev, tail); + } + } + else + { + prev = tail; + tail = XCDR (tail); + } + } + } + /* Now that we have stripped the elements that need not be in the + undo_list any more, we can finally mark the list. */ + mark_object (nextb->BUFFER_INTERNAL_FIELD (undo_list)); + } gc_sweep (); @@ -5987,9 +5976,10 @@ mark_object (Lisp_Object arg) #ifdef GC_CHECK_MARKED_OBJECTS if (po != &buffer_defaults && po != &buffer_local_symbols) { - struct buffer *b = all_buffers; - for (; b && b != po; b = b->header.next.buffer) - ; + struct buffer *b; + for_each_buffer (b) + if (b == po) + break; if (b == NULL) abort (); } diff --git a/src/buffer.c b/src/buffer.c index 1e1bd933f9..40370460b9 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1532,10 +1532,8 @@ cleaning up all windows currently displaying the buffer to be killed. */) GCPRO1 (buffer); - for (other = all_buffers; other; other = other->header.next.buffer) - /* all_buffers contains dead buffers too; - don't re-kill them. */ - if (other->base_buffer == b && !NILP (BVAR (other, name))) + for_each_buffer (other) + if (other->base_buffer == b) { Lisp_Object buf; XSETBUFFER (buf, other); @@ -2052,7 +2050,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, { /* This is probably harder to make work. */ struct buffer *other; - for (other = all_buffers; other; other = other->header.next.buffer) + for_each_buffer (other) if (other->base_buffer == other_buffer || other->base_buffer == current_buffer) error ("One of the buffers to swap has indirect buffers"); @@ -2429,7 +2427,7 @@ current buffer is cleared. */) /* Copy this buffer's new multibyte status into all of its indirect buffers. */ - for (other = all_buffers; other; other = other->header.next.buffer) + for_each_buffer (other) if (other->base_buffer == current_buffer && !NILP (BVAR (other, name))) { BVAR (other, enable_multibyte_characters) @@ -5035,7 +5033,7 @@ init_buffer (void) Map new memory. */ struct buffer *b; - for (b = all_buffers; b; b = b->header.next.buffer) + for_each_buffer (b) if (b->text->beg == NULL) enlarge_buffer_text (b, 0); } diff --git a/src/buffer.h b/src/buffer.h index 4003be5c8c..8c596835fc 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -857,6 +857,15 @@ struct buffer }; +/* Chain of all buffers, including killed ones. */ + +extern struct buffer *all_buffers; + +/* Used to iterate over the chain above. */ + +#define for_each_buffer(b) \ + for ((b) = all_buffers; (b); (b) = (b)->header.next.buffer) + /* This points to the current buffer. */ extern struct buffer *current_buffer; diff --git a/src/coding.c b/src/coding.c index d9fcc634b7..212eb8275f 100644 --- a/src/coding.c +++ b/src/coding.c @@ -7588,7 +7588,7 @@ code_conversion_restore (Lisp_Object arg) { if (EQ (workbuf, Vcode_conversion_reused_workbuf)) reused_workbuf_in_use = 0; - else if (! NILP (Fbuffer_live_p (workbuf))) + else Fkill_buffer (workbuf); } set_buffer_internal (XBUFFER (current)); diff --git a/src/data.c b/src/data.c index 2254634967..84bd347b13 100644 --- a/src/data.c +++ b/src/data.c @@ -1401,7 +1401,7 @@ for this variable. */) { struct buffer *b; - for (b = all_buffers; b; b = b->header.next.buffer) + for_each_buffer (b) if (!PER_BUFFER_VALUE_P (b, idx)) PER_BUFFER_VALUE (b, offset) = value; } diff --git a/src/lisp.h b/src/lisp.h index 4dd9f37ca6..bfdc4ea4c0 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2858,7 +2858,6 @@ extern Lisp_Object set_buffer_if_live (Lisp_Object); extern Lisp_Object other_buffer_safely (Lisp_Object); extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; extern Lisp_Object get_truename_buffer (Lisp_Object); -extern struct buffer *all_buffers; extern void init_buffer_once (void); extern void init_buffer (void); extern void syms_of_buffer (void); -- 2.20.1