changeset 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 c26bceb68019
children 9ac5045a93ce
files src/alloc.c
diffstat 1 files changed, 73 insertions(+), 0 deletions(-) [+]
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);