aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorRichard M. Stallman <[email protected]>1998-03-28 21:50:59 +0000
committerRichard M. Stallman <[email protected]>1998-03-28 21:50:59 +0000
commit4c315bdabd2270964b4054dce2d9f52f018bcb3a (patch)
tree7468748b29cf0430d34898605292da53fcd11e76 /src/alloc.c
parentb50f6283db965303f3c7d2ac0950e0a725af8c05 (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.c73
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);