emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r109982: Discard killed buffers from


From: Dmitry Antipov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109982: Discard killed buffers from deleted window and frame objects.
Date: Tue, 11 Sep 2012 19:42:50 +0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109982
committer: Dmitry Antipov <address@hidden>
branch nick: trunk
timestamp: Tue 2012-09-11 19:42:50 +0400
message:
  Discard killed buffers from deleted window and frame objects.
  This reduces an amount of references to killed buffers and
  helps GC to reclaim them faster.
  * alloc.c (discard_killed_buffers): New function.
  (mark_object): Use it for deleted windows and frames.
  (mark_object): If symbol's value is set up for a killed buffer
  or deleted frame, restore it's global binding.
  * data.c (swap_in_global_binding): Add GC notice.
  (swap_in_symval_forwarding): Use convenient set_blv_where.
  * window.c (wset_next_buffers, wset_prev_buffers): Move ...
  * window.h: ... to here.
modified:
  src/ChangeLog
  src/alloc.c
  src/data.c
  src/window.c
  src/window.h
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-09-11 04:22:03 +0000
+++ b/src/ChangeLog     2012-09-11 15:42:50 +0000
@@ -1,5 +1,19 @@
 2012-09-11  Dmitry Antipov  <address@hidden>
 
+       Discard killed buffers from deleted window and frame objects.
+       This reduces an amount of references to killed buffers and
+       helps GC to reclaim them faster.
+       * alloc.c (discard_killed_buffers): New function.
+       (mark_object): Use it for deleted windows and frames.
+       (mark_object): If symbol's value is set up for a killed buffer
+       or deleted frame, restore it's global binding.
+       * data.c (swap_in_global_binding): Add GC notice.
+       (swap_in_symval_forwarding): Use convenient set_blv_where.
+       * window.c (wset_next_buffers, wset_prev_buffers): Move ...
+       * window.h: ... to here.
+
+2012-09-11  Dmitry Antipov  <address@hidden>
+
        Convenient macro to check whether the buffer is live.
        * buffer.h (BUFFER_LIVE_P): New macro.
        * alloc.c, buffer.c, editfns.c, insdel.c, lread.c, marker.c:

=== modified file 'src/alloc.c'
--- a/src/alloc.c       2012-09-11 04:22:03 +0000
+++ b/src/alloc.c       2012-09-11 15:42:50 +0000
@@ -5865,6 +5865,32 @@
     mark_buffer (buffer->base_buffer);
 }
 
+/* Remove killed buffers or items whose car is a killed buffer
+   from LIST and return changed LIST.  Called during GC.  */
+
+static inline Lisp_Object
+discard_killed_buffers (Lisp_Object list)
+{
+  Lisp_Object tail, prev, tem;
+
+  for (tail = list, prev = Qnil; CONSP (tail); tail = XCDR (tail))
+    {
+      tem = XCAR (tail);
+      if (CONSP (tem))
+       tem = XCAR (tem);
+      if (BUFFERP (tem) && !BUFFER_LIVE_P (XBUFFER (tem)))
+       {
+         if (NILP (prev))
+           list = XCDR (tail);
+         else
+           XSETCDR (prev, XCDR (tail));
+       }
+      else
+       prev = tail;
+    }
+  return list;
+}
+
 /* Determine type of generic Lisp_Object and mark it accordingly.  */
 
 void
@@ -6001,20 +6027,41 @@
            break;
 
          case PVEC_FRAME:
-           mark_vectorlike (ptr);
-           mark_face_cache (((struct frame *) ptr)->face_cache);
+           {
+             struct frame *f = (struct frame *) ptr;
+
+             /* For live frames, killed buffers are filtered out by
+                store_frame_param.  For dead frames, we do it here in
+                attempt to help GC to reclaim killed buffers faster.  */
+             if (!FRAME_LIVE_P (f))
+               fset_buffer_list (f, discard_killed_buffers (f->buffer_list));
+
+             mark_vectorlike (ptr);
+             mark_face_cache (f->face_cache);
+           }
            break;
 
          case PVEC_WINDOW:
            {
              struct window *w = (struct window *) ptr;
+             bool leaf = NILP (w->hchild) && NILP (w->vchild);
+             
+             /* For live windows, Lisp code filters out killed buffers
+                from both buffer lists.  For dead windows, we do it here
+                in attempt to help GC to reclaim killed buffers faster.  */
+             if (leaf && NILP (w->buffer))
+               {
+                 wset_prev_buffers
+                   (w, discard_killed_buffers (w->prev_buffers));
+                 wset_next_buffers
+                   (w, discard_killed_buffers (w->next_buffers));
+               }
 
              mark_vectorlike (ptr);
              /* Mark glyphs for leaf windows.  Marking window
                 matrices is sufficient because frame matrices
                 use the same glyph memory.  */
-             if (NILP (w->hchild) && NILP (w->vchild)
-                 && w->current_matrix)
+             if (leaf && w->current_matrix)
                {
                  mark_glyph_matrix (w->current_matrix);
                  mark_glyph_matrix (w->desired_matrix);
@@ -6081,10 +6128,14 @@
          case SYMBOL_LOCALIZED:
            {
              struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr);
-             /* If the value is forwarded to a buffer or keyboard field,
-                these are marked when we see the corresponding object.
-                And if it's forwarded to a C variable, either it's not
-                a Lisp_Object var, or it's staticpro'd already.  */
+             Lisp_Object where = blv->where;
+             /* If the value is set up for a killed buffer or deleted
+                frame, restore it's global binding.  If the value is
+                forwarded to a C variable, either it's not a Lisp_Object
+                var, or it's staticpro'd already.  */
+             if ((BUFFERP (where) && !BUFFER_LIVE_P (XBUFFER (where)))
+                 || (FRAMEP (where) && !FRAME_LIVE_P (XFRAME (where))))
+               swap_in_global_binding (ptr);
              mark_object (blv->where);
              mark_object (blv->valcell);
              mark_object (blv->defcell);

=== modified file 'src/data.c'
--- a/src/data.c        2012-09-11 02:28:27 +0000
+++ b/src/data.c        2012-09-11 15:42:50 +0000
@@ -948,8 +948,10 @@
     }
 }
 
-/* Set up SYMBOL to refer to its global binding.
-   This makes it safe to alter the status of other bindings.  */
+/* Set up SYMBOL to refer to its global binding.  This makes it safe
+   to alter the status of other bindings.  BEWARE: this may be called
+   during the mark phase of GC, where we assume that Lisp_Object slots
+   of BLV are marked after this function has changed them.  */
 
 void
 swap_in_global_binding (struct Lisp_Symbol *symbol)
@@ -1008,7 +1010,7 @@
        else
          {
            tem1 = assq_no_quit (var, BVAR (current_buffer, local_var_alist));
-           XSETBUFFER (blv->where, current_buffer);
+           set_blv_where (blv, Fcurrent_buffer ());
          }
       }
       if (!(blv->found = !NILP (tem1)))

=== modified file 'src/window.c'
--- a/src/window.c      2012-09-11 04:22:03 +0000
+++ b/src/window.c      2012-09-11 15:42:50 +0000
@@ -176,11 +176,6 @@
   w->new_total = val;
 }
 static inline void
-wset_next_buffers (struct window *w, Lisp_Object val)
-{
-  w->next_buffers = val;
-}
-static inline void
 wset_normal_cols (struct window *w, Lisp_Object val)
 {
   w->normal_cols = val;
@@ -201,11 +196,6 @@
   w->pointm = val;
 }
 static inline void
-wset_prev_buffers (struct window *w, Lisp_Object val)
-{
-  w->prev_buffers = val;
-}
-static inline void
 wset_right_fringe_width (struct window *w, Lisp_Object val)
 {
   w->right_fringe_width = val;

=== modified file 'src/window.h'
--- a/src/window.h      2012-09-05 17:05:32 +0000
+++ b/src/window.h      2012-09-11 15:42:50 +0000
@@ -414,7 +414,16 @@
 {
   w->window_end_vpos = val;
 }
-
+WINDOW_INLINE void
+wset_prev_buffers (struct window *w, Lisp_Object val)
+{
+  w->prev_buffers = val;
+}
+WINDOW_INLINE void
+wset_next_buffers (struct window *w, Lisp_Object val)
+{
+  w->next_buffers = val;
+}
 
 /* 1 if W is a minibuffer window.  */
 


reply via email to

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