Mercurial > emacs
diff src/alloc.c @ 21306:dc2cbd40703c
(mark_buffer): Mark the undo_list slot specially;
don't mark a marker just cause it is in this list.
(Fgarbage_collect): Discard from all undo-lists
all elements that adjust markers that were not marked.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 28 Mar 1998 21:50:59 +0000 |
parents | 693573ac0944 |
children | 1701bf5b9dec |
line wrap: on
line diff
--- a/src/alloc.c Sat Mar 28 21:50:39 1998 +0000 +++ b/src/alloc.c Sat Mar 28 21:50:59 1998 +0000 @@ -1816,6 +1816,46 @@ } mark_kboards (); + /* 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->undo_list, Qt)) + { + Lisp_Object tail, prev; + tail = nextb->undo_list; + prev = Qnil; + while (CONSP (tail)) + { + if (GC_CONSP (XCONS (tail)->car) + && GC_MARKERP (XCONS (XCONS (tail)->car)->car) + && ! XMARKBIT (XMARKER (XCONS (XCONS (tail)->car)->car)->chain)) + { + if (NILP (prev)) + nextb->undo_list = tail = XCONS (tail)->cdr; + else + tail = XCONS (prev)->cdr = XCONS (tail)->cdr; + } + else + { + prev = tail; + tail = XCONS (tail)->cdr; + } + } + } + + nextb = nextb->next; + } + } + gc_sweep (); /* Clear the mark bits that we set in certain root slots. */ @@ -2228,6 +2268,39 @@ MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); + if (CONSP (buffer->undo_list)) + { + Lisp_Object tail; + tail = buffer->undo_list; + + while (CONSP (tail)) + { + register struct Lisp_Cons *ptr = XCONS (tail); + + if (XMARKBIT (ptr->car)) + break; + XMARK (ptr->car); + if (GC_CONSP (ptr->car) + && ! XMARKBIT (XCONS (ptr->car)->car) + && GC_MARKERP (XCONS (ptr->car)->car)) + { + XMARK (XCONS (ptr->car)->car); + mark_object (&XCONS (ptr->car)->cdr); + } + else + mark_object (&ptr->car); + + if (CONSP (ptr->cdr)) + tail = ptr->cdr; + else + break; + } + + mark_object (&XCONS (tail)->cdr); + } + else + mark_object (&buffer->undo_list); + #if 0 mark_object (buffer->syntax_table);