]> gcc.gnu.org Git - gcc.git/blob - gcc/ggc-simple.c
Makefile.in (ggc-simple.o): Depend on hash.h.
[gcc.git] / gcc / ggc-simple.c
1 /* Simple garbage collection for the GNU compiler.
2 Copyright (C) 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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)
9 any later version.
10
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.
15
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. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "rtl.h"
24 #include "tree.h"
25 #include "ggc.h"
26 #include "flags.h"
27 #include "varray.h"
28 #include "hash.h"
29
30 /* Debugging flags. */
31 #undef GGC_DUMP
32 #define GGC_POISON
33
34 /* Global lists of roots, rtxs, and trees. */
35
36 struct ggc_root
37 {
38 struct ggc_root *next;
39 void *base;
40 int nelt;
41 int size;
42 void (*cb) PROTO ((void *));
43 };
44
45 static struct ggc_root *roots;
46
47 struct ggc_rtx
48 {
49 struct ggc_rtx *chain;
50 struct rtx_def rtx;
51 };
52
53 static struct ggc_rtx *rtxs;
54
55 struct ggc_rtvec
56 {
57 struct ggc_rtvec *chain;
58 struct rtvec_def vec;
59 };
60
61 static struct ggc_rtvec *vecs;
62
63 struct ggc_tree
64 {
65 struct ggc_tree *chain;
66 union tree_node tree;
67 };
68
69 static struct ggc_tree *trees;
70
71 struct ggc_string
72 {
73 struct ggc_string *chain;
74 int magic_mark;
75 char string[1];
76 };
77
78 #define GGC_STRING_MAGIC ((unsigned int)0xa1b2c3d4)
79
80 static struct ggc_string *strings;
81
82 /* Some statistics. */
83
84 static int n_rtxs_collected;
85 static int n_vecs_collected;
86 static int n_trees_collected;
87 static int n_strings_collected;
88 static int bytes_alloced_since_gc;
89 extern int gc_time;
90
91 #ifdef GGC_DUMP
92 static FILE *dump;
93 #endif
94
95 /* Local function prototypes. */
96
97 static void ggc_free_rtx PROTO ((struct ggc_rtx *r));
98 static void ggc_free_tree PROTO ((struct ggc_tree *t));
99 static void ggc_mark_rtx_ptr PROTO ((void *elt));
100 static void ggc_mark_tree_ptr PROTO ((void *elt));
101 static void ggc_mark_tree_varray_ptr PROTO ((void *elt));
102 static void ggc_mark_tree_hash_table_ptr PROTO ((void *elt));
103 static boolean ggc_mark_tree_hash_table_entry PROTO ((struct hash_entry *,
104 hash_table_key));
105
106 /* These allocators are dreadfully simple, with no caching whatsoever so
107 that Purify-like tools that do allocation versioning can catch errors.
108 This collector is never going to go fast anyway. */
109
110 rtx
111 ggc_alloc_rtx (nslots)
112 int nslots;
113 {
114 struct ggc_rtx *n;
115 int size = sizeof(*n) + (nslots-1) * sizeof(rtunion);
116
117 n = (struct ggc_rtx *) xmalloc (size);
118 bzero ((char *) n, size);
119 n->chain = rtxs;
120 rtxs = n;
121
122 #ifdef GGC_DUMP
123 fprintf (dump, "alloc rtx %p\n", &n->rtx);
124 #endif
125
126 bytes_alloced_since_gc += size;
127
128 return &n->rtx;
129 }
130
131 rtvec
132 ggc_alloc_rtvec (nelt)
133 int nelt;
134 {
135 struct ggc_rtvec *v;
136 int size = sizeof (*v) + (nelt - 1) * sizeof (rtunion);
137
138 v = (struct ggc_rtvec *) xmalloc (size);
139 bzero ((char *) v, size);
140 v->chain = vecs;
141 vecs = v;
142
143 #ifdef GGC_DUMP
144 fprintf(dump, "alloc vec %p\n", &v->vec);
145 #endif
146
147 bytes_alloced_since_gc += size;
148
149 return &v->vec;
150 }
151
152 tree
153 ggc_alloc_tree (length)
154 int length;
155 {
156 struct ggc_tree *n;
157 int size = sizeof(*n) - sizeof(n->tree) + length;
158
159 n = (struct ggc_tree *) xmalloc (size);
160 bzero ((char *) n, size);
161 n->chain = trees;
162 trees = n;
163
164 #ifdef GGC_DUMP
165 fprintf(dump, "alloc tree %p\n", &n->tree);
166 #endif
167
168 bytes_alloced_since_gc += size;
169
170 return &n->tree;
171 }
172
173 char *
174 ggc_alloc_string (contents, length)
175 const char *contents;
176 int length;
177 {
178 struct ggc_string *s;
179 int size;
180
181 if (length < 0)
182 {
183 if (contents == NULL)
184 return NULL;
185 length = strlen (contents);
186 }
187
188 size = (s->string - (char *)s) + length + 1;
189 s = (struct ggc_string *) xmalloc(size);
190 s->chain = strings;
191 s->magic_mark = GGC_STRING_MAGIC;
192 if (contents)
193 bcopy (contents, s->string, length);
194 s->string[length] = 0;
195 strings = s;
196
197 #ifdef GGC_DUMP
198 fprintf(dump, "alloc string %p\n", &n->tree);
199 #endif
200
201 bytes_alloced_since_gc += size;
202
203 return s->string;
204 }
205
206
207 /* Freeing a bit of rtl isn't quite as simple as calling free, there are
208 a few associated bits that might need freeing as well. */
209
210 static void
211 ggc_free_rtx (r)
212 struct ggc_rtx *r;
213 {
214 #ifdef GGC_DUMP
215 fprintf (dump, "collect rtx %p\n", &r->rtx);
216 #endif
217 #ifdef GGC_POISON
218 memset (r, 0xAA, sizeof(*r));
219 #endif
220
221 free (r);
222 }
223
224 /* Freeing an rtvec is as simple as calling free. */
225
226 static void
227 ggc_free_rtvec (v)
228 struct ggc_rtvec *v;
229 {
230 #ifdef GGC_DUMP
231 fprintf(dump, "collect vec %p\n", &v->vec);
232 #endif
233 #ifdef GGC_POISON
234 memset (v, 0xBB, sizeof (*v) + ((GET_NUM_ELEM (&v->vec) - 1)
235 * sizeof (rtunion)));
236 #endif
237
238 free (v);
239 }
240
241 /* Freeing a tree node is almost, but not quite, as simple as calling free.
242 Mostly we need to let the language clean up its lang_specific bits. */
243
244 static void
245 ggc_free_tree (t)
246 struct ggc_tree *t;
247 {
248 switch (TREE_CODE_CLASS (TREE_CODE (&t->tree)))
249 {
250 case 'd': /* A decl node. */
251 case 't': /* A type node. */
252 lang_cleanup_tree (&t->tree);
253 break;
254 }
255
256 #ifdef GGC_DUMP
257 fprintf (dump, "collect tree %p\n", &t->tree);
258 #endif
259 #ifdef GGC_POISON
260 memset(&t->tree.common, 0xCC, sizeof(t->tree.common));
261 #endif
262
263 free (t);
264 }
265
266 /* Freeing a string is as simple as calling free. */
267
268 static void
269 ggc_free_string (s)
270 struct ggc_string *s;
271 {
272 #ifdef GGC_DUMP
273 fprintf(dump, "collect string %p\n", s->string);
274 #endif
275 #ifdef GGC_POISON
276 s->magic_mark = 0xDDDDDDDD;
277 s->string[0] = 0xDD;
278 #endif
279
280 free (s);
281 }
282
283 /* Mark a node. */
284
285 void
286 ggc_mark_rtx (r)
287 rtx r;
288 {
289 const char *fmt;
290 int i;
291
292 if (r == NULL_RTX || r->gc_mark)
293 return;
294 r->gc_mark = 1;
295
296 /* ??? If (some of) these are really pass-dependant info, do we have
297 any right poking our noses in? */
298 switch (GET_CODE (r))
299 {
300 case JUMP_INSN:
301 ggc_mark_rtx (JUMP_LABEL (r));
302 break;
303 case CODE_LABEL:
304 ggc_mark_rtx (LABEL_REFS (r));
305 break;
306 case LABEL_REF:
307 ggc_mark_rtx (LABEL_NEXTREF (r));
308 ggc_mark_rtx (CONTAINING_INSN (r));
309 break;
310 case ADDRESSOF:
311 ggc_mark_tree (ADDRESSOF_DECL (r));
312 break;
313 case CONST_DOUBLE:
314 ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
315 break;
316
317 default:
318 break;
319 }
320
321 for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
322 {
323 switch (*fmt)
324 {
325 case 'e': case 'u':
326 ggc_mark_rtx (XEXP (r, i));
327 break;
328 case 'V': case 'E':
329 ggc_mark_rtvec (XVEC (r, i));
330 break;
331 case 'S': case 's':
332 ggc_mark_string (XSTR (r, i));
333 break;
334 }
335 }
336 }
337
338 void
339 ggc_mark_rtvec (v)
340 rtvec v;
341 {
342 int i;
343
344 if (v == NULL || v->gc_mark)
345 return;
346 v->gc_mark = 1;
347
348 i = GET_NUM_ELEM (v);
349 while (--i >= 0)
350 ggc_mark_rtx (RTVEC_ELT (v, i));
351 }
352
353 void
354 ggc_mark_tree (t)
355 tree t;
356 {
357 if (t == NULL_TREE || t->common.gc_mark)
358 return;
359 t->common.gc_mark = 1;
360
361 /* Bits from common. */
362 ggc_mark_tree (TREE_TYPE (t));
363 ggc_mark_tree (TREE_CHAIN (t));
364
365 /* Some nodes require special handling. */
366 switch (TREE_CODE (t))
367 {
368 case TREE_LIST:
369 ggc_mark_tree (TREE_PURPOSE (t));
370 ggc_mark_tree (TREE_VALUE (t));
371 return;
372
373 case TREE_VEC:
374 {
375 int i = TREE_VEC_LENGTH (t);
376 while (--i >= 0)
377 ggc_mark_tree (TREE_VEC_ELT (t, i));
378 return;
379 }
380
381 case SAVE_EXPR:
382 ggc_mark_tree (TREE_OPERAND (t, 0));
383 ggc_mark_tree (SAVE_EXPR_CONTEXT (t));
384 ggc_mark_rtx (SAVE_EXPR_RTL (t));
385 return;
386
387 case RTL_EXPR:
388 ggc_mark_rtx (RTL_EXPR_SEQUENCE (t));
389 ggc_mark_rtx (RTL_EXPR_RTL (t));
390 return;
391
392 case CALL_EXPR:
393 ggc_mark_tree (TREE_OPERAND (t, 0));
394 ggc_mark_tree (TREE_OPERAND (t, 1));
395 ggc_mark_rtx (CALL_EXPR_RTL (t));
396 return;
397
398 case COMPLEX_CST:
399 ggc_mark_tree (TREE_REALPART (t));
400 ggc_mark_tree (TREE_IMAGPART (t));
401 break;
402
403 case STRING_CST:
404 ggc_mark_string (TREE_STRING_POINTER (t));
405 break;
406
407 case PARM_DECL:
408 ggc_mark_rtx (DECL_INCOMING_RTL (t));
409 break;
410
411 case IDENTIFIER_NODE:
412 ggc_mark_string (IDENTIFIER_POINTER (t));
413 lang_mark_tree (t);
414 return;
415
416 default:
417 break;
418 }
419
420 /* But in general we can handle them by class. */
421 switch (TREE_CODE_CLASS (TREE_CODE (t)))
422 {
423 case 'd': /* A decl node. */
424 ggc_mark_tree (DECL_SIZE (t));
425 ggc_mark_tree (DECL_NAME (t));
426 ggc_mark_tree (DECL_CONTEXT (t));
427 ggc_mark_tree (DECL_ARGUMENTS (t));
428 ggc_mark_tree (DECL_RESULT (t));
429 ggc_mark_tree (DECL_INITIAL (t));
430 ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
431 ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
432 ggc_mark_tree (DECL_SECTION_NAME (t));
433 ggc_mark_tree (DECL_MACHINE_ATTRIBUTES (t));
434 ggc_mark_rtx (DECL_RTL (t));
435 ggc_mark_tree (DECL_VINDEX (t));
436 lang_mark_tree (t);
437 break;
438
439 case 't': /* A type node. */
440 ggc_mark_tree (TYPE_SIZE (t));
441 ggc_mark_tree (TYPE_SIZE_UNIT (t));
442 ggc_mark_tree (TYPE_ATTRIBUTES (t));
443 ggc_mark_tree (TYPE_VALUES (t));
444 ggc_mark_tree (TYPE_POINTER_TO (t));
445 ggc_mark_tree (TYPE_REFERENCE_TO (t));
446 ggc_mark_tree (TYPE_NAME (t));
447 ggc_mark_tree (TYPE_MIN_VALUE (t));
448 ggc_mark_tree (TYPE_MAX_VALUE (t));
449 ggc_mark_tree (TYPE_NEXT_VARIANT (t));
450 ggc_mark_tree (TYPE_MAIN_VARIANT (t));
451 ggc_mark_tree (TYPE_BINFO (t));
452 ggc_mark_tree (TYPE_NONCOPIED_PARTS (t));
453 ggc_mark_tree (TYPE_CONTEXT (t));
454 lang_mark_tree (t);
455 break;
456
457 case 'b': /* A lexical block. */
458 ggc_mark_tree (BLOCK_VARS (t));
459 ggc_mark_tree (BLOCK_TYPE_TAGS (t));
460 ggc_mark_tree (BLOCK_SUBBLOCKS (t));
461 ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
462 ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
463 ggc_mark_rtx (BLOCK_END_NOTE (t));
464 break;
465
466 case 'c': /* A constant. */
467 ggc_mark_rtx (TREE_CST_RTL (t));
468 break;
469
470 case 'r': case '<': case '1':
471 case '2': case 'e': case 's': /* Expressions. */
472 {
473 int i = tree_code_length[TREE_CODE (t)];
474 while (--i >= 0)
475 ggc_mark_tree (TREE_OPERAND (t, i));
476 break;
477 }
478 }
479 }
480
481 /* Mark all the elements of the varray V, which contains trees. */
482
483 void
484 ggc_mark_tree_varray (v)
485 varray_type v;
486 {
487 int i;
488
489 for (i = v->num_elements - 1; i >= 0; --i)
490 ggc_mark_tree (VARRAY_TREE (v, i));
491 }
492
493 /* Mark the hash table-entry HE. It's key field is really a tree. */
494
495 static boolean
496 ggc_mark_tree_hash_table_entry (he, k)
497 struct hash_entry *he;
498 hash_table_key k ATTRIBUTE_UNUSED;
499 {
500 ggc_mark_tree ((tree) he->key);
501 return true;
502 }
503
504 /* Mark all the elements of the hash-table H, which contains trees. */
505
506 void
507 ggc_mark_tree_hash_table (ht)
508 struct hash_table *ht;
509 {
510 hash_traverse (ht, ggc_mark_tree_hash_table_entry, /*info=*/0);
511 }
512
513 void
514 ggc_mark_string (s)
515 char *s;
516 {
517 unsigned int *magic = (unsigned int *)s - 1;
518
519 if (s == NULL)
520 return;
521
522 if ((*magic & ~(unsigned)1) != GGC_STRING_MAGIC)
523 return; /* abort? */
524 *magic = GGC_STRING_MAGIC | 1;
525 }
526
527 /* The top level mark-and-sweep routine. */
528
529 void
530 ggc_collect ()
531 {
532 struct ggc_rtx *r, **rp;
533 struct ggc_rtvec *v, **vp;
534 struct ggc_tree *t, **tp;
535 struct ggc_string *s, **sp;
536 struct ggc_root *x;
537 int time, n_rtxs, n_trees, n_vecs, n_strings;
538
539 #ifndef ENABLE_CHECKING
540 /* See if it's even worth our while. */
541 if (bytes_alloced_since_gc < 64*1024)
542 return;
543 #endif
544
545 if (!quiet_flag)
546 fputs (" {GC ", stderr);
547
548 time = get_run_time ();
549
550 /* Clean out all of the GC marks. */
551 for (r = rtxs; r != NULL; r = r->chain)
552 r->rtx.gc_mark = 0;
553 for (v = vecs; v != NULL; v = v->chain)
554 v->vec.gc_mark = 0;
555 for (t = trees; t != NULL; t = t->chain)
556 t->tree.common.gc_mark = 0;
557 for (s = strings; s != NULL; s = s->chain)
558 s->magic_mark = GGC_STRING_MAGIC;
559
560 /* Mark through all the roots. */
561 for (x = roots; x != NULL; x = x->next)
562 {
563 char *elt = x->base;
564 int s = x->size, n = x->nelt;
565 void (*cb) PROTO ((void *)) = x->cb;
566 int i;
567
568 for (i = 0; i < n; ++i, elt += s)
569 (*cb)(elt);
570 }
571
572 /* Sweep the resulting dead nodes. */
573 rp = &rtxs, r = rtxs, n_rtxs = 0;
574 while (r != NULL)
575 {
576 struct ggc_rtx *chain = r->chain;
577 if (!r->rtx.gc_mark)
578 {
579 ggc_free_rtx (r);
580 *rp = chain;
581 n_rtxs++;
582 }
583 else
584 rp = &r->chain;
585 r = chain;
586 }
587 *rp = NULL;
588 n_rtxs_collected += n_rtxs;
589
590 vp = &vecs, v = vecs, n_vecs = 0;
591 while (v != NULL)
592 {
593 struct ggc_rtvec *chain = v->chain;
594 if (!v->vec.gc_mark)
595 {
596 ggc_free_rtvec (v);
597 *vp = chain;
598 n_vecs++;
599 }
600 else
601 vp = &v->chain;
602 v = chain;
603 }
604 *vp = NULL;
605 n_vecs_collected += n_vecs;
606
607 tp = &trees, t = trees, n_trees = 0;
608 while (t != NULL)
609 {
610 struct ggc_tree *chain = t->chain;
611 if (!t->tree.common.gc_mark)
612 {
613 ggc_free_tree (t);
614 *tp = chain;
615 n_trees++;
616 }
617 else
618 tp = &t->chain;
619 t = chain;
620 }
621 *tp = NULL;
622 n_trees_collected += n_trees;
623
624 sp = &strings, s = strings, n_strings = 0;
625 while (s != NULL)
626 {
627 struct ggc_string *chain = s->chain;
628 if (!(s->magic_mark & 1))
629 {
630 ggc_free_string (s);
631 *sp = chain;
632 n_strings++;
633 }
634 else
635 sp = &s->chain;
636 s = chain;
637 }
638 *sp = NULL;
639 n_strings_collected += n_strings;
640
641 gc_time += time = get_run_time () - time;
642
643 if (!quiet_flag)
644 {
645 time = (time + 500) / 1000;
646 fprintf (stderr, "%d,%d,%d,%d %d.%03d}", n_rtxs, n_vecs, n_trees,
647 n_strings, time / 1000, time % 1000);
648 }
649 }
650
651 /* Manipulate global roots that are needed between calls to gc. */
652
653 void
654 ggc_add_root (base, nelt, size, cb)
655 void *base;
656 int nelt, size;
657 void (*cb) PROTO ((void *));
658 {
659 struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof(*x));
660
661 x->next = roots;
662 x->base = base;
663 x->nelt = nelt;
664 x->size = size;
665 x->cb = cb;
666
667 roots = x;
668 }
669
670 void
671 ggc_add_rtx_root (base, nelt)
672 rtx *base;
673 int nelt;
674 {
675 ggc_add_root (base, nelt, sizeof(rtx), ggc_mark_rtx_ptr);
676 }
677
678 void
679 ggc_add_tree_root (base, nelt)
680 tree *base;
681 int nelt;
682 {
683 ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr);
684 }
685
686 /* Add V (a varray full of trees) to the list of GC roots. */
687
688 void
689 ggc_add_tree_varray_root (base, nelt)
690 varray_type *base;
691 int nelt;
692 {
693 ggc_add_root (base, nelt, sizeof (varray_type),
694 ggc_mark_tree_varray_ptr);
695 }
696
697 /* Add HT (a hash-table where ever key is a tree) to the list of GC
698 roots. */
699
700 void
701 ggc_add_tree_hash_table_root (base, nelt)
702 struct hash_table **base;
703 int nelt;
704 {
705 ggc_add_root (base, nelt, sizeof (struct hash_table *),
706 ggc_mark_tree_hash_table_ptr);
707 }
708
709 void
710 ggc_del_root (base)
711 void *base;
712 {
713 struct ggc_root *x, **p;
714
715 p = &roots, x = roots;
716 while (x)
717 {
718 if (x->base == base)
719 {
720 *p = x->next;
721 free (x);
722 return;
723 }
724 p = &x->next;
725 x = x->next;
726 }
727
728 abort();
729 }
730
731 static void
732 ggc_mark_rtx_ptr (elt)
733 void *elt;
734 {
735 ggc_mark_rtx (*(rtx *)elt);
736 }
737
738 static void
739 ggc_mark_tree_ptr (elt)
740 void *elt;
741 {
742 ggc_mark_tree (*(tree *)elt);
743 }
744
745 /* Type-correct function to pass to ggc_add_root. It just forwards
746 ELT (which is really a varray_type *) to ggc_mark_tree_varray. */
747
748 static void
749 ggc_mark_tree_varray_ptr (elt)
750 void *elt;
751 {
752 ggc_mark_tree_varray (*(varray_type *)elt);
753 }
754
755 /* Type-correct function to pass to ggc_add_root. It just forwards
756 ELT (which is really a struct hash_table **) to
757 ggc_mark_tree_hash_table. */
758
759 static void
760 ggc_mark_tree_hash_table_ptr (elt)
761 void *elt;
762 {
763 ggc_mark_tree_hash_table (*(struct hash_table **) elt);
764 }
765
766 #ifdef GGC_DUMP
767 /* Don't enable this unless you want a really really lot of data. */
768 static void __attribute__((constructor))
769 init(void)
770 {
771 dump = fopen ("zgcdump", "w");
772 setlinebuf (dump);
773 }
774 #endif
775
776 #if 0
777 /* GDB really should have a memory search function. Since this is just
778 for initial debugging, I won't even pretend to get the __data_start
779 to work on any but alpha-dec-linux-gnu. */
780 static void **
781 search_data(void **start, void *target)
782 {
783 extern void *__data_start[];
784 void **_end = (void **)sbrk(0);
785
786 if (start == NULL)
787 start = __data_start;
788 while (start < _end)
789 {
790 if (*start == target)
791 return start;
792 start++;
793 }
794 return NULL;
795 }
796 #endif
This page took 0.079217 seconds and 6 git commands to generate.