1 /* Simple garbage collection for the GNU compiler.
2 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
31 /* Debugging flags. */
33 /* Zap memory before freeing to catch dangling pointers. */
36 /* Log alloc and release. Don't enable this unless you want a
37 really really lot of data. */
40 /* Some magic tags for strings and anonymous memory, hoping to catch
41 certain errors wrt marking memory. */
43 #define IS_MARKED(X) ((X) & 1)
44 #define IGNORE_MARK(X) ((X) & -2)
46 #define GGC_STRING_MAGIC ((unsigned int)0xa1b2c3d4)
47 #define GGC_STRING_MAGIC_MARK ((unsigned int)0xa1b2c3d4 | 1)
49 #define GGC_ANY_MAGIC ((unsigned int)0xa9bacbdc)
50 #define GGC_ANY_MAGIC_MARK ((unsigned int)0xa9bacbdc | 1)
52 /* Constants for general use. */
56 /* Global lists of roots, rtxs, and trees. */
60 struct ggc_rtx
*chain
;
66 struct ggc_rtvec
*chain
;
72 struct ggc_tree
*chain
;
78 struct ggc_string
*chain
;
79 unsigned int magic_mark
;
83 /* A generic allocation, with an external mark bit. */
87 struct ggc_any
*chain
;
88 unsigned int magic_mark
;
90 /* Make sure the data is reasonably aligned. */
94 #ifdef HAVE_LONG_DOUBLE
104 struct ggc_status
*next
;
105 struct ggc_rtx
*rtxs
;
106 struct ggc_rtvec
*vecs
;
107 struct ggc_tree
*trees
;
108 struct ggc_string
*strings
;
109 struct ggc_any
*anys
;
110 size_t bytes_alloced_since_gc
;
113 /* A chain of GGC contexts. The currently active context is at the
114 front of the chain. */
115 static struct ggc_status
*ggc_chain
;
117 /* Some statistics. */
119 static int n_rtxs_collected
;
120 static int n_vecs_collected
;
121 static int n_trees_collected
;
122 static int n_strings_collected
;
123 static int n_anys_collected
;
130 /* Local function prototypes. */
132 static void ggc_free_rtx
PROTO ((struct ggc_rtx
*r
));
133 static void ggc_free_rtvec
PROTO ((struct ggc_rtvec
*v
));
134 static void ggc_free_tree
PROTO ((struct ggc_tree
*t
));
135 static void ggc_free_string
PROTO ((struct ggc_string
*s
));
136 static void ggc_free_any
PROTO ((struct ggc_any
*a
));
138 /* Called once to initialize the garbage collector. */
141 init_ggc
PROTO ((void))
143 /* Initialize the global context. */
147 dump
= fopen ("zgcdump", "w");
151 empty_string
= ggc_alloc_string ("", 0);
152 ggc_add_string_root (&empty_string
, 1);
155 /* Start a new GGC context. Memory allocated in previous contexts
156 will not be collected while the new context is active. */
159 ggc_push_context
PROTO ((void))
161 struct ggc_status
*gs
= (struct ggc_status
*) xcalloc (1, sizeof (*gs
));
162 gs
->next
= ggc_chain
;
166 /* Finish a GC context. Any uncollected memory in the new context
167 will be merged with the old context. */
170 ggc_pop_context
PROTO ((void))
175 struct ggc_string
*s
;
176 struct ggc_status
*gs
;
185 r
->chain
= gs
->next
->rtxs
;
186 gs
->next
->rtxs
= gs
->rtxs
;
194 v
->chain
= gs
->next
->vecs
;
195 gs
->next
->vecs
= gs
->vecs
;
203 t
->chain
= gs
->next
->trees
;
204 gs
->next
->trees
= gs
->trees
;
212 s
->chain
= gs
->next
->strings
;
213 gs
->next
->strings
= gs
->strings
;
216 gs
->next
->bytes_alloced_since_gc
+= gs
->bytes_alloced_since_gc
;
218 ggc_chain
= gs
->next
;
222 /* These allocators are dreadfully simple, with no caching whatsoever so
223 that Purify-like tools that do allocation versioning can catch errors.
224 This collector is never going to go fast anyway. */
227 ggc_alloc_rtx (nslots
)
231 int size
= sizeof(*n
) + (nslots
-1) * sizeof(rtunion
);
233 n
= (struct ggc_rtx
*) xcalloc (1, size
);
234 n
->chain
= ggc_chain
->rtxs
;
238 fprintf (dump
, "alloc rtx %p\n", &n
->rtx
);
241 ggc_chain
->bytes_alloced_since_gc
+= size
;
247 ggc_alloc_rtvec (nelt
)
251 int size
= sizeof (*v
) + (nelt
- 1) * sizeof (rtx
);
253 v
= (struct ggc_rtvec
*) xcalloc (1, size
);
254 v
->chain
= ggc_chain
->vecs
;
258 fprintf(dump
, "alloc vec %p\n", &v
->vec
);
261 ggc_chain
->bytes_alloced_since_gc
+= size
;
267 ggc_alloc_tree (length
)
271 int size
= sizeof(*n
) - sizeof(n
->tree
) + length
;
273 n
= (struct ggc_tree
*) xcalloc (1, size
);
274 n
->chain
= ggc_chain
->trees
;
275 ggc_chain
->trees
= n
;
278 fprintf(dump
, "alloc tree %p\n", &n
->tree
);
281 ggc_chain
->bytes_alloced_since_gc
+= size
;
287 ggc_alloc_string (contents
, length
)
288 const char *contents
;
291 struct ggc_string
*s
;
296 if (contents
== NULL
)
298 length
= strlen (contents
);
301 size
= (s
->string
- (char *)s
) + length
+ 1;
302 s
= (struct ggc_string
*) xmalloc (size
);
303 s
->chain
= ggc_chain
->strings
;
304 s
->magic_mark
= GGC_STRING_MAGIC
;
305 ggc_chain
->strings
= s
;
308 memcpy (s
->string
, contents
, length
);
309 s
->string
[length
] = 0;
312 fprintf(dump
, "alloc string %p\n", &s
->string
);
315 ggc_chain
->bytes_alloced_since_gc
+= size
;
320 /* Like xmalloc, but allocates GC-able memory. */
330 bytes
+= (&((struct ggc_any
*) 0)->u
.c
- (char *) 0);
332 a
= (struct ggc_any
*) xmalloc (bytes
);
333 a
->chain
= ggc_chain
->anys
;
334 a
->magic_mark
= GGC_ANY_MAGIC
;
337 ggc_chain
->bytes_alloced_since_gc
+= bytes
;
342 /* Freeing a bit of rtl is as simple as calling free. */
349 fprintf (dump
, "collect rtx %p\n", &r
->rtx
);
352 memset (r
, 0xAA, sizeof(*r
) + ((GET_RTX_LENGTH (r
->rtx
.code
) -1)
359 /* Freeing an rtvec is as simple as calling free. */
366 fprintf(dump
, "collect vec %p\n", &v
->vec
);
369 memset (v
, 0xBB, sizeof (*v
) + ((GET_NUM_ELEM (&v
->vec
) - 1)
376 /* Freeing a tree node is almost, but not quite, as simple as calling free.
377 Mostly we need to let the language clean up its lang_specific bits. */
384 fprintf (dump
, "collect tree %p\n", &t
->tree
);
387 memset(&t
->tree
.common
, 0xCC, sizeof(t
->tree
.common
));
393 /* Freeing a string is as simple as calling free. */
397 struct ggc_string
*s
;
400 fprintf(dump
, "collect string %p\n", s
->string
);
403 s
->magic_mark
= 0xDDDDDDDD;
410 /* Freeing anonymous memory is as simple as calling free. */
417 fprintf(dump
, "collect mem %p\n", &a
->u
);
420 a
->magic_mark
= 0xEEEEEEEE;
432 int marked
= r
->gc_mark
;
439 ggc_set_mark_rtvec (v
)
442 int marked
= v
->gc_mark
;
449 ggc_set_mark_tree (t
)
452 int marked
= t
->common
.gc_mark
;
454 t
->common
.gc_mark
= 1;
462 const ptrdiff_t d
= (((struct ggc_string
*) 0)->string
- (char *) 0);
463 struct ggc_string
*gs
;
468 gs
= (struct ggc_string
*)(s
- d
);
469 if (IGNORE_MARK (gs
->magic_mark
) != GGC_STRING_MAGIC
)
471 gs
->magic_mark
= GGC_STRING_MAGIC_MARK
;
474 /* Mark P, allocated with ggc_alloc. */
480 const ptrdiff_t d
= (&((struct ggc_any
*) 0)->u
.c
- (char *) 0);
486 a
= (struct ggc_any
*) (((char*) p
) - d
);
487 if (IGNORE_MARK (a
->magic_mark
) != GGC_ANY_MAGIC
)
489 a
->magic_mark
= GGC_ANY_MAGIC_MARK
;
492 /* The top level mark-and-sweep routine. */
497 struct ggc_rtx
*r
, **rp
;
498 struct ggc_rtvec
*v
, **vp
;
499 struct ggc_tree
*t
, **tp
;
500 struct ggc_string
*s
, **sp
;
501 struct ggc_status
*gs
;
502 struct ggc_any
*a
, **ap
;
503 int time
, n_rtxs
, n_trees
, n_vecs
, n_strings
, n_anys
;
505 #if !defined(ENABLE_CHECKING)
506 /* See if it's even worth our while. */
507 if (ggc_chain
->bytes_alloced_since_gc
< 4*1024*1024)
512 fputs (" {GC ", stderr
);
514 time
= get_run_time ();
516 /* Clean out all of the GC marks. */
517 for (gs
= ggc_chain
; gs
; gs
= gs
->next
)
519 for (r
= gs
->rtxs
; r
!= NULL
; r
= r
->chain
)
521 for (v
= gs
->vecs
; v
!= NULL
; v
= v
->chain
)
523 for (t
= gs
->trees
; t
!= NULL
; t
= t
->chain
)
524 t
->tree
.common
.gc_mark
= 0;
525 for (s
= gs
->strings
; s
!= NULL
; s
= s
->chain
)
526 s
->magic_mark
= GGC_STRING_MAGIC
;
527 for (a
= gs
->anys
; a
!= NULL
; a
= a
->chain
)
528 a
->magic_mark
= GGC_ANY_MAGIC
;
533 /* Sweep the resulting dead nodes. */
537 rp
= &ggc_chain
->rtxs
;
542 struct ggc_rtx
*chain
= r
->chain
;
554 n_rtxs_collected
+= n_rtxs
;
558 vp
= &ggc_chain
->vecs
;
563 struct ggc_rtvec
*chain
= v
->chain
;
575 n_vecs_collected
+= n_vecs
;
579 tp
= &ggc_chain
->trees
;
580 t
= ggc_chain
->trees
;
584 struct ggc_tree
*chain
= t
->chain
;
585 if (!t
->tree
.common
.gc_mark
)
596 n_trees_collected
+= n_trees
;
600 sp
= &ggc_chain
->strings
;
601 s
= ggc_chain
->strings
;
605 struct ggc_string
*chain
= s
->chain
;
606 if (! IS_MARKED (s
->magic_mark
))
617 n_strings_collected
+= n_strings
;
619 /* The generic data. */
621 ap
= &ggc_chain
->anys
;
626 struct ggc_any
*chain
= a
->chain
;
627 if (! IS_MARKED (a
->magic_mark
))
637 n_anys_collected
+= n_anys
;
639 ggc_chain
->bytes_alloced_since_gc
= 0;
641 time
= get_run_time () - time
;
646 time
= (time
+ 500) / 1000;
647 fprintf (stderr
, "%dr,%dv,%dt,%ds,%da %d.%03d}", n_rtxs
, n_vecs
,
648 n_trees
, n_strings
, n_anys
, time
/ 1000, time
% 1000);
653 /* GDB really should have a memory search function. Since this is just
654 for initial debugging, I won't even pretend to get the __data_start
655 to work on any but alpha-dec-linux-gnu. */
657 search_data(void **start
, void *target
)
659 extern void *__data_start
[];
660 void **_end
= (void **)sbrk(0);
663 start
= __data_start
;
666 if (*start
== target
)