OSDN Git Service

Commit parts that were missing in Mark's last commit
[pf3gnuchains/gcc-fork.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 (rtx);
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", &s->string);
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