diff options
| author | Dmitry Antipov | 2012-07-02 10:23:15 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-07-02 10:23:15 +0400 |
| commit | cf5c017598d130e76e96c47045372ba4a9ad6404 (patch) | |
| tree | 2b332b43249d16d5f11c52fd646932d044a8034c /src/alloc.c | |
| parent | 6651c01506b4c903a8e473544ee4f7af9c555bca (diff) | |
| download | emacs-cf5c017598d130e76e96c47045372ba4a9ad6404.tar.gz emacs-cf5c017598d130e76e96c47045372ba4a9ad6404.zip | |
* alloc.c (mark_buffer): Simplify. Remove prototype.
(mark_object): Add comment. Reorganize marking of vector-like
objects. Use CHECK_LIVE for all vector-like ojects except buffers
and subroutines when GC_CHECK_MARKED_OBJECTS is defined. Avoid
redundant calls to mark_vectorlike for bool vectors.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 237 |
1 files changed, 125 insertions, 112 deletions
diff --git a/src/alloc.c b/src/alloc.c index bb57d46ee03..b059d6c04a6 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -270,7 +270,6 @@ Lisp_Object Qchar_table_extra_slots; | |||
| 270 | 270 | ||
| 271 | static Lisp_Object Qpost_gc_hook; | 271 | static Lisp_Object Qpost_gc_hook; |
| 272 | 272 | ||
| 273 | static void mark_buffer (Lisp_Object); | ||
| 274 | static void mark_terminals (void); | 273 | static void mark_terminals (void); |
| 275 | static void gc_sweep (void); | 274 | static void gc_sweep (void); |
| 276 | static Lisp_Object make_pure_vector (ptrdiff_t); | 275 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -5787,6 +5786,48 @@ mark_char_table (struct Lisp_Vector *ptr) | |||
| 5787 | } | 5786 | } |
| 5788 | } | 5787 | } |
| 5789 | 5788 | ||
| 5789 | /* Mark the pointers in a buffer structure. */ | ||
| 5790 | |||
| 5791 | static void | ||
| 5792 | mark_buffer (struct buffer *buffer) | ||
| 5793 | { | ||
| 5794 | register Lisp_Object *ptr, tmp; | ||
| 5795 | |||
| 5796 | eassert (!VECTOR_MARKED_P (buffer)); | ||
| 5797 | VECTOR_MARK (buffer); | ||
| 5798 | |||
| 5799 | MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | ||
| 5800 | |||
| 5801 | /* For now, we just don't mark the undo_list. It's done later in | ||
| 5802 | a special way just before the sweep phase, and after stripping | ||
| 5803 | some of its elements that are not needed any more. */ | ||
| 5804 | |||
| 5805 | if (buffer->overlays_before) | ||
| 5806 | { | ||
| 5807 | XSETMISC (tmp, buffer->overlays_before); | ||
| 5808 | mark_object (tmp); | ||
| 5809 | } | ||
| 5810 | if (buffer->overlays_after) | ||
| 5811 | { | ||
| 5812 | XSETMISC (tmp, buffer->overlays_after); | ||
| 5813 | mark_object (tmp); | ||
| 5814 | } | ||
| 5815 | |||
| 5816 | /* buffer-local Lisp variables start at `undo_list', | ||
| 5817 | tho only the ones from `name' on are GC'd normally. */ | ||
| 5818 | for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); | ||
| 5819 | ptr <= &PER_BUFFER_VALUE (buffer, | ||
| 5820 | PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER)); | ||
| 5821 | ptr++) | ||
| 5822 | mark_object (*ptr); | ||
| 5823 | |||
| 5824 | /* If this is an indirect buffer, mark its base buffer. */ | ||
| 5825 | if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) | ||
| 5826 | mark_buffer (buffer->base_buffer); | ||
| 5827 | } | ||
| 5828 | |||
| 5829 | /* Determine type of generic Lisp_Object and mark it accordingly. */ | ||
| 5830 | |||
| 5790 | void | 5831 | void |
| 5791 | mark_object (Lisp_Object arg) | 5832 | mark_object (Lisp_Object arg) |
| 5792 | { | 5833 | { |
| @@ -5863,77 +5904,88 @@ mark_object (Lisp_Object arg) | |||
| 5863 | break; | 5904 | break; |
| 5864 | 5905 | ||
| 5865 | case Lisp_Vectorlike: | 5906 | case Lisp_Vectorlike: |
| 5866 | if (VECTOR_MARKED_P (XVECTOR (obj))) | 5907 | { |
| 5867 | break; | 5908 | register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5909 | register ptrdiff_t pvectype; | ||
| 5910 | |||
| 5911 | if (VECTOR_MARKED_P (ptr)) | ||
| 5912 | break; | ||
| 5913 | |||
| 5868 | #ifdef GC_CHECK_MARKED_OBJECTS | 5914 | #ifdef GC_CHECK_MARKED_OBJECTS |
| 5869 | m = mem_find (po); | 5915 | m = mem_find (po); |
| 5870 | if (m == MEM_NIL && !SUBRP (obj) | 5916 | if (m == MEM_NIL && !SUBRP (obj) |
| 5871 | && po != &buffer_defaults | 5917 | && po != &buffer_defaults |
| 5872 | && po != &buffer_local_symbols) | 5918 | && po != &buffer_local_symbols) |
| 5873 | abort (); | 5919 | abort (); |
| 5874 | #endif /* GC_CHECK_MARKED_OBJECTS */ | 5920 | #endif /* GC_CHECK_MARKED_OBJECTS */ |
| 5875 | 5921 | ||
| 5876 | if (BUFFERP (obj)) | 5922 | if (ptr->header.size & PSEUDOVECTOR_FLAG) |
| 5877 | { | 5923 | pvectype = ptr->header.size & PVEC_TYPE_MASK; |
| 5924 | else | ||
| 5925 | pvectype = 0; | ||
| 5926 | |||
| 5878 | #ifdef GC_CHECK_MARKED_OBJECTS | 5927 | #ifdef GC_CHECK_MARKED_OBJECTS |
| 5879 | if (po != &buffer_defaults && po != &buffer_local_symbols) | 5928 | if (pvectype != PVEC_SUBR && pvectype != PVEC_BUFFER) |
| 5880 | { | 5929 | CHECK_LIVE (live_vector_p); |
| 5881 | struct buffer *b; | ||
| 5882 | for (b = all_buffers; b && b != po; b = b->header.next.buffer) | ||
| 5883 | ; | ||
| 5884 | if (b == NULL) | ||
| 5885 | abort (); | ||
| 5886 | } | ||
| 5887 | #endif /* GC_CHECK_MARKED_OBJECTS */ | 5930 | #endif /* GC_CHECK_MARKED_OBJECTS */ |
| 5888 | mark_buffer (obj); | ||
| 5889 | } | ||
| 5890 | else if (SUBRP (obj)) | ||
| 5891 | break; | ||
| 5892 | else if (COMPILEDP (obj)) | ||
| 5893 | /* We could treat this just like a vector, but it is better to | ||
| 5894 | save the COMPILED_CONSTANTS element for last and avoid | ||
| 5895 | recursion there. */ | ||
| 5896 | { | ||
| 5897 | register struct Lisp_Vector *ptr = XVECTOR (obj); | ||
| 5898 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; | ||
| 5899 | int i; | ||
| 5900 | 5931 | ||
| 5901 | CHECK_LIVE (live_vector_p); | 5932 | if (pvectype == PVEC_BUFFER) |
| 5902 | VECTOR_MARK (ptr); /* Else mark it */ | 5933 | { |
| 5903 | for (i = 0; i < size; i++) /* and then mark its elements */ | 5934 | #ifdef GC_CHECK_MARKED_OBJECTS |
| 5904 | { | 5935 | if (po != &buffer_defaults && po != &buffer_local_symbols) |
| 5936 | { | ||
| 5937 | struct buffer *b = all_buffers; | ||
| 5938 | for (; b && b != po; b = b->header.next.buffer) | ||
| 5939 | ; | ||
| 5940 | if (b == NULL) | ||
| 5941 | abort (); | ||
| 5942 | } | ||
| 5943 | #endif /* GC_CHECK_MARKED_OBJECTS */ | ||
| 5944 | mark_buffer ((struct buffer *) ptr); | ||
| 5945 | } | ||
| 5946 | |||
| 5947 | else if (pvectype == PVEC_COMPILED) | ||
| 5948 | /* We could treat this just like a vector, but it is better | ||
| 5949 | to save the COMPILED_CONSTANTS element for last and avoid | ||
| 5950 | recursion there. */ | ||
| 5951 | { | ||
| 5952 | int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK; | ||
| 5953 | int i; | ||
| 5954 | |||
| 5955 | VECTOR_MARK (ptr); | ||
| 5956 | for (i = 0; i < size; i++) | ||
| 5905 | if (i != COMPILED_CONSTANTS) | 5957 | if (i != COMPILED_CONSTANTS) |
| 5906 | mark_object (ptr->contents[i]); | 5958 | mark_object (ptr->contents[i]); |
| 5907 | } | 5959 | obj = ptr->contents[COMPILED_CONSTANTS]; |
| 5908 | obj = ptr->contents[COMPILED_CONSTANTS]; | 5960 | goto loop; |
| 5909 | goto loop; | 5961 | } |
| 5910 | } | 5962 | |
| 5911 | else if (FRAMEP (obj)) | 5963 | else if (pvectype == PVEC_FRAME) |
| 5912 | { | 5964 | { |
| 5913 | register struct frame *ptr = XFRAME (obj); | 5965 | mark_vectorlike (ptr); |
| 5914 | mark_vectorlike (XVECTOR (obj)); | 5966 | mark_face_cache (((struct frame *) ptr)->face_cache); |
| 5915 | mark_face_cache (ptr->face_cache); | 5967 | } |
| 5916 | } | 5968 | |
| 5917 | else if (WINDOWP (obj)) | 5969 | else if (pvectype == PVEC_WINDOW) |
| 5970 | { | ||
| 5971 | struct window *w = (struct window *) ptr; | ||
| 5972 | |||
| 5973 | mark_vectorlike (ptr); | ||
| 5974 | /* Mark glyphs for leaf windows. Marking window | ||
| 5975 | matrices is sufficient because frame matrices | ||
| 5976 | use the same glyph memory. */ | ||
| 5977 | if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix) | ||
| 5978 | { | ||
| 5979 | mark_glyph_matrix (w->current_matrix); | ||
| 5980 | mark_glyph_matrix (w->desired_matrix); | ||
| 5981 | } | ||
| 5982 | } | ||
| 5983 | |||
| 5984 | else if (pvectype == PVEC_HASH_TABLE) | ||
| 5918 | { | 5985 | { |
| 5919 | register struct Lisp_Vector *ptr = XVECTOR (obj); | 5986 | struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr; |
| 5920 | struct window *w = XWINDOW (obj); | 5987 | |
| 5921 | mark_vectorlike (ptr); | 5988 | mark_vectorlike (ptr); |
| 5922 | /* Mark glyphs for leaf windows. Marking window matrices is | ||
| 5923 | sufficient because frame matrices use the same glyph | ||
| 5924 | memory. */ | ||
| 5925 | if (NILP (w->hchild) | ||
| 5926 | && NILP (w->vchild) | ||
| 5927 | && w->current_matrix) | ||
| 5928 | { | ||
| 5929 | mark_glyph_matrix (w->current_matrix); | ||
| 5930 | mark_glyph_matrix (w->desired_matrix); | ||
| 5931 | } | ||
| 5932 | } | ||
| 5933 | else if (HASH_TABLE_P (obj)) | ||
| 5934 | { | ||
| 5935 | struct Lisp_Hash_Table *h = XHASH_TABLE (obj); | ||
| 5936 | mark_vectorlike ((struct Lisp_Vector *)h); | ||
| 5937 | /* If hash table is not weak, mark all keys and values. | 5989 | /* If hash table is not weak, mark all keys and values. |
| 5938 | For weak tables, mark only the vector. */ | 5990 | For weak tables, mark only the vector. */ |
| 5939 | if (NILP (h->weak)) | 5991 | if (NILP (h->weak)) |
| @@ -5941,10 +5993,17 @@ mark_object (Lisp_Object arg) | |||
| 5941 | else | 5993 | else |
| 5942 | VECTOR_MARK (XVECTOR (h->key_and_value)); | 5994 | VECTOR_MARK (XVECTOR (h->key_and_value)); |
| 5943 | } | 5995 | } |
| 5944 | else if (CHAR_TABLE_P (obj)) | 5996 | |
| 5945 | mark_char_table (XVECTOR (obj)); | 5997 | else if (pvectype == PVEC_CHAR_TABLE) |
| 5946 | else | 5998 | mark_char_table (ptr); |
| 5947 | mark_vectorlike (XVECTOR (obj)); | 5999 | |
| 6000 | else if (pvectype == PVEC_BOOL_VECTOR) | ||
| 6001 | /* No Lisp_Objects to mark in a bool vector. */ | ||
| 6002 | VECTOR_MARK (ptr); | ||
| 6003 | |||
| 6004 | else if (pvectype != PVEC_SUBR) | ||
| 6005 | mark_vectorlike (ptr); | ||
| 6006 | } | ||
| 5948 | break; | 6007 | break; |
| 5949 | 6008 | ||
| 5950 | case Lisp_Symbol: | 6009 | case Lisp_Symbol: |
| @@ -6091,52 +6150,6 @@ mark_object (Lisp_Object arg) | |||
| 6091 | #undef CHECK_ALLOCATED | 6150 | #undef CHECK_ALLOCATED |
| 6092 | #undef CHECK_ALLOCATED_AND_LIVE | 6151 | #undef CHECK_ALLOCATED_AND_LIVE |
| 6093 | } | 6152 | } |
| 6094 | |||
| 6095 | /* Mark the pointers in a buffer structure. */ | ||
| 6096 | |||
| 6097 | static void | ||
| 6098 | mark_buffer (Lisp_Object buf) | ||
| 6099 | { | ||
| 6100 | register struct buffer *buffer = XBUFFER (buf); | ||
| 6101 | register Lisp_Object *ptr, tmp; | ||
| 6102 | Lisp_Object base_buffer; | ||
| 6103 | |||
| 6104 | eassert (!VECTOR_MARKED_P (buffer)); | ||
| 6105 | VECTOR_MARK (buffer); | ||
| 6106 | |||
| 6107 | MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | ||
| 6108 | |||
| 6109 | /* For now, we just don't mark the undo_list. It's done later in | ||
| 6110 | a special way just before the sweep phase, and after stripping | ||
| 6111 | some of its elements that are not needed any more. */ | ||
| 6112 | |||
| 6113 | if (buffer->overlays_before) | ||
| 6114 | { | ||
| 6115 | XSETMISC (tmp, buffer->overlays_before); | ||
| 6116 | mark_object (tmp); | ||
| 6117 | } | ||
| 6118 | if (buffer->overlays_after) | ||
| 6119 | { | ||
| 6120 | XSETMISC (tmp, buffer->overlays_after); | ||
| 6121 | mark_object (tmp); | ||
| 6122 | } | ||
| 6123 | |||
| 6124 | /* buffer-local Lisp variables start at `undo_list', | ||
| 6125 | tho only the ones from `name' on are GC'd normally. */ | ||
| 6126 | for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name); | ||
| 6127 | ptr <= &PER_BUFFER_VALUE (buffer, | ||
| 6128 | PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER)); | ||
| 6129 | ptr++) | ||
| 6130 | mark_object (*ptr); | ||
| 6131 | |||
| 6132 | /* If this is an indirect buffer, mark its base buffer. */ | ||
| 6133 | if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) | ||
| 6134 | { | ||
| 6135 | XSETBUFFER (base_buffer, buffer->base_buffer); | ||
| 6136 | mark_buffer (base_buffer); | ||
| 6137 | } | ||
| 6138 | } | ||
| 6139 | |||
| 6140 | /* Mark the Lisp pointers in the terminal objects. | 6153 | /* Mark the Lisp pointers in the terminal objects. |
| 6141 | Called by Fgarbage_collect. */ | 6154 | Called by Fgarbage_collect. */ |
| 6142 | 6155 | ||