/[emacs]/emacs/src/alloc.c
ViewVC logotype

Diff of /emacs/src/alloc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.340 by monnier, Fri May 28 20:59:14 2004 UTC revision 1.341 by monnier, Sat May 29 00:00:17 2004 UTC
# Line 2866  int marker_block_index; Line 2866  int marker_block_index;
2866    
2867  union Lisp_Misc *marker_free_list;  union Lisp_Misc *marker_free_list;
2868    
 /* Marker blocks which should be freed at end of GC.  */  
   
 struct marker_block *marker_blocks_pending_free;  
   
2869  /* Total number of marker blocks now in use.  */  /* Total number of marker blocks now in use.  */
2870    
2871  int n_marker_blocks;  int n_marker_blocks;
# Line 2880  init_marker () Line 2876  init_marker ()
2876    marker_block = NULL;    marker_block = NULL;
2877    marker_block_index = MARKER_BLOCK_SIZE;    marker_block_index = MARKER_BLOCK_SIZE;
2878    marker_free_list = 0;    marker_free_list = 0;
   marker_blocks_pending_free = 0;  
2879    n_marker_blocks = 0;    n_marker_blocks = 0;
2880  }  }
2881    
# Line 4459  returns nil, because real GC can't be do Line 4454  returns nil, because real GC can't be do
4454    }    }
4455  #endif  #endif
4456    
4457    gc_sweep ();    /* Everything is now marked, except for the things that require special
4458         finalization, i.e. the undo_list.
4459    /* Look thru every buffer's undo list for elements that used to       Look thru every buffer's undo list
4460       contain update markers that were changed to Lisp_Misc_Free       for elements that update markers that were not marked,
4461       objects and delete them.  This may leave a few cons cells       and delete them.  */
      unchained, but we will get those on the next sweep.  */  
4462    {    {
4463      register struct buffer *nextb = all_buffers;      register struct buffer *nextb = all_buffers;
4464    
4465      while (nextb)      while (nextb)
4466        {        {
4467          /* If a buffer's undo list is Qt, that means that undo is          /* If a buffer's undo list is Qt, that means that undo is
4468             turned off in that buffer.  */             turned off in that buffer.  Calling truncate_undo_list on
4469               Qt tends to return NULL, which effectively turns undo back on.
4470               So don't call truncate_undo_list if undo_list is Qt.  */
4471          if (! EQ (nextb->undo_list, Qt))          if (! EQ (nextb->undo_list, Qt))
4472            {            {
4473              Lisp_Object tail, prev, elt, car;              Lisp_Object tail, prev;
4474              tail = nextb->undo_list;              tail = nextb->undo_list;
4475              prev = Qnil;              prev = Qnil;
4476              while (CONSP (tail))              while (CONSP (tail))
4477                {                {
4478                  if ((elt = XCAR (tail), GC_CONSP (elt))                  if (GC_CONSP (XCAR (tail))
4479                      && (car = XCAR (elt), GC_MISCP (car))                      && GC_MARKERP (XCAR (XCAR (tail)))
4480                      && XMISCTYPE (car) == Lisp_Misc_Free)                      && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit)
4481                    {                    {
                     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);  
4482                      if (NILP (prev))                      if (NILP (prev))
4483                        nextb->undo_list = tail = cdr;                        nextb->undo_list = tail = XCDR (tail);
4484                      else                      else
4485                        {                        {
4486                          tail = cdr;                          tail = XCDR (tail);
4487                          XSETCDR (prev, tail);                          XSETCDR (prev, tail);
4488                        }                        }
4489                    }                    }
# Line 4505  returns nil, because real GC can't be do Line 4494  returns nil, because real GC can't be do
4494                    }                    }
4495                }                }
4496            }            }
4497            /* Now that we have stripped the elements that need not be in the
4498               undo_list any more, we can finally mark the list.  */
4499            mark_object (nextb->undo_list);
4500    
4501          nextb = nextb->next;          nextb = nextb->next;
4502        }        }
4503    }    }
4504    
4505    /* Undo lists have been cleaned up, so we can free marker blocks now.  */    gc_sweep ();
   
   {  
     struct marker_block *mblk;  
   
     while ((mblk = marker_blocks_pending_free) != 0)  
       {  
         marker_blocks_pending_free = mblk->next;  
         lisp_free (mblk);  
       }  
   }  
4506    
4507    /* Clear the mark bits that we set in certain root slots.  */    /* Clear the mark bits that we set in certain root slots.  */
4508    
# Line 5088  mark_buffer (buf) Line 5070  mark_buffer (buf)
5070    
5071    MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));    MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
5072    
5073    if (CONSP (buffer->undo_list))    /* For now, we just don't mark the undo_list.  It's done later in
5074      {       a special way just before the sweep phase, and after stripping
5075        Lisp_Object tail;       some of its elements that are not needed any more.  */
       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);  
5076    
5077    if (buffer->overlays_before)    if (buffer->overlays_before)
5078      {      {
# Line 5202  survives_gc_p (obj) Line 5152  survives_gc_p (obj)
5152  static void  static void
5153  gc_sweep ()  gc_sweep ()
5154  {  {
5155      /* Remove or mark entries in weak hash tables.
5156         This must be done before any object is unmarked.  */
5157      sweep_weak_hash_tables ();
5158    
5159      sweep_strings ();
5160    #ifdef GC_CHECK_STRING_BYTES
5161      if (!noninteractive)
5162        check_string_bytes (1);
5163    #endif
5164    
5165    /* Put all unmarked conses on free list */    /* Put all unmarked conses on free list */
5166    {    {
5167      register struct cons_block *cblk;      register struct cons_block *cblk;
# Line 5252  gc_sweep () Line 5212  gc_sweep ()
5212      total_free_conses = num_free;      total_free_conses = num_free;
5213    }    }
5214    
   /* 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  
   
5215    /* Put all unmarked floats on free list */    /* Put all unmarked floats on free list */
5216    {    {
5217      register struct float_block *fblk;      register struct float_block *fblk;
# Line 5430  gc_sweep () Line 5380  gc_sweep ()
5380      register int num_free = 0, num_used = 0;      register int num_free = 0, num_used = 0;
5381    
5382      marker_free_list = 0;      marker_free_list = 0;
     marker_blocks_pending_free = 0;  
5383    
5384      for (mblk = marker_block; mblk; mblk = *mprev)      for (mblk = marker_block; mblk; mblk = *mprev)
5385        {        {
# Line 5466  gc_sweep () Line 5415  gc_sweep ()
5415              *mprev = mblk->next;              *mprev = mblk->next;
5416              /* Unhook from the free list.  */              /* Unhook from the free list.  */
5417              marker_free_list = mblk->markers[0].u_free.chain;              marker_free_list = mblk->markers[0].u_free.chain;
5418                lisp_free (mblk);
5419              n_marker_blocks--;              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;  
5420            }            }
5421          else          else
5422            {            {

Legend:
Removed from v.1.340  
changed lines
  Added in v.1.341

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26