diff options
author | Richard M. Stallman <[email protected]> | 1998-03-28 21:50:59 +0000 |
---|---|---|
committer | Richard M. Stallman <[email protected]> | 1998-03-28 21:50:59 +0000 |
commit | 4c315bdabd2270964b4054dce2d9f52f018bcb3a (patch) | |
tree | 7468748b29cf0430d34898605292da53fcd11e76 /src/alloc.c | |
parent | b50f6283db965303f3c7d2ac0950e0a725af8c05 (diff) |
(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.
Diffstat (limited to 'src/alloc.c')
-rw-r--r-- | src/alloc.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/alloc.c b/src/alloc.c index 47fa682010..be4c82d0a1 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1816,6 +1816,46 @@ Garbage collection happens automatically if you cons more than\n\ } 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_buffer (buf) 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); |