[Top][All Lists]
[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. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] /srv/bzr/emacs/trunk r109982: Discard killed buffers from deleted window and frame objects.,
Dmitry Antipov <=