diff options
| author | Dmitry Antipov | 2012-09-11 19:42:50 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-09-11 19:42:50 +0400 |
| commit | d73e321cc241c0029e6874501cf32ee63643825c (patch) | |
| tree | 457e4314e10ba51343f53a20ac8104d9db6203b2 /src | |
| parent | 96d0357142bf277e6eb4d957a59b2c655034e2b7 (diff) | |
| download | emacs-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/ChangeLog | 14 | ||||
| -rw-r--r-- | src/alloc.c | 67 | ||||
| -rw-r--r-- | src/data.c | 8 | ||||
| -rw-r--r-- | src/window.c | 10 | ||||
| -rw-r--r-- | src/window.h | 11 |
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 @@ | |||
| 1 | 2012-09-11 Dmitry Antipov <dmantipov@yandex.ru> | 1 | 2012-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 | |||
| 15 | 2012-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 | |||
| 5871 | static inline Lisp_Object | ||
| 5872 | discard_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 | ||
| 5870 | void | 5896 | void |
| @@ -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 | ||
| 954 | void | 956 | void |
| 955 | swap_in_global_binding (struct Lisp_Symbol *symbol) | 957 | swap_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 | } |
| 178 | static inline void | 178 | static inline void |
| 179 | wset_next_buffers (struct window *w, Lisp_Object val) | ||
| 180 | { | ||
| 181 | w->next_buffers = val; | ||
| 182 | } | ||
| 183 | static inline void | ||
| 184 | wset_normal_cols (struct window *w, Lisp_Object val) | 179 | wset_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 | } |
| 203 | static inline void | 198 | static inline void |
| 204 | wset_prev_buffers (struct window *w, Lisp_Object val) | ||
| 205 | { | ||
| 206 | w->prev_buffers = val; | ||
| 207 | } | ||
| 208 | static inline void | ||
| 209 | wset_right_fringe_width (struct window *w, Lisp_Object val) | 199 | wset_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 | 417 | WINDOW_INLINE void | |
| 418 | wset_prev_buffers (struct window *w, Lisp_Object val) | ||
| 419 | { | ||
| 420 | w->prev_buffers = val; | ||
| 421 | } | ||
| 422 | WINDOW_INLINE void | ||
| 423 | wset_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 | ||