]> git.eshelyaron.com Git - emacs.git/commitdiff
(struct backtrace): Add debug_on_exit member.
authorKim F. Storm <storm@cua.dk>
Fri, 21 May 2004 23:36:10 +0000 (23:36 +0000)
committerKim F. Storm <storm@cua.dk>
Fri, 21 May 2004 23:36:10 +0000 (23:36 +0000)
(Fgarbage_collect): Clear out buffer undo_list markers after gc_sweep.
Identify those markers as Lisp_Misc_Free objects.  Clear car and cdr of
the removed cons cells.
(mark_object): Undo previous change - disallow Lisp_Misc_Free objects.
(gc_sweep): Clear cons_blocks before sweeping strings, so we don't have
any cons cells pointing to unallocated stings.
Do not lisp_free any marker blocks, as there may still be pointers
to them from buffer undo lists at this stage of GC.

src/alloc.c

index 3dc21ca30e015cd67b65f93a3dc5fee3b7f0fff1..fb424e6aee61faca64193580a6737b516875cda2 100644 (file)
@@ -2334,7 +2334,6 @@ free_cons (ptr)
   cons_free_list = ptr;
 }
 
-
 DEFUN ("cons", Fcons, Scons, 2, 2, 0,
        doc: /* Create a new cons, give it CAR and CDR as components, and return it.  */)
      (car, cdr)
@@ -4286,6 +4285,8 @@ struct backtrace
   /* If nargs is UNEVALLED, args points to slot holding list of
      unevalled args.  */
   char evalargs;
+  /* Nonzero means call value of debugger when done with this operation. */
+  char debug_on_exit;
 };
 
 
@@ -4476,34 +4477,42 @@ returns nil, because real GC can't be done.  */)
   }
 #endif
 
-  /* Look thru every buffer's undo list
-     for elements that update markers that were not marked,
-     and delete them.  */
+  gc_sweep ();
+
+  /* Look thru every buffer's undo list for elements that used to
+     contain update markers that were changed to Lisp_Misc_Free
+     objects and delete them.  This may leave a few cons cells
+     unchained, but we will get those on the next sweep.  */
   {
     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.  */
+          turned off in that buffer.  */
        if (! EQ (nextb->undo_list, Qt))
          {
-           Lisp_Object tail, prev;
+           Lisp_Object tail, prev, elt, car;
            tail = nextb->undo_list;
            prev = Qnil;
            while (CONSP (tail))
              {
-               if (GC_CONSP (XCAR (tail))
-                   && GC_MARKERP (XCAR (XCAR (tail)))
-                   && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
+               if ((elt = XCAR (tail), GC_CONSP (elt))
+                   && (car = XCAR (elt), GC_MISCP (car))
+                   && XMISCTYPE (car) == Lisp_Misc_Free)
                  {
+                   Lisp_Object cdr = XCDR (tail);
+                   /* Do not use free_cons here, as we don't know if
+                      anybody else has a pointer to these conses.  */
+                   XSETCAR (elt, Qnil);
+                   XSETCDR (elt, Qnil);
+                   XSETCAR (tail, Qnil);
+                   XSETCDR (tail, Qnil);
                    if (NILP (prev))
-                     nextb->undo_list = tail = XCDR (tail);
+                     nextb->undo_list = tail = cdr;
                    else
                      {
-                       tail = XCDR (tail);
+                       tail = cdr;
                        XSETCDR (prev, tail);
                      }
                  }
@@ -4519,8 +4528,6 @@ returns nil, because real GC can't be done.  */)
       }
   }
 
-  gc_sweep ();
-
   /* Clear the mark bits that we set in certain root slots.  */
 
   unmark_byte_stack ();
@@ -4976,14 +4983,6 @@ mark_object (arg)
       break;
 
     case Lisp_Misc:
-      if (XMISCTYPE (obj) == Lisp_Misc_Free)
-       {
-         /* This is (probably) a freed marker which may still exist on
-            a buffer undo list, so accept it here, as check below will
-            fail (not live).  KFS 2004-05-17 */
-         XMARKER (obj)->gcmarkbit = 1;
-         break;
-       }
       CHECK_ALLOCATED_AND_LIVE (live_misc_p);
       if (XMARKER (obj)->gcmarkbit)
        break;
@@ -5209,16 +5208,6 @@ survives_gc_p (obj)
 static void
 gc_sweep ()
 {
-  /* Remove or mark entries in weak hash tables.
-     This must be done before any object is unmarked.  */
-  sweep_weak_hash_tables ();
-
-  sweep_strings ();
-#ifdef GC_CHECK_STRING_BYTES
-  if (!noninteractive)
-    check_string_bytes (1);
-#endif
-
   /* Put all unmarked conses on free list */
   {
     register struct cons_block *cblk;
@@ -5269,6 +5258,16 @@ gc_sweep ()
     total_free_conses = num_free;
   }
 
+  /* Remove or mark entries in weak hash tables.
+     This must be done before any object is unmarked.  */
+  sweep_weak_hash_tables ();
+
+  sweep_strings ();
+#ifdef GC_CHECK_STRING_BYTES
+  if (!noninteractive)
+    check_string_bytes (1);
+#endif
+
   /* Put all unmarked floats on free list */
   {
     register struct float_block *fblk;
@@ -5467,6 +5466,9 @@ gc_sweep ()
        /* If this block contains only free markers and we have already
           seen more than two blocks worth of free markers then deallocate
           this block.  */
+#if 0
+       /* There may still be pointers to these markers from a buffer's
+          undo list, so don't free them.  KFS 2004-05-21  /
        if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE)
          {
            *mprev = mblk->next;
@@ -5476,6 +5478,7 @@ gc_sweep ()
            n_marker_blocks--;
          }
        else
+#endif
          {
            num_free += this_free;
            mprev = &mblk->next;