aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorGerd Moellmann1999-07-21 21:43:52 +0000
committerGerd Moellmann1999-07-21 21:43:52 +0000
commit41c28a3753d17471b669cabb85c3bd5a375e78d7 (patch)
treebf708c4ef6d27375ea283a42008ae44ae32931b1 /src/alloc.c
parentecfd95532daefab697b130da736ecdc7cb292169 (diff)
downloademacs-41c28a3753d17471b669cabb85c3bd5a375e78d7.tar.gz
emacs-41c28a3753d17471b669cabb85c3bd5a375e78d7.zip
(gc_sweep): Call sweep_weak_hash_tables.
(survives_gc_p): New. (mark_object): Mark objects referenced from glyphs, hash tables, toolbar date, toolbar window, face caches, menu bar window. Mark windows specially. (Fgarbage_collect): Use message3_nolog. (mark_face_cache): New. (NSTATICS): Increased to 1024. (mark_glyph_matrix): New.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c291
1 files changed, 287 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 79e3278680b..1ae6cdd153a 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -192,9 +192,17 @@ int ignore_warnings;
192 192
193Lisp_Object Qgc_cons_threshold, Qchar_table_extra_slots; 193Lisp_Object Qgc_cons_threshold, Qchar_table_extra_slots;
194 194
195static void mark_object (), mark_buffer (), mark_kboards (); 195static void mark_buffer (), mark_kboards ();
196static void clear_marks (), gc_sweep (); 196static void clear_marks (), gc_sweep ();
197static void compact_strings (); 197static void compact_strings ();
198static void mark_glyph_matrix P_ ((struct glyph_matrix *));
199static void mark_face_cache P_ ((struct face_cache *));
200
201#ifdef HAVE_WINDOW_SYSTEM
202static void mark_image P_ ((struct image *));
203static void mark_image_cache P_ ((struct frame *));
204#endif /* HAVE_WINDOW_SYSTEM */
205
198 206
199extern int message_enable_multibyte; 207extern int message_enable_multibyte;
200 208
@@ -1667,7 +1675,7 @@ Does not copy symbols.")
1667 1675
1668struct gcpro *gcprolist; 1676struct gcpro *gcprolist;
1669 1677
1670#define NSTATICS 768 1678#define NSTATICS 1024
1671 1679
1672Lisp_Object *staticvec[NSTATICS] = {0}; 1680Lisp_Object *staticvec[NSTATICS] = {0};
1673 1681
@@ -1739,15 +1747,19 @@ Garbage collection happens automatically if you cons more than\n\
1739 register struct backtrace *backlist; 1747 register struct backtrace *backlist;
1740 register Lisp_Object tem; 1748 register Lisp_Object tem;
1741 char *omessage = echo_area_glyphs; 1749 char *omessage = echo_area_glyphs;
1750 Lisp_Object omessage_string = echo_area_message;
1742 int omessage_length = echo_area_glyphs_length; 1751 int omessage_length = echo_area_glyphs_length;
1743 int oldmultibyte = message_enable_multibyte; 1752 int oldmultibyte = message_enable_multibyte;
1744 char stack_top_variable; 1753 char stack_top_variable;
1745 register int i; 1754 register int i;
1755 struct gcpro gcpro1;
1746 1756
1747 /* In case user calls debug_print during GC, 1757 /* In case user calls debug_print during GC,
1748 don't let that cause a recursive GC. */ 1758 don't let that cause a recursive GC. */
1749 consing_since_gc = 0; 1759 consing_since_gc = 0;
1750 1760
1761 GCPRO1 (omessage_string);
1762
1751 /* Save a copy of the contents of the stack, for debugging. */ 1763 /* Save a copy of the contents of the stack, for debugging. */
1752#if MAX_SAVE_STACK > 0 1764#if MAX_SAVE_STACK > 0
1753 if (NILP (Vpurify_flag)) 1765 if (NILP (Vpurify_flag))
@@ -1930,12 +1942,15 @@ Garbage collection happens automatically if you cons more than\n\
1930 1942
1931 if (garbage_collection_messages) 1943 if (garbage_collection_messages)
1932 { 1944 {
1945 if (STRINGP (omessage_string))
1946 message3_nolog (omessage_string, omessage_length, oldmultibyte);
1933 if (omessage || minibuf_level > 0) 1947 if (omessage || minibuf_level > 0)
1934 message2_nolog (omessage, omessage_length, oldmultibyte); 1948 message2_nolog (omessage, omessage_length, oldmultibyte);
1935 else 1949 else
1936 message1_nolog ("Garbage collecting...done"); 1950 message1_nolog ("Garbage collecting...done");
1937 } 1951 }
1938 1952
1953 UNGCPRO;
1939 return Fcons (Fcons (make_number (total_conses), 1954 return Fcons (Fcons (make_number (total_conses),
1940 make_number (total_free_conses)), 1955 make_number (total_free_conses)),
1941 Fcons (Fcons (make_number (total_symbols), 1956 Fcons (Fcons (make_number (total_symbols),
@@ -2019,6 +2034,95 @@ clear_marks ()
2019 } 2034 }
2020} 2035}
2021#endif 2036#endif
2037
2038/* Mark Lisp objects in glyph matrix MATRIX. */
2039
2040static void
2041mark_glyph_matrix (matrix)
2042 struct glyph_matrix *matrix;
2043{
2044 struct glyph_row *row = matrix->rows;
2045 struct glyph_row *end = row + matrix->nrows;
2046
2047 while (row < end)
2048 {
2049 if (row->enabled_p)
2050 {
2051 int area;
2052 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
2053 {
2054 struct glyph *glyph = row->glyphs[area];
2055 struct glyph *end_glyph = glyph + row->used[area];
2056
2057 while (glyph < end_glyph)
2058 {
2059 if (/* OBJECT Is zero for face extending glyphs, padding
2060 spaces and such. */
2061 glyph->object
2062 /* Marking the buffer itself should not be necessary. */
2063 && !BUFFERP (glyph->object))
2064 mark_object (&glyph->object);
2065 ++glyph;
2066 }
2067 }
2068 }
2069
2070 ++row;
2071 }
2072}
2073
2074/* Mark Lisp faces in the face cache C. */
2075
2076static void
2077mark_face_cache (c)
2078 struct face_cache *c;
2079{
2080 if (c)
2081 {
2082 int i, j;
2083 for (i = 0; i < c->used; ++i)
2084 {
2085 struct face *face = FACE_FROM_ID (c->f, i);
2086
2087 if (face)
2088 {
2089 for (j = 0; j < LFACE_VECTOR_SIZE; ++j)
2090 mark_object (&face->lface[j]);
2091 mark_object (&face->registry);
2092 }
2093 }
2094 }
2095}
2096
2097
2098#ifdef HAVE_WINDOW_SYSTEM
2099
2100/* Mark Lisp objects in image IMG. */
2101
2102static void
2103mark_image (img)
2104 struct image *img;
2105{
2106 mark_object (&img->spec);
2107
2108 if (!NILP (img->data.lisp_val))
2109 mark_object (&img->data.lisp_val);
2110}
2111
2112
2113/* Mark Lisp objects in image cache of frame F. It's done this way so
2114 that we don't have to include xterm.h here. */
2115
2116static void
2117mark_image_cache (f)
2118 struct frame *f;
2119{
2120 forall_images_in_image_cache (f, mark_image);
2121}
2122
2123#endif /* HAVE_X_WINDOWS */
2124
2125
2022 2126
2023/* Mark reference to a Lisp_Object. 2127/* Mark reference to a Lisp_Object.
2024 If the object referred to has not been seen yet, recursively mark 2128 If the object referred to has not been seen yet, recursively mark
@@ -2034,7 +2138,7 @@ clear_marks ()
2034Lisp_Object *last_marked[LAST_MARKED_SIZE]; 2138Lisp_Object *last_marked[LAST_MARKED_SIZE];
2035int last_marked_index; 2139int last_marked_index;
2036 2140
2037static void 2141void
2038mark_object (argptr) 2142mark_object (argptr)
2039 Lisp_Object *argptr; 2143 Lisp_Object *argptr;
2040{ 2144{
@@ -2144,6 +2248,16 @@ mark_object (argptr)
2144 mark_object (&ptr->menu_bar_vector); 2248 mark_object (&ptr->menu_bar_vector);
2145 mark_object (&ptr->buffer_predicate); 2249 mark_object (&ptr->buffer_predicate);
2146 mark_object (&ptr->buffer_list); 2250 mark_object (&ptr->buffer_list);
2251 mark_object (&ptr->menu_bar_window);
2252 mark_object (&ptr->toolbar_window);
2253 mark_face_cache (ptr->face_cache);
2254#ifdef HAVE_WINDOW_SYSTEM
2255 mark_image_cache (ptr);
2256 mark_object (&ptr->desired_toolbar_items);
2257 mark_object (&ptr->current_toolbar_items);
2258 mark_object (&ptr->desired_toolbar_string);
2259 mark_object (&ptr->current_toolbar_string);
2260#endif /* HAVE_WINDOW_SYSTEM */
2147 } 2261 }
2148 else if (GC_BOOL_VECTOR_P (obj)) 2262 else if (GC_BOOL_VECTOR_P (obj))
2149 { 2263 {
@@ -2153,6 +2267,76 @@ mark_object (argptr)
2153 break; /* Already marked */ 2267 break; /* Already marked */
2154 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ 2268 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
2155 } 2269 }
2270 else if (GC_WINDOWP (obj))
2271 {
2272 register struct Lisp_Vector *ptr = XVECTOR (obj);
2273 struct window *w = XWINDOW (obj);
2274 register EMACS_INT size = ptr->size;
2275 /* The reason we use ptr1 is to avoid an apparent hardware bug
2276 that happens occasionally on the FSF's HP 300s.
2277 The bug is that a2 gets clobbered by recursive calls to mark_object.
2278 The clobberage seems to happen during function entry,
2279 perhaps in the moveml instruction.
2280 Yes, this is a crock, but we have to do it. */
2281 struct Lisp_Vector *volatile ptr1 = ptr;
2282 register int i;
2283
2284 /* Stop if already marked. */
2285 if (size & ARRAY_MARK_FLAG)
2286 break;
2287
2288 /* Mark it. */
2289 ptr->size |= ARRAY_MARK_FLAG;
2290
2291 /* There is no Lisp data above The member CURRENT_MATRIX in
2292 struct WINDOW. Stop marking when that slot is reached. */
2293 for (i = 0;
2294 (char *) &ptr1->contents[i] < (char *) &w->current_matrix;
2295 i++)
2296 mark_object (&ptr1->contents[i]);
2297
2298 /* Mark glyphs for leaf windows. Marking window matrices is
2299 sufficient because frame matrices use the same glyph
2300 memory. */
2301 if (NILP (w->hchild)
2302 && NILP (w->vchild)
2303 && w->current_matrix)
2304 {
2305 mark_glyph_matrix (w->current_matrix);
2306 mark_glyph_matrix (w->desired_matrix);
2307 }
2308 }
2309 else if (GC_HASH_TABLE_P (obj))
2310 {
2311 struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
2312 EMACS_INT size = h->size;
2313
2314 /* Stop if already marked. */
2315 if (size & ARRAY_MARK_FLAG)
2316 break;
2317
2318 /* Mark it. */
2319 h->size |= ARRAY_MARK_FLAG;
2320
2321 /* Mark contents. */
2322 mark_object (&h->test);
2323 mark_object (&h->weak);
2324 mark_object (&h->rehash_size);
2325 mark_object (&h->rehash_threshold);
2326 mark_object (&h->hash);
2327 mark_object (&h->next);
2328 mark_object (&h->index);
2329 mark_object (&h->user_hash_function);
2330 mark_object (&h->user_cmp_function);
2331
2332 /* If hash table is not weak, mark all keys and values.
2333 For weak tables, mark only the vector. */
2334 if (GC_NILP (h->weak))
2335 mark_object (&h->key_and_value);
2336 else
2337 XVECTOR (h->key_and_value)->size |= ARRAY_MARK_FLAG;
2338
2339 }
2156 else 2340 else
2157 { 2341 {
2158 register struct Lisp_Vector *ptr = XVECTOR (obj); 2342 register struct Lisp_Vector *ptr = XVECTOR (obj);
@@ -2170,6 +2354,7 @@ mark_object (argptr)
2170 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ 2354 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
2171 if (size & PSEUDOVECTOR_FLAG) 2355 if (size & PSEUDOVECTOR_FLAG)
2172 size &= PSEUDOVECTOR_SIZE_MASK; 2356 size &= PSEUDOVECTOR_SIZE_MASK;
2357
2173 for (i = 0; i < size; i++) /* and then mark its elements */ 2358 for (i = 0; i < size; i++) /* and then mark its elements */
2174 mark_object (&ptr1->contents[i]); 2359 mark_object (&ptr1->contents[i]);
2175 } 2360 }
@@ -2187,7 +2372,7 @@ mark_object (argptr)
2187 mark_object (&ptr->function); 2372 mark_object (&ptr->function);
2188 mark_object (&ptr->plist); 2373 mark_object (&ptr->plist);
2189 XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String); 2374 XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
2190 mark_object (&ptr->name); 2375 mark_object ((Lisp_Object *) &ptr->name);
2191 /* Note that we do not mark the obarray of the symbol. 2376 /* Note that we do not mark the obarray of the symbol.
2192 It is safe not to do so because nothing accesses that 2377 It is safe not to do so because nothing accesses that
2193 slot except to check whether it is nil. */ 2378 slot except to check whether it is nil. */
@@ -2403,12 +2588,104 @@ mark_kboards ()
2403 mark_object (&kb->Vdefault_minibuffer_frame); 2588 mark_object (&kb->Vdefault_minibuffer_frame);
2404 } 2589 }
2405} 2590}
2591
2592
2593/* Value is non-zero if OBJ will survive the current GC because it's
2594 either marked or does not need to be marked to survive. */
2595
2596int
2597survives_gc_p (obj)
2598 Lisp_Object obj;
2599{
2600 int survives_p;
2601
2602 switch (XGCTYPE (obj))
2603 {
2604 case Lisp_Int:
2605 survives_p = 1;
2606 break;
2607
2608 case Lisp_Symbol:
2609 survives_p = XMARKBIT (XSYMBOL (obj)->plist);
2610 break;
2611
2612 case Lisp_Misc:
2613 switch (XMISCTYPE (obj))
2614 {
2615 case Lisp_Misc_Marker:
2616 survives_p = XMARKBIT (obj);
2617 break;
2618
2619 case Lisp_Misc_Buffer_Local_Value:
2620 case Lisp_Misc_Some_Buffer_Local_Value:
2621 survives_p = XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue);
2622 break;
2623
2624 case Lisp_Misc_Intfwd:
2625 case Lisp_Misc_Boolfwd:
2626 case Lisp_Misc_Objfwd:
2627 case Lisp_Misc_Buffer_Objfwd:
2628 case Lisp_Misc_Kboard_Objfwd:
2629 survives_p = 1;
2630 break;
2631
2632 case Lisp_Misc_Overlay:
2633 survives_p = XMARKBIT (XOVERLAY (obj)->plist);
2634 break;
2635
2636 default:
2637 abort ();
2638 }
2639 break;
2640
2641 case Lisp_String:
2642 {
2643 struct Lisp_String *s = XSTRING (obj);
2644
2645 if (s->size & MARKBIT)
2646 survives_p = s->size & ARRAY_MARK_FLAG;
2647 else
2648 survives_p = (s->size & ~DONT_COPY_FLAG) > STRING_BLOCK_SIZE;
2649 }
2650 break;
2651
2652 case Lisp_Vectorlike:
2653 if (GC_BUFFERP (obj))
2654 survives_p = XMARKBIT (XBUFFER (obj)->name);
2655 else if (GC_SUBRP (obj))
2656 survives_p = 1;
2657 else
2658 survives_p = XVECTOR (obj)->size & ARRAY_MARK_FLAG;
2659 break;
2660
2661 case Lisp_Cons:
2662 survives_p = XMARKBIT (XCAR (obj));
2663 break;
2664
2665#ifdef LISP_FLOAT_TYPE
2666 case Lisp_Float:
2667 survives_p = XMARKBIT (XFLOAT (obj)->type);
2668 break;
2669#endif /* LISP_FLOAT_TYPE */
2670
2671 default:
2672 abort ();
2673 }
2674
2675 return survives_p;
2676}
2677
2678
2406 2679
2407/* Sweep: find all structures not marked, and free them. */ 2680/* Sweep: find all structures not marked, and free them. */
2408 2681
2409static void 2682static void
2410gc_sweep () 2683gc_sweep ()
2411{ 2684{
2685 /* Remove or mark entries in weak hash tables.
2686 This must be done before any object is unmarked. */
2687 sweep_weak_hash_tables ();
2688
2412 total_string_size = 0; 2689 total_string_size = 0;
2413 compact_strings (); 2690 compact_strings ();
2414 2691
@@ -2746,6 +3023,11 @@ gc_sweep ()
2746 while (vector) 3023 while (vector)
2747 if (!(vector->size & ARRAY_MARK_FLAG)) 3024 if (!(vector->size & ARRAY_MARK_FLAG))
2748 { 3025 {
3026#if 0
3027 if ((vector->size & (PSEUDOVECTOR_FLAG | PVEC_HASH_TABLE))
3028 == (PSEUDOVECTOR_FLAG | PVEC_HASH_TABLE))
3029 fprintf (stderr, "Freeing hash table %p\n", vector);
3030#endif
2749 if (prev) 3031 if (prev)
2750 prev->next = vector->next; 3032 prev->next = vector->next;
2751 else 3033 else
@@ -2754,6 +3036,7 @@ gc_sweep ()
2754 lisp_free (vector); 3036 lisp_free (vector);
2755 n_vectors--; 3037 n_vectors--;
2756 vector = next; 3038 vector = next;
3039
2757 } 3040 }
2758 else 3041 else
2759 { 3042 {