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/alloc.c | |
| 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/alloc.c')
| -rw-r--r-- | src/alloc.c | 67 |
1 files changed, 59 insertions, 8 deletions
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); |