aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorDmitry Antipov2012-07-02 10:23:15 +0400
committerDmitry Antipov2012-07-02 10:23:15 +0400
commitcf5c017598d130e76e96c47045372ba4a9ad6404 (patch)
tree2b332b43249d16d5f11c52fd646932d044a8034c /src/alloc.c
parent6651c01506b4c903a8e473544ee4f7af9c555bca (diff)
downloademacs-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.c237
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
271static Lisp_Object Qpost_gc_hook; 271static Lisp_Object Qpost_gc_hook;
272 272
273static void mark_buffer (Lisp_Object);
274static void mark_terminals (void); 273static void mark_terminals (void);
275static void gc_sweep (void); 274static void gc_sweep (void);
276static Lisp_Object make_pure_vector (ptrdiff_t); 275static 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
5791static void
5792mark_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
5790void 5831void
5791mark_object (Lisp_Object arg) 5832mark_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
6097static void
6098mark_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