unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Dmitry Antipov <dmantipov@yandex.ru>
To: emacs-devel@gnu.org
Cc: martin rudalics <rudalics@gmx.at>,
	Paul Eggert <eggert@cs.ucla.edu>,
	Stefan Monnier <monnier@iro.umontreal.ca>
Subject: Re: Reachable killed buffers
Date: Fri, 14 Sep 2012 16:10:27 +0400	[thread overview]
Message-ID: <50531EB3.5030604@yandex.ru> (raw)
In-Reply-To: <50521839.9060605@gmx.at>

[-- Attachment #1: Type: text/plain, Size: 822 bytes --]

Since our discussion shows that there is no solid and bullet-proof
solution for killed buffers problem (IMHO), I would like to propose
an alternate (less effective, but safe) solution: when the window
dies, it's prev_buffers and next_buffers are set to nil, but both
buffer lists are saved in struct saved_window just for the sake of
possible resurrection. Martin said that the most of window-configuration
objects are created with 'save-window-excursion' and so they're
short-lived objects which tends to not survive next GC. So, if
deleted window isn't recorded in window-configuration object or
such an object dies quickly, we're lucky; otherwise, the only thing
we can do is to hope that recorded window will be resurrected and
Lisp code from window.el will take care about the contents of
it's buffer lists.

Dmitry


[-- Attachment #2: kill_window.patch --]
[-- Type: text/plain, Size: 5266 bytes --]

=== modified file 'src/alloc.c'
--- src/alloc.c	2012-09-13 05:18:26 +0000
+++ src/alloc.c	2012-09-14 11:11:54 +0000
@@ -5865,32 +5865,6 @@
     mark_buffer (buffer->base_buffer);
 }
 
-/* Remove killed buffers or items whose car is a killed buffer from
-   LIST, and mark other items. Return changed LIST, which is marked.  */
-
-static Lisp_Object
-mark_discard_killed_buffers (Lisp_Object list)
-{
-  Lisp_Object tail, *prev = &list;
-
-  for (tail = list; CONSP (tail) && !CONS_MARKED_P (XCONS (tail));
-       tail = XCDR (tail))
-    {
-      Lisp_Object tem = XCAR (tail);
-      if (CONSP (tem))
-	tem = XCAR (tem);
-      if (BUFFERP (tem) && !BUFFER_LIVE_P (XBUFFER (tem)))
-	*prev = XCDR (tail);
-      else
-	{
-	  CONS_MARK (XCONS (tail));
-	  mark_object (XCAR (tail));
-	  prev = &XCDR_AS_LVALUE (tail);
-	}
-    }
-  return list;
-}
-
 /* Determine type of generic Lisp_Object and mark it accordingly.  */
 
 void
@@ -6034,24 +6008,12 @@
 	  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, mark_discard_killed_buffers (w->prev_buffers));
-		  wset_next_buffers
-		    (w, mark_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 (leaf && w->current_matrix)
+	      if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix)
 		{
 		  mark_glyph_matrix (w->current_matrix);
 		  mark_glyph_matrix (w->desired_matrix);

=== modified file 'src/window.c'
--- src/window.c	2012-09-11 15:42:50 +0000
+++ src/window.c	2012-09-14 12:09:06 +0000
@@ -3988,6 +3988,31 @@
   return new;
 }
 
+/* Reset W's fields so WINDOW_VALID_P is non-zero for W.  */
+
+static void
+kill_window (struct window *w)
+{
+  if (!NILP (w->vchild))
+    {
+      delete_all_child_windows (w->vchild);
+      wset_vchild (w, Qnil);
+    }
+  else if (!NILP (w->hchild))
+    {
+      delete_all_child_windows (w->hchild);
+      wset_hchild (w, Qnil);
+    }
+  else if (!NILP (w->buffer))
+    {
+      unshow_buffer (w);
+      unchain_marker (XMARKER (w->pointm));
+      unchain_marker (XMARKER (w->start));
+      wset_buffer (w, Qnil);
+    }
+  wset_prev_buffers (w, Qnil);
+  wset_next_buffers (w, Qnil);
+}
 
 DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0,
        doc: /* Remove WINDOW from its frame.
@@ -4078,23 +4103,8 @@
       wset_next (w, Qnil);  /* Don't delete w->next too.  */
       free_window_matrices (w);
 
-      if (!NILP (w->vchild))
-	{
-	  delete_all_child_windows (w->vchild);
-	  wset_vchild (w, Qnil);
-	}
-      else if (!NILP (w->hchild))
-	{
-	  delete_all_child_windows (w->hchild);
-	  wset_hchild (w, Qnil);
-	}
-      else if (!NILP (w->buffer))
-	{
-	  unshow_buffer (w);
-	  unchain_marker (XMARKER (w->pointm));
-	  unchain_marker (XMARKER (w->start));
-	  wset_buffer (w, Qnil);
-	}
+      /* W is really dead after this.  */
+      kill_window (w);
 
       if (NILP (s->prev) && NILP (s->next))
 	  /* A matrjoshka where SIBLING has become the only child of
@@ -5486,6 +5496,7 @@
   Lisp_Object parent, prev;
   Lisp_Object start_at_line_beg;
   Lisp_Object display_table;
+  Lisp_Object prev_buffers, next_buffers;
   Lisp_Object left_margin_cols, right_margin_cols;
   Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
   Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
@@ -5726,6 +5737,8 @@
 	  w->hscroll = XFASTINT (p->hscroll);
 	  w->min_hscroll = XFASTINT (p->min_hscroll);
 	  wset_display_table (w, p->display_table);
+	  wset_prev_buffers (w, p->prev_buffers);
+	  wset_next_buffers (w, p->next_buffers);
 	  wset_left_margin_cols (w, p->left_margin_cols);
 	  wset_right_margin_cols (w, p->right_margin_cols);
 	  wset_left_fringe_width (w, p->left_fringe_width);
@@ -5926,23 +5939,8 @@
   /* See Fset_window_configuration for excuse.  */
   wset_total_lines (w, w->buffer);
 
-  if (!NILP (w->vchild))
-    {
-      delete_all_child_windows (w->vchild);
-      wset_vchild (w, Qnil);
-    }
-  else if (!NILP (w->hchild))
-    {
-      delete_all_child_windows (w->hchild);
-      wset_hchild (w, Qnil);
-    }
-  else if (!NILP (w->buffer))
-    {
-      unshow_buffer (w);
-      unchain_marker (XMARKER (w->pointm));
-      unchain_marker (XMARKER (w->start));
-      wset_buffer (w, Qnil);
-    }
+  /* W is really dead after this.  */
+  kill_window (w);
 
   Vwindow_list = Qnil;
 }
@@ -6045,6 +6043,8 @@
       XSETFASTINT (p->hscroll, w->hscroll);
       XSETFASTINT (p->min_hscroll, w->min_hscroll);
       p->display_table = w->display_table;
+      p->prev_buffers = w->prev_buffers;
+      p->next_buffers = w->next_buffers;
       p->left_margin_cols = w->left_margin_cols;
       p->right_margin_cols = w->right_margin_cols;
       p->left_fringe_width = w->left_fringe_width;


  reply	other threads:[~2012-09-14 12:10 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <E1T9II0-0005q4-Gh@vcs.savannah.gnu.org>
2012-09-05 18:24 ` [Emacs-diffs] /srv/bzr/emacs/trunk r109890: Do not mark objects from deleted buffers, windows and frames Stefan Monnier
2012-09-05 19:15   ` Stefan Monnier
2012-09-06  6:55   ` Dmitry Antipov
2012-09-06  7:00     ` Herring, Davis
2012-09-06  7:28     ` martin rudalics
2012-09-06  9:57       ` Dmitry Antipov
2012-09-06 14:42         ` martin rudalics
2012-09-06 12:53       ` Stefan Monnier
2012-09-06 14:42         ` martin rudalics
2012-09-06 12:52     ` Stefan Monnier
2012-09-06 14:42       ` martin rudalics
2012-09-06 17:33         ` Stefan Monnier
2012-09-07  9:52           ` martin rudalics
2012-09-06 17:06       ` Dmitry Antipov
2012-09-06 17:37         ` Stefan Monnier
2012-09-07  9:53           ` martin rudalics
2012-09-07 15:19             ` Stefan Monnier
2012-09-10  9:46             ` Reachable killed buffers [Was: Re: [Emacs-diffs] /srv/bzr/emacs/trunk r109890: Do not mark objects from deleted buffers, windows and frames] Dmitry Antipov
2012-09-10 13:25               ` Stefan Monnier
2012-09-10 15:15                 ` Reachable killed buffers Dmitry Antipov
2012-09-10 20:15                   ` Stefan Monnier
2012-09-10 21:10                     ` Stefan Monnier
2012-09-11  5:25                     ` Dmitry Antipov
2012-09-11 13:06                       ` Stefan Monnier
2012-09-12  8:09                       ` martin rudalics
2012-09-12 13:47                         ` Paul Eggert
2012-09-12 13:59                           ` Dmitry Antipov
2012-09-12 14:05                             ` Paul Eggert
2012-09-12 14:15                               ` martin rudalics
2012-09-12 15:59                                 ` Dmitry Antipov
2012-09-12 17:37                                   ` martin rudalics
2012-09-12 17:55                                   ` Paul Eggert
2012-09-13  3:29                                     ` Stefan Monnier
2012-09-13  4:43                                       ` Paul Eggert
2012-09-13  5:00                                         ` Dmitry Antipov
2012-09-13  5:18                                           ` Paul Eggert
2012-09-13 12:47                                         ` Stefan Monnier
2012-09-13 16:49                                         ` martin rudalics
2012-09-13 17:11                                           ` Paul Eggert
2012-09-13 17:30                                             ` martin rudalics
2012-09-14 12:10                                               ` Dmitry Antipov [this message]
2012-09-14 13:29                                                 ` Stefan Monnier
2012-09-14 13:38                                                 ` martin rudalics
2012-09-13 18:01                                             ` Dmitry Antipov
2012-09-06  7:20   ` [Emacs-diffs] /srv/bzr/emacs/trunk r109890: Do not mark objects from deleted buffers, windows and frames martin rudalics

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50531EB3.5030604@yandex.ru \
    --to=dmantipov@yandex.ru \
    --cc=eggert@cs.ucla.edu \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    --cc=rudalics@gmx.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).