ggc-common.c revision 117395
1102050Stjr/* Simple garbage collection for the GNU compiler.
2128004Stjr   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3102050Stjr
4102050StjrThis file is part of GCC.
5102050Stjr
6102050StjrGCC is free software; you can redistribute it and/or modify it under
7102050Stjrthe terms of the GNU General Public License as published by the Free
8102050StjrSoftware Foundation; either version 2, or (at your option) any later
9102050Stjrversion.
10102050Stjr
11102050StjrGCC is distributed in the hope that it will be useful, but WITHOUT ANY
12102050StjrWARRANTY; without even the implied warranty of MERCHANTABILITY or
13102050StjrFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14102050Stjrfor more details.
15102050Stjr
16102050StjrYou should have received a copy of the GNU General Public License
17102050Stjralong with GCC; see the file COPYING.  If not, write to the Free
18102050StjrSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
19102050Stjr02111-1307, USA.  */
20102050Stjr
21102050Stjr/* Generic garbage collection (GC) functions and data, not specific to
22102050Stjr   any particular GC implementation.  */
23102050Stjr
24102050Stjr#include "config.h"
25102050Stjr#include "system.h"
26102050Stjr#include "rtl.h"
27102050Stjr#include "tree.h"
28102050Stjr#include "tm_p.h"
29102050Stjr#include "hashtab.h"
30102050Stjr#include "varray.h"
31129153Stjr#include "ggc.h"
32102050Stjr#include "langhooks.h"
33102050Stjr#include "params.h"
34128004Stjr#ifdef HAVE_SYS_RESOURCE_H
35102050Stjr# include <sys/resource.h>
36102050Stjr#endif
37128004Stjr#ifdef ENABLE_VALGRIND_CHECKING
38102050Stjr#include <valgrind.h>
39#else
40/* Avoid #ifdef:s when we can help it.  */
41#define VALGRIND_DISCARD(x)
42#endif
43
44/* Statistics about the allocation.  */
45static ggc_statistics *ggc_stats;
46
47static int ggc_htab_delete PARAMS ((void **, void *));
48static double ggc_rlimit_bound PARAMS ((double));
49
50/* Maintain global roots that are preserved during GC.  */
51
52/* Global roots that are preserved during calls to gc.  */
53
54struct ggc_root
55{
56  struct ggc_root *next;
57  void *base;
58  int nelt;
59  int size;
60  void (*cb) PARAMS ((void *));
61};
62
63static struct ggc_root *roots;
64
65/* Add BASE as a new garbage collection root.  It is an array of
66   length NELT with each element SIZE bytes long.  CB is a
67   function that will be called with a pointer to each element
68   of the array; it is the intention that CB call the appropriate
69   routine to mark gc-able memory for that element.  */
70
71void
72ggc_add_root (base, nelt, size, cb)
73     void *base;
74     int nelt, size;
75     void (*cb) PARAMS ((void *));
76{
77  struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof (*x));
78
79  x->next = roots;
80  x->base = base;
81  x->nelt = nelt;
82  x->size = size;
83  x->cb = cb;
84
85  roots = x;
86}
87
88/* Process a slot of an htab by deleting it if it has not been marked.  */
89
90static int
91ggc_htab_delete (slot, info)
92     void **slot;
93     void *info;
94{
95  const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
96
97  if (! (*r->marked_p) (*slot))
98    htab_clear_slot (*r->base, slot);
99  else
100    (*r->cb) (*slot);
101
102  return 1;
103}
104
105/* Iterate through all registered roots and mark each element.  */
106
107void
108ggc_mark_roots ()
109{
110  struct ggc_root *x;
111  const struct ggc_root_tab *const *rt;
112  const struct ggc_root_tab *rti;
113  const struct ggc_cache_tab *const *ct;
114  const struct ggc_cache_tab *cti;
115  size_t i;
116
117  for (rt = gt_ggc_deletable_rtab; *rt; rt++)
118    for (rti = *rt; rti->base != NULL; rti++)
119      memset (rti->base, 0, rti->stride);
120
121  for (rt = gt_ggc_rtab; *rt; rt++)
122    for (rti = *rt; rti->base != NULL; rti++)
123      for (i = 0; i < rti->nelt; i++)
124	(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
125
126  for (x = roots; x != NULL; x = x->next)
127    {
128      char *elt = x->base;
129      int s = x->size, n = x->nelt;
130      void (*cb) PARAMS ((void *)) = x->cb;
131      int i;
132
133      for (i = 0; i < n; ++i, elt += s)
134	(*cb)(elt);
135    }
136
137  /* Now scan all hash tables that have objects which are to be deleted if
138     they are not already marked.  */
139  for (ct = gt_ggc_cache_rtab; *ct; ct++)
140    for (cti = *ct; cti->base != NULL; cti++)
141      if (*cti->base)
142	htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
143}
144
145/* Allocate a block of memory, then clear it.  */
146void *
147ggc_alloc_cleared (size)
148     size_t size;
149{
150  void *buf = ggc_alloc (size);
151  memset (buf, 0, size);
152  return buf;
153}
154
155/* Resize a block of memory, possibly re-allocating it.  */
156void *
157ggc_realloc (x, size)
158     void *x;
159     size_t size;
160{
161  void *r;
162  size_t old_size;
163
164  if (x == NULL)
165    return ggc_alloc (size);
166
167  old_size = ggc_get_size (x);
168  if (size <= old_size)
169    {
170      /* Mark the unwanted memory as unaccessible.  We also need to make
171	 the "new" size accessible, since ggc_get_size returns the size of
172	 the pool, not the size of the individually allocated object, the
173	 size which was previously made accessible.  Unfortunately, we
174	 don't know that previously allocated size.  Without that
175	 knowledge we have to lose some initialization-tracking for the
176	 old parts of the object.  An alternative is to mark the whole
177	 old_size as reachable, but that would lose tracking of writes
178	 after the end of the object (by small offsets).  Discard the
179	 handle to avoid handle leak.  */
180      VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
181						old_size - size));
182      VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, size));
183      return x;
184    }
185
186  r = ggc_alloc (size);
187
188  /* Since ggc_get_size returns the size of the pool, not the size of the
189     individually allocated object, we'd access parts of the old object
190     that were marked invalid with the memcpy below.  We lose a bit of the
191     initialization-tracking since some of it may be uninitialized.  */
192  VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, old_size));
193
194  memcpy (r, x, old_size);
195
196  /* The old object is not supposed to be used anymore.  */
197  VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (x, old_size));
198
199  return r;
200}
201
202/* Like ggc_alloc_cleared, but performs a multiplication.  */
203void *
204ggc_calloc (s1, s2)
205     size_t s1, s2;
206{
207  return ggc_alloc_cleared (s1 * s2);
208}
209
210/* Print statistics that are independent of the collector in use.  */
211#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
212		  ? (x) \
213		  : ((x) < 1024*1024*10 \
214		     ? (x) / 1024 \
215		     : (x) / (1024*1024))))
216#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
217
218void
219ggc_print_common_statistics (stream, stats)
220     FILE *stream;
221     ggc_statistics *stats;
222{
223  int code;
224
225  /* Set the pointer so that during collection we will actually gather
226     the statistics.  */
227  ggc_stats = stats;
228
229  /* Then do one collection to fill in the statistics.  */
230  ggc_collect ();
231
232  /* Total the statistics.  */
233  for (code = 0; code < MAX_TREE_CODES; ++code)
234    {
235      stats->total_num_trees += stats->num_trees[code];
236      stats->total_size_trees += stats->size_trees[code];
237    }
238  for (code = 0; code < NUM_RTX_CODE; ++code)
239    {
240      stats->total_num_rtxs += stats->num_rtxs[code];
241      stats->total_size_rtxs += stats->size_rtxs[code];
242    }
243
244  /* Print the statistics for trees.  */
245  fprintf (stream, "\n%-17s%10s %16s %10s\n", "Tree",
246	   "Number", "Bytes", "% Total");
247  for (code = 0; code < MAX_TREE_CODES; ++code)
248    if (ggc_stats->num_trees[code])
249      {
250	fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
251		 tree_code_name[code],
252		 ggc_stats->num_trees[code],
253		 SCALE (ggc_stats->size_trees[code]),
254		 LABEL (ggc_stats->size_trees[code]),
255		 (100 * ((double) ggc_stats->size_trees[code])
256		  / ggc_stats->total_size_trees));
257      }
258  fprintf (stream,
259	   "%-17s%10u%16ld%c\n", "Total",
260	   ggc_stats->total_num_trees,
261	   SCALE (ggc_stats->total_size_trees),
262	   LABEL (ggc_stats->total_size_trees));
263
264  /* Print the statistics for RTL.  */
265  fprintf (stream, "\n%-17s%10s %16s %10s\n", "RTX",
266	   "Number", "Bytes", "% Total");
267  for (code = 0; code < NUM_RTX_CODE; ++code)
268    if (ggc_stats->num_rtxs[code])
269      {
270	fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
271		 rtx_name[code],
272		 ggc_stats->num_rtxs[code],
273		 SCALE (ggc_stats->size_rtxs[code]),
274		 LABEL (ggc_stats->size_rtxs[code]),
275		 (100 * ((double) ggc_stats->size_rtxs[code])
276		  / ggc_stats->total_size_rtxs));
277      }
278  fprintf (stream,
279	   "%-17s%10u%16ld%c\n", "Total",
280	   ggc_stats->total_num_rtxs,
281	   SCALE (ggc_stats->total_size_rtxs),
282	   LABEL (ggc_stats->total_size_rtxs));
283
284  /* Don't gather statistics any more.  */
285  ggc_stats = NULL;
286}
287
288/* Modify the bound based on rlimits.  Keep the smallest number found.  */
289static double
290ggc_rlimit_bound (limit)
291     double limit;
292{
293#if defined(HAVE_GETRLIMIT)
294  struct rlimit rlim;
295# ifdef RLIMIT_RSS
296  if (getrlimit (RLIMIT_RSS, &rlim) == 0
297      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
298      && rlim.rlim_cur < limit)
299    limit = rlim.rlim_cur;
300# endif
301# ifdef RLIMIT_DATA
302  if (getrlimit (RLIMIT_DATA, &rlim) == 0
303      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
304      && rlim.rlim_cur < limit)
305    limit = rlim.rlim_cur;
306# endif
307# ifdef RLIMIT_AS
308  if (getrlimit (RLIMIT_AS, &rlim) == 0
309      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
310      && rlim.rlim_cur < limit)
311    limit = rlim.rlim_cur;
312# endif
313#endif /* HAVE_GETRLIMIT */
314
315  return limit;
316}
317
318/* Heuristic to set a default for GGC_MIN_EXPAND.  */
319int
320ggc_min_expand_heuristic()
321{
322  double min_expand = physmem_total();
323
324  /* Adjust for rlimits.  */
325  min_expand = ggc_rlimit_bound (min_expand);
326
327  /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
328     a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB).  */
329  min_expand /= 1024*1024*1024;
330  min_expand *= 70;
331  min_expand = MIN (min_expand, 70);
332  min_expand += 30;
333
334  return min_expand;
335}
336
337/* Heuristic to set a default for GGC_MIN_HEAPSIZE.  */
338int
339ggc_min_heapsize_heuristic()
340{
341  double min_heap_kbytes = physmem_total();
342
343  /* Adjust for rlimits.  */
344  min_heap_kbytes = ggc_rlimit_bound (min_heap_kbytes);
345
346  min_heap_kbytes /= 1024; /* convert to Kbytes. */
347
348  /* The heuristic is RAM/8, with a lower bound of 4M and an upper
349     bound of 128M (when RAM >= 1GB).  */
350  min_heap_kbytes /= 8;
351  min_heap_kbytes = MAX (min_heap_kbytes, 4 * 1024);
352  min_heap_kbytes = MIN (min_heap_kbytes, 128 * 1024);
353
354  return min_heap_kbytes;
355}
356
357void
358init_ggc_heuristics ()
359{
360#ifndef ENABLE_GC_ALWAYS_COLLECT
361  set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
362  set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
363#endif
364}
365