emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/alloc.c


From: Stefan Monnier
Subject: [Emacs-diffs] Changes to emacs/src/alloc.c
Date: Sat, 29 May 2004 01:34:16 -0400

Index: emacs/src/alloc.c
diff -c emacs/src/alloc.c:1.340 emacs/src/alloc.c:1.341
*** emacs/src/alloc.c:1.340     Fri May 28 20:59:14 2004
--- emacs/src/alloc.c   Sat May 29 00:00:17 2004
***************
*** 2866,2875 ****
  
  union Lisp_Misc *marker_free_list;
  
- /* Marker blocks which should be freed at end of GC.  */
- 
- struct marker_block *marker_blocks_pending_free;
- 
  /* Total number of marker blocks now in use.  */
  
  int n_marker_blocks;
--- 2866,2871 ----
***************
*** 2880,2886 ****
    marker_block = NULL;
    marker_block_index = MARKER_BLOCK_SIZE;
    marker_free_list = 0;
-   marker_blocks_pending_free = 0;
    n_marker_blocks = 0;
  }
  
--- 2876,2881 ----
***************
*** 4459,4500 ****
    }
  #endif
  
!   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.  */
        if (! EQ (nextb->undo_list, Qt))
          {
!           Lisp_Object tail, prev, elt, car;
            tail = nextb->undo_list;
            prev = Qnil;
            while (CONSP (tail))
              {
!               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 = cdr;
                    else
                      {
!                       tail = cdr;
                        XSETCDR (prev, tail);
                      }
                  }
--- 4454,4489 ----
    }
  #endif
  
!   /* Everything is now marked, except for the things that require special
!      finalization, i.e. the undo_list.
!      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 (XCAR (tail))
!                   && GC_MARKERP (XCAR (XCAR (tail)))
!                   && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
                  {
                    if (NILP (prev))
!                     nextb->undo_list = tail = XCDR (tail);
                    else
                      {
!                       tail = XCDR (tail);
                        XSETCDR (prev, tail);
                      }
                  }
***************
*** 4505,4526 ****
                  }
              }
          }
  
        nextb = nextb->next;
        }
    }
  
!   /* Undo lists have been cleaned up, so we can free marker blocks now.  */
! 
!   {
!     struct marker_block *mblk;
! 
!     while ((mblk = marker_blocks_pending_free) != 0)
!       {
!       marker_blocks_pending_free = mblk->next;
!       lisp_free (mblk);
!       }
!   }
  
    /* Clear the mark bits that we set in certain root slots.  */
  
--- 4494,4508 ----
                  }
              }
          }
+       /* Now that we have stripped the elements that need not be in the
+          undo_list any more, we can finally mark the list.  */
+       mark_object (nextb->undo_list);
  
        nextb = nextb->next;
        }
    }
  
!   gc_sweep ();
  
    /* Clear the mark bits that we set in certain root slots.  */
  
***************
*** 5088,5128 ****
  
    MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
  
!   if (CONSP (buffer->undo_list))
!     {
!       Lisp_Object tail;
!       tail = buffer->undo_list;
! 
!       /* We mark the undo list specially because
!        its pointers to markers should be weak.  */
! 
!       while (CONSP (tail))
!       {
!         register struct Lisp_Cons *ptr = XCONS (tail);
! 
!         if (CONS_MARKED_P (ptr))
!           break;
!         CONS_MARK (ptr);
!         if (GC_CONSP (ptr->car)
!             && !CONS_MARKED_P (XCONS (ptr->car))
!             && GC_MARKERP (XCAR (ptr->car)))
!           {
!             CONS_MARK (XCONS (ptr->car));
!             mark_object (XCDR (ptr->car));
!           }
!         else
!           mark_object (ptr->car);
! 
!         if (CONSP (ptr->cdr))
!           tail = ptr->cdr;
!         else
!           break;
!       }
! 
!       mark_object (XCDR (tail));
!     }
!   else
!     mark_object (buffer->undo_list);
  
    if (buffer->overlays_before)
      {
--- 5070,5078 ----
  
    MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
  
!   /* For now, we just don't mark the undo_list.  It's done later in
!      a special way just before the sweep phase, and after stripping
!      some of its elements that are not needed any more.  */
  
    if (buffer->overlays_before)
      {
***************
*** 5202,5207 ****
--- 5152,5167 ----
  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;
***************
*** 5252,5267 ****
      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;
--- 5212,5217 ----
***************
*** 5430,5436 ****
      register int num_free = 0, num_used = 0;
  
      marker_free_list = 0;
-     marker_blocks_pending_free = 0;
  
      for (mblk = marker_block; mblk; mblk = *mprev)
        {
--- 5380,5385 ----
***************
*** 5466,5478 ****
            *mprev = mblk->next;
            /* Unhook from the free list.  */
            marker_free_list = mblk->markers[0].u_free.chain;
            n_marker_blocks--;
- 
-           /* It is not safe to free the marker block at this stage,
-              since there may still be pointers to these markers from
-              a buffer's undo list.  KFS 2004-05-25.  */
-           mblk->next = marker_blocks_pending_free;
-           marker_blocks_pending_free = mblk;
          }
        else
          {
--- 5415,5422 ----
            *mprev = mblk->next;
            /* Unhook from the free list.  */
            marker_free_list = mblk->markers[0].u_free.chain;
+           lisp_free (mblk);
            n_marker_blocks--;
          }
        else
          {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]