aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2012-09-11 19:42:50 +0400
committerDmitry Antipov2012-09-11 19:42:50 +0400
commitd73e321cc241c0029e6874501cf32ee63643825c (patch)
tree457e4314e10ba51343f53a20ac8104d9db6203b2 /src
parent96d0357142bf277e6eb4d957a59b2c655034e2b7 (diff)
downloademacs-d73e321cc241c0029e6874501cf32ee63643825c.tar.gz
emacs-d73e321cc241c0029e6874501cf32ee63643825c.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/alloc.c67
-rw-r--r--src/data.c8
-rw-r--r--src/window.c10
-rw-r--r--src/window.h11
5 files changed, 88 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index cecd31ddab4..46f1847f7f6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,19 @@
12012-09-11 Dmitry Antipov <dmantipov@yandex.ru> 12012-09-11 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 Discard killed buffers from deleted window and frame objects.
4 This reduces an amount of references to killed buffers and
5 helps GC to reclaim them faster.
6 * alloc.c (discard_killed_buffers): New function.
7 (mark_object): Use it for deleted windows and frames.
8 (mark_object): If symbol's value is set up for a killed buffer
9 or deleted frame, restore it's global binding.
10 * data.c (swap_in_global_binding): Add GC notice.
11 (swap_in_symval_forwarding): Use convenient set_blv_where.
12 * window.c (wset_next_buffers, wset_prev_buffers): Move ...
13 * window.h: ... to here.
14
152012-09-11 Dmitry Antipov <dmantipov@yandex.ru>
16
3 Convenient macro to check whether the buffer is live. 17 Convenient macro to check whether the buffer is live.
4 * buffer.h (BUFFER_LIVE_P): New macro. 18 * buffer.h (BUFFER_LIVE_P): New macro.
5 * alloc.c, buffer.c, editfns.c, insdel.c, lread.c, marker.c: 19 * alloc.c, buffer.c, editfns.c, insdel.c, lread.c, marker.c:
diff --git a/src/alloc.c b/src/alloc.c
index 7bbc0abcd9a..fb16b7d7511 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5865,6 +5865,32 @@ mark_buffer (struct buffer *buffer)
5865 mark_buffer (buffer->base_buffer); 5865 mark_buffer (buffer->base_buffer);
5866} 5866}
5867 5867
5868/* Remove killed buffers or items whose car is a killed buffer
5869 from LIST and return changed LIST. Called during GC. */
5870
5871static inline Lisp_Object
5872discard_killed_buffers (Lisp_Object list)
5873{
5874 Lisp_Object tail, prev, tem;
5875
5876 for (tail = list, prev = Qnil; CONSP (tail); tail = XCDR (tail))
5877 {
5878 tem = XCAR (tail);
5879 if (CONSP (tem))
5880 tem = XCAR (tem);
5881 if (BUFFERP (tem) && !BUFFER_LIVE_P (XBUFFER (tem)))
5882 {
5883 if (NILP (prev))
5884 list = XCDR (tail);
5885 else
5886 XSETCDR (prev, XCDR (tail));
5887 }
5888 else
5889 prev = tail;
5890 }
5891 return list;
5892}
5893
5868/* Determine type of generic Lisp_Object and mark it accordingly. */ 5894/* Determine type of generic Lisp_Object and mark it accordingly. */
5869 5895
5870void 5896void
@@ -6001,20 +6027,41 @@ mark_object (Lisp_Object arg)
6001 break; 6027 break;
6002 6028
6003 case PVEC_FRAME: 6029 case PVEC_FRAME:
6004 mark_vectorlike (ptr); 6030 {
6005 mark_face_cache (((struct frame *) ptr)->face_cache); 6031 struct frame *f = (struct frame *) ptr;
6032
6033 /* For live frames, killed buffers are filtered out by
6034 store_frame_param. For dead frames, we do it here in
6035 attempt to help GC to reclaim killed buffers faster. */
6036 if (!FRAME_LIVE_P (f))
6037 fset_buffer_list (f, discard_killed_buffers (f->buffer_list));
6038
6039 mark_vectorlike (ptr);
6040 mark_face_cache (f->face_cache);
6041 }
6006 break; 6042 break;
6007 6043
6008 case PVEC_WINDOW: 6044 case PVEC_WINDOW:
6009 { 6045 {
6010 struct window *w = (struct window *) ptr; 6046 struct window *w = (struct window *) ptr;
6047 bool leaf = NILP (w->hchild) && NILP (w->vchild);
6048
6049 /* For live windows, Lisp code filters out killed buffers
6050 from both buffer lists. For dead windows, we do it here
6051 in attempt to help GC to reclaim killed buffers faster. */
6052 if (leaf && NILP (w->buffer))
6053 {
6054 wset_prev_buffers
6055 (w, discard_killed_buffers (w->prev_buffers));
6056 wset_next_buffers
6057 (w, discard_killed_buffers (w->next_buffers));
6058 }
6011 6059
6012 mark_vectorlike (ptr); 6060 mark_vectorlike (ptr);
6013 /* Mark glyphs for leaf windows. Marking window 6061 /* Mark glyphs for leaf windows. Marking window
6014 matrices is sufficient because frame matrices 6062 matrices is sufficient because frame matrices
6015 use the same glyph memory. */ 6063 use the same glyph memory. */
6016 if (NILP (w->hchild) && NILP (w->vchild) 6064 if (leaf && w->current_matrix)
6017 && w->current_matrix)
6018 { 6065 {
6019 mark_glyph_matrix (w->current_matrix); 6066 mark_glyph_matrix (w->current_matrix);
6020 mark_glyph_matrix (w->desired_matrix); 6067 mark_glyph_matrix (w->desired_matrix);
@@ -6081,10 +6128,14 @@ mark_object (Lisp_Object arg)
6081 case SYMBOL_LOCALIZED: 6128 case SYMBOL_LOCALIZED:
6082 { 6129 {
6083 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); 6130 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr);
6084 /* If the value is forwarded to a buffer or keyboard field, 6131 Lisp_Object where = blv->where;
6085 these are marked when we see the corresponding object. 6132 /* If the value is set up for a killed buffer or deleted
6086 And if it's forwarded to a C variable, either it's not 6133 frame, restore it's global binding. If the value is
6087 a Lisp_Object var, or it's staticpro'd already. */ 6134 forwarded to a C variable, either it's not a Lisp_Object
6135 var, or it's staticpro'd already. */
6136 if ((BUFFERP (where) && !BUFFER_LIVE_P (XBUFFER (where)))
6137 || (FRAMEP (where) && !FRAME_LIVE_P (XFRAME (where))))
6138 swap_in_global_binding (ptr);
6088 mark_object (blv->where); 6139 mark_object (blv->where);
6089 mark_object (blv->valcell); 6140 mark_object (blv->valcell);
6090 mark_object (blv->defcell); 6141 mark_object (blv->defcell);
diff --git a/src/data.c b/src/data.c
index 4678ac1208c..d894ac71a65 100644
--- a/src/data.c
+++ b/src/data.c
@@ -948,8 +948,10 @@ store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newva
948 } 948 }
949} 949}
950 950
951/* Set up SYMBOL to refer to its global binding. 951/* Set up SYMBOL to refer to its global binding. This makes it safe
952 This makes it safe to alter the status of other bindings. */ 952 to alter the status of other bindings. BEWARE: this may be called
953 during the mark phase of GC, where we assume that Lisp_Object slots
954 of BLV are marked after this function has changed them. */
953 955
954void 956void
955swap_in_global_binding (struct Lisp_Symbol *symbol) 957swap_in_global_binding (struct Lisp_Symbol *symbol)
@@ -1008,7 +1010,7 @@ swap_in_symval_forwarding (struct Lisp_Symbol *symbol, struct Lisp_Buffer_Local_
1008 else 1010 else
1009 { 1011 {
1010 tem1 = assq_no_quit (var, BVAR (current_buffer, local_var_alist)); 1012 tem1 = assq_no_quit (var, BVAR (current_buffer, local_var_alist));
1011 XSETBUFFER (blv->where, current_buffer); 1013 set_blv_where (blv, Fcurrent_buffer ());
1012 } 1014 }
1013 } 1015 }
1014 if (!(blv->found = !NILP (tem1))) 1016 if (!(blv->found = !NILP (tem1)))
diff --git a/src/window.c b/src/window.c
index 4a833a120b3..18a550782e8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -176,11 +176,6 @@ wset_new_total (struct window *w, Lisp_Object val)
176 w->new_total = val; 176 w->new_total = val;
177} 177}
178static inline void 178static inline void
179wset_next_buffers (struct window *w, Lisp_Object val)
180{
181 w->next_buffers = val;
182}
183static inline void
184wset_normal_cols (struct window *w, Lisp_Object val) 179wset_normal_cols (struct window *w, Lisp_Object val)
185{ 180{
186 w->normal_cols = val; 181 w->normal_cols = val;
@@ -201,11 +196,6 @@ wset_pointm (struct window *w, Lisp_Object val)
201 w->pointm = val; 196 w->pointm = val;
202} 197}
203static inline void 198static inline void
204wset_prev_buffers (struct window *w, Lisp_Object val)
205{
206 w->prev_buffers = val;
207}
208static inline void
209wset_right_fringe_width (struct window *w, Lisp_Object val) 199wset_right_fringe_width (struct window *w, Lisp_Object val)
210{ 200{
211 w->right_fringe_width = val; 201 w->right_fringe_width = val;
diff --git a/src/window.h b/src/window.h
index a70bc55bac5..62ae43a999d 100644
--- a/src/window.h
+++ b/src/window.h
@@ -414,7 +414,16 @@ wset_window_end_vpos (struct window *w, Lisp_Object val)
414{ 414{
415 w->window_end_vpos = val; 415 w->window_end_vpos = val;
416} 416}
417 417WINDOW_INLINE void
418wset_prev_buffers (struct window *w, Lisp_Object val)
419{
420 w->prev_buffers = val;
421}
422WINDOW_INLINE void
423wset_next_buffers (struct window *w, Lisp_Object val)
424{
425 w->next_buffers = val;
426}
418 427
419/* 1 if W is a minibuffer window. */ 428/* 1 if W is a minibuffer window. */
420 429