diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/src/alloc.c b/src/alloc.c index 7bbc0abcd9a..61cb7086c25 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -5865,6 +5865,28 @@ 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 Lisp_Object | ||
| 5872 | discard_killed_buffers (Lisp_Object list) | ||
| 5873 | { | ||
| 5874 | Lisp_Object *prev = &list; | ||
| 5875 | Lisp_Object tail; | ||
| 5876 | |||
| 5877 | for (tail = list; CONSP (tail); tail = XCDR (tail)) | ||
| 5878 | { | ||
| 5879 | Lisp_Object tem = XCAR (tail); | ||
| 5880 | if (CONSP (tem)) | ||
| 5881 | tem = XCAR (tem); | ||
| 5882 | if (BUFFERP (tem) && !BUFFER_LIVE_P (XBUFFER (tem))) | ||
| 5883 | *prev = XCDR (tail); | ||
| 5884 | else | ||
| 5885 | prev = &XCDR_AS_LVALUE (tail); | ||
| 5886 | } | ||
| 5887 | return list; | ||
| 5888 | } | ||
| 5889 | |||
| 5868 | /* Determine type of generic Lisp_Object and mark it accordingly. */ | 5890 | /* Determine type of generic Lisp_Object and mark it accordingly. */ |
| 5869 | 5891 | ||
| 5870 | void | 5892 | void |
| @@ -6001,20 +6023,41 @@ mark_object (Lisp_Object arg) | |||
| 6001 | break; | 6023 | break; |
| 6002 | 6024 | ||
| 6003 | case PVEC_FRAME: | 6025 | case PVEC_FRAME: |
| 6004 | mark_vectorlike (ptr); | 6026 | { |
| 6005 | mark_face_cache (((struct frame *) ptr)->face_cache); | 6027 | struct frame *f = (struct frame *) ptr; |
| 6028 | |||
| 6029 | /* For live frames, killed buffers are filtered out by | ||
| 6030 | store_frame_param. For dead frames, we do it here in | ||
| 6031 | attempt to help GC to reclaim killed buffers faster. */ | ||
| 6032 | if (!FRAME_LIVE_P (f)) | ||
| 6033 | fset_buffer_list (f, discard_killed_buffers (f->buffer_list)); | ||
| 6034 | |||
| 6035 | mark_vectorlike (ptr); | ||
| 6036 | mark_face_cache (f->face_cache); | ||
| 6037 | } | ||
| 6006 | break; | 6038 | break; |
| 6007 | 6039 | ||
| 6008 | case PVEC_WINDOW: | 6040 | case PVEC_WINDOW: |
| 6009 | { | 6041 | { |
| 6010 | struct window *w = (struct window *) ptr; | 6042 | struct window *w = (struct window *) ptr; |
| 6043 | bool leaf = NILP (w->hchild) && NILP (w->vchild); | ||
| 6044 | |||
| 6045 | /* For live windows, Lisp code filters out killed buffers | ||
| 6046 | from both buffer lists. For dead windows, we do it here | ||
| 6047 | in attempt to help GC to reclaim killed buffers faster. */ | ||
| 6048 | if (leaf && NILP (w->buffer)) | ||
| 6049 | { | ||
| 6050 | wset_prev_buffers | ||
| 6051 | (w, discard_killed_buffers (w->prev_buffers)); | ||
| 6052 | wset_next_buffers | ||
| 6053 | (w, discard_killed_buffers (w->next_buffers)); | ||
| 6054 | } | ||
| 6011 | 6055 | ||
| 6012 | mark_vectorlike (ptr); | 6056 | mark_vectorlike (ptr); |
| 6013 | /* Mark glyphs for leaf windows. Marking window | 6057 | /* Mark glyphs for leaf windows. Marking window |
| 6014 | matrices is sufficient because frame matrices | 6058 | matrices is sufficient because frame matrices |
| 6015 | use the same glyph memory. */ | 6059 | use the same glyph memory. */ |
| 6016 | if (NILP (w->hchild) && NILP (w->vchild) | 6060 | if (leaf && w->current_matrix) |
| 6017 | && w->current_matrix) | ||
| 6018 | { | 6061 | { |
| 6019 | mark_glyph_matrix (w->current_matrix); | 6062 | mark_glyph_matrix (w->current_matrix); |
| 6020 | mark_glyph_matrix (w->desired_matrix); | 6063 | mark_glyph_matrix (w->desired_matrix); |
| @@ -6081,10 +6124,14 @@ mark_object (Lisp_Object arg) | |||
| 6081 | case SYMBOL_LOCALIZED: | 6124 | case SYMBOL_LOCALIZED: |
| 6082 | { | 6125 | { |
| 6083 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); | 6126 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); |
| 6084 | /* If the value is forwarded to a buffer or keyboard field, | 6127 | Lisp_Object where = blv->where; |
| 6085 | these are marked when we see the corresponding object. | 6128 | /* 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 | 6129 | frame, restore it's global binding. If the value is |
| 6087 | a Lisp_Object var, or it's staticpro'd already. */ | 6130 | forwarded to a C variable, either it's not a Lisp_Object |
| 6131 | var, or it's staticpro'd already. */ | ||
| 6132 | if ((BUFFERP (where) && !BUFFER_LIVE_P (XBUFFER (where))) | ||
| 6133 | || (FRAMEP (where) && !FRAME_LIVE_P (XFRAME (where)))) | ||
| 6134 | swap_in_global_binding (ptr); | ||
| 6088 | mark_object (blv->where); | 6135 | mark_object (blv->where); |
| 6089 | mark_object (blv->valcell); | 6136 | mark_object (blv->valcell); |
| 6090 | mark_object (blv->defcell); | 6137 | mark_object (blv->defcell); |