1 /* Simple garbage collection for the GNU compiler.
2 Copyright (C) 1998 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. */
28 /* Debugging flags. */
32 /* Global lists of roots, rtxs, and trees. */
36 struct ggc_root *next;
43 static struct ggc_root *roots;
47 struct ggc_rtx *chain;
51 static struct ggc_rtx *rtxs;
55 struct ggc_rtvec *chain;
59 static struct ggc_rtvec *vecs;
63 struct ggc_tree *chain;
67 static struct ggc_tree *trees;
71 struct ggc_string *chain;
76 #define GGC_STRING_MAGIC ((unsigned int)0xa1b2c3d4)
78 static struct ggc_string *strings;
80 /* Some statistics. */
82 static int n_rtxs_collected;
83 static int n_vecs_collected;
84 static int n_trees_collected;
85 static int n_strings_collected;
86 static int bytes_alloced_since_gc;
93 /* Local function prototypes. */
95 static void ggc_free_rtx PROTO ((struct ggc_rtx *r));
96 static void ggc_free_tree PROTO ((struct ggc_tree *t));
97 static void ggc_mark_rtx_ptr PROTO ((void *elt));
98 static void ggc_mark_tree_ptr PROTO ((void *elt));
100 /* These allocators are dreadfully simple, with no caching whatsoever so
101 that Purify-like tools that do allocation versioning can catch errors.
102 This collector is never going to go fast anyway. */
105 ggc_alloc_rtx (nslots)
109 int size = sizeof(*n) + (nslots-1) * sizeof(rtunion);
111 n = (struct ggc_rtx *) xmalloc (size);
112 bzero ((char *) n, size);
117 fprintf (dump, "alloc rtx %p\n", &n->rtx);
120 bytes_alloced_since_gc += size;
126 ggc_alloc_rtvec (nelt)
130 int size = sizeof (*v) + (nelt - 1) * sizeof (rtunion);
132 v = (struct ggc_rtvec *) xmalloc (size);
133 bzero ((char *) v, size);
138 fprintf(dump, "alloc vec %p\n", &v->vec);
141 bytes_alloced_since_gc += size;
147 ggc_alloc_tree (length)
151 int size = sizeof(*n) - sizeof(n->tree) + length;
153 n = (struct ggc_tree *) xmalloc (size);
154 bzero ((char *) n, size);
159 fprintf(dump, "alloc tree %p\n", &n->tree);
162 bytes_alloced_since_gc += size;
168 ggc_alloc_string (contents, length)
169 const char *contents;
172 struct ggc_string *s;
177 if (contents == NULL)
179 length = strlen (contents);
182 size = (s->string - (char *)s) + length + 1;
183 s = (struct ggc_string *) xmalloc(size);
185 s->magic_mark = GGC_STRING_MAGIC;
187 bcopy (contents, s->string, length);
188 s->string[length] = 0;
192 fprintf(dump, "alloc string %p\n", &n->tree);
195 bytes_alloced_since_gc += size;
201 /* Freeing a bit of rtl isn't quite as simple as calling free, there are
202 a few associated bits that might need freeing as well. */
209 fprintf (dump, "collect rtx %p\n", &r->rtx);
212 memset (r, 0xAA, sizeof(*r));
218 /* Freeing an rtvec is as simple as calling free. */
225 fprintf(dump, "collect vec %p\n", &v->vec);
228 memset (v, 0xBB, sizeof (*v) + ((GET_NUM_ELEM (&v->vec) - 1)
229 * sizeof (rtunion)));
235 /* Freeing a tree node is almost, but not quite, as simple as calling free.
236 Mostly we need to let the language clean up its lang_specific bits. */
242 switch (TREE_CODE_CLASS (TREE_CODE (&t->tree)))
244 case 'd': /* A decl node. */
245 case 't': /* A type node. */
246 lang_cleanup_tree (&t->tree);
251 fprintf (dump, "collect tree %p\n", &t->tree);
254 memset(&t->tree.common, 0xCC, sizeof(t->tree.common));
260 /* Freeing a string is as simple as calling free. */
264 struct ggc_string *s;
267 fprintf(dump, "collect string %p\n", s->string);
270 s->magic_mark = 0xDDDDDDDD;
286 if (r == NULL_RTX || r->gc_mark)
290 /* ??? If (some of) these are really pass-dependant info, do we have
291 any right poking our noses in? */
292 switch (GET_CODE (r))
295 ggc_mark_rtx (JUMP_LABEL (r));
298 ggc_mark_rtx (LABEL_REFS (r));
301 ggc_mark_rtx (LABEL_NEXTREF (r));
302 ggc_mark_rtx (CONTAINING_INSN (r));
305 ggc_mark_tree (ADDRESSOF_DECL (r));
308 ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
315 for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
320 ggc_mark_rtx (XEXP (r, i));
323 ggc_mark_rtvec (XVEC (r, i));
326 ggc_mark_string (XSTR (r, i));
338 if (v == NULL || v->gc_mark)
342 i = GET_NUM_ELEM (v);
344 ggc_mark_rtx (RTVEC_ELT (v, i));
351 if (t == NULL_TREE || t->common.gc_mark)
353 t->common.gc_mark = 1;
355 /* Bits from common. */
356 ggc_mark_tree (TREE_TYPE (t));
357 ggc_mark_tree (TREE_CHAIN (t));
359 /* Some nodes require special handling. */
360 switch (TREE_CODE (t))
363 ggc_mark_tree (TREE_PURPOSE (t));
364 ggc_mark_tree (TREE_VALUE (t));
369 int i = TREE_VEC_LENGTH (t);
371 ggc_mark_tree (TREE_VEC_ELT (t, i));
376 ggc_mark_tree (TREE_OPERAND (t, 0));
377 ggc_mark_tree (SAVE_EXPR_CONTEXT (t));
378 ggc_mark_rtx (SAVE_EXPR_RTL (t));
382 ggc_mark_rtx (RTL_EXPR_SEQUENCE (t));
383 ggc_mark_rtx (RTL_EXPR_RTL (t));
387 ggc_mark_tree (TREE_OPERAND (t, 0));
388 ggc_mark_tree (TREE_OPERAND (t, 1));
389 ggc_mark_rtx (CALL_EXPR_RTL (t));
393 ggc_mark_tree (TREE_REALPART (t));
394 ggc_mark_tree (TREE_IMAGPART (t));
398 ggc_mark_string (TREE_STRING_POINTER (t));
402 ggc_mark_rtx (DECL_INCOMING_RTL (t));
405 case IDENTIFIER_NODE:
406 ggc_mark_string (IDENTIFIER_POINTER (t));
414 /* But in general we can handle them by class. */
415 switch (TREE_CODE_CLASS (TREE_CODE (t)))
417 case 'd': /* A decl node. */
418 ggc_mark_tree (DECL_SIZE (t));
419 ggc_mark_tree (DECL_NAME (t));
420 ggc_mark_tree (DECL_CONTEXT (t));
421 ggc_mark_tree (DECL_ARGUMENTS (t));
422 ggc_mark_tree (DECL_RESULT (t));
423 ggc_mark_tree (DECL_INITIAL (t));
424 ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
425 ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
426 ggc_mark_tree (DECL_SECTION_NAME (t));
427 ggc_mark_tree (DECL_MACHINE_ATTRIBUTES (t));
428 ggc_mark_rtx (DECL_RTL (t));
429 ggc_mark_tree (DECL_VINDEX (t));
433 case 't': /* A type node. */
434 ggc_mark_tree (TYPE_SIZE (t));
435 ggc_mark_tree (TYPE_SIZE_UNIT (t));
436 ggc_mark_tree (TYPE_ATTRIBUTES (t));
437 ggc_mark_tree (TYPE_VALUES (t));
438 ggc_mark_tree (TYPE_POINTER_TO (t));
439 ggc_mark_tree (TYPE_REFERENCE_TO (t));
440 ggc_mark_tree (TYPE_NAME (t));
441 ggc_mark_tree (TYPE_MIN_VALUE (t));
442 ggc_mark_tree (TYPE_MAX_VALUE (t));
443 ggc_mark_tree (TYPE_NEXT_VARIANT (t));
444 ggc_mark_tree (TYPE_MAIN_VARIANT (t));
445 ggc_mark_tree (TYPE_BINFO (t));
446 ggc_mark_tree (TYPE_NONCOPIED_PARTS (t));
447 ggc_mark_tree (TYPE_CONTEXT (t));
451 case 'b': /* A lexical block. */
452 ggc_mark_tree (BLOCK_VARS (t));
453 ggc_mark_tree (BLOCK_TYPE_TAGS (t));
454 ggc_mark_tree (BLOCK_SUBBLOCKS (t));
455 ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
456 ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
457 ggc_mark_rtx (BLOCK_END_NOTE (t));
460 case 'c': /* A constant. */
461 ggc_mark_rtx (TREE_CST_RTL (t));
464 case 'r': case '<': case '1':
465 case '2': case 'e': case 's': /* Expressions. */
467 int i = tree_code_length[TREE_CODE (t)];
469 ggc_mark_tree (TREE_OPERAND (t, i));
479 unsigned int *magic = (unsigned int *)s - 1;
484 if ((*magic & ~(unsigned)1) != GGC_STRING_MAGIC)
486 *magic = GGC_STRING_MAGIC | 1;
489 /* The top level mark-and-sweep routine. */
494 struct ggc_rtx *r, **rp;
495 struct ggc_rtvec *v, **vp;
496 struct ggc_tree *t, **tp;
497 struct ggc_string *s, **sp;
499 int time, n_rtxs, n_trees, n_vecs, n_strings;
501 #ifndef ENABLE_CHECKING
502 /* See if it's even worth our while. */
503 if (bytes_alloced_since_gc < 64*1024)
508 fputs (" {GC ", stderr);
510 time = get_run_time ();
512 /* Clean out all of the GC marks. */
513 for (r = rtxs; r != NULL; r = r->chain)
515 for (v = vecs; v != NULL; v = v->chain)
517 for (t = trees; t != NULL; t = t->chain)
518 t->tree.common.gc_mark = 0;
519 for (s = strings; s != NULL; s = s->chain)
520 s->magic_mark = GGC_STRING_MAGIC;
522 /* Mark through all the roots. */
523 for (x = roots; x != NULL; x = x->next)
526 int s = x->size, n = x->nelt;
527 void (*cb)(void *) = x->cb;
530 for (i = 0; i < n; ++i, elt += s)
534 /* Sweep the resulting dead nodes. */
535 rp = &rtxs, r = rtxs, n_rtxs = 0;
538 struct ggc_rtx *chain = r->chain;
550 n_rtxs_collected += n_rtxs;
552 vp = &vecs, v = vecs, n_vecs = 0;
555 struct ggc_rtvec *chain = v->chain;
567 n_vecs_collected += n_vecs;
569 tp = &trees, t = trees, n_trees = 0;
572 struct ggc_tree *chain = t->chain;
573 if (!t->tree.common.gc_mark)
584 n_trees_collected += n_trees;
586 sp = &strings, s = strings, n_strings = 0;
589 struct ggc_string *chain = s->chain;
590 if (!(s->magic_mark & 1))
601 n_strings_collected += n_strings;
603 gc_time += time = get_run_time () - time;
607 time = (time + 500) / 1000;
608 fprintf (stderr, "%d,%d,%d,%d %d.%03d}", n_rtxs, n_vecs, n_trees,
609 n_strings, time / 1000, time % 1000);
613 /* Manipulate global roots that are needed between calls to gc. */
616 ggc_add_root (base, nelt, size, cb)
619 void (*cb) PROTO ((void *));
621 struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof(*x));
633 ggc_add_rtx_root (base, nelt)
637 ggc_add_root (base, nelt, sizeof(rtx), ggc_mark_rtx_ptr);
641 ggc_add_tree_root (base, nelt)
645 ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr);
652 struct ggc_root *x, **p;
654 p = &roots, x = roots;
671 ggc_mark_rtx_ptr (elt)
674 ggc_mark_rtx (*(rtx *)elt);
678 ggc_mark_tree_ptr (elt)
681 ggc_mark_tree (*(tree *)elt);
685 /* Don't enable this unless you want a really really lot of data. */
686 static void __attribute__((constructor))
689 dump = fopen ("zgcdump", "w");
695 /* GDB really should have a memory search function. Since this is just
696 for initial debugging, I won't even pretend to get the __data_start
697 to work on any but alpha-dec-linux-gnu. */
699 search_data(void **start, void *target)
701 extern void *__data_start[];
702 void **_end = (void **)sbrk(0);
705 start = __data_start;
708 if (*start == target)