ggc-common.c revision 117395
190075Sobrien/* Simple garbage collection for the GNU compiler.
290075Sobrien   Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
390075Sobrien
490075SobrienThis file is part of GCC.
590075Sobrien
690075SobrienGCC is free software; you can redistribute it and/or modify it under
790075Sobrienthe terms of the GNU General Public License as published by the Free
890075SobrienSoftware Foundation; either version 2, or (at your option) any later
990075Sobrienversion.
1090075Sobrien
1190075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1290075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1390075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1490075Sobrienfor more details.
1590075Sobrien
1690075SobrienYou should have received a copy of the GNU General Public License
1790075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1890075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
1990075Sobrien02111-1307, USA.  */
2090075Sobrien
2190075Sobrien/* Generic garbage collection (GC) functions and data, not specific to
2290075Sobrien   any particular GC implementation.  */
2390075Sobrien
2490075Sobrien#include "config.h"
2590075Sobrien#include "system.h"
2690075Sobrien#include "rtl.h"
2790075Sobrien#include "tree.h"
2890075Sobrien#include "tm_p.h"
2990075Sobrien#include "hashtab.h"
3090075Sobrien#include "varray.h"
3190075Sobrien#include "ggc.h"
32117395Skan#include "langhooks.h"
33117395Skan#include "params.h"
34117395Skan#ifdef HAVE_SYS_RESOURCE_H
35117395Skan# include <sys/resource.h>
36117395Skan#endif
37117395Skan#ifdef ENABLE_VALGRIND_CHECKING
38117395Skan#include <valgrind.h>
39117395Skan#else
40117395Skan/* Avoid #ifdef:s when we can help it.  */
41117395Skan#define VALGRIND_DISCARD(x)
42117395Skan#endif
4390075Sobrien
4490075Sobrien/* Statistics about the allocation.  */
4590075Sobrienstatic ggc_statistics *ggc_stats;
4690075Sobrien
4790075Sobrienstatic int ggc_htab_delete PARAMS ((void **, void *));
48117395Skanstatic double ggc_rlimit_bound PARAMS ((double));
4990075Sobrien
5090075Sobrien/* Maintain global roots that are preserved during GC.  */
5190075Sobrien
5290075Sobrien/* Global roots that are preserved during calls to gc.  */
5390075Sobrien
5490075Sobrienstruct ggc_root
5590075Sobrien{
5690075Sobrien  struct ggc_root *next;
5790075Sobrien  void *base;
5890075Sobrien  int nelt;
5990075Sobrien  int size;
6090075Sobrien  void (*cb) PARAMS ((void *));
6190075Sobrien};
6290075Sobrien
6390075Sobrienstatic struct ggc_root *roots;
6490075Sobrien
6590075Sobrien/* Add BASE as a new garbage collection root.  It is an array of
66117395Skan   length NELT with each element SIZE bytes long.  CB is a
6790075Sobrien   function that will be called with a pointer to each element
6890075Sobrien   of the array; it is the intention that CB call the appropriate
6990075Sobrien   routine to mark gc-able memory for that element.  */
7090075Sobrien
7190075Sobrienvoid
7290075Sobrienggc_add_root (base, nelt, size, cb)
7390075Sobrien     void *base;
7490075Sobrien     int nelt, size;
7590075Sobrien     void (*cb) PARAMS ((void *));
7690075Sobrien{
7790075Sobrien  struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof (*x));
7890075Sobrien
7990075Sobrien  x->next = roots;
8090075Sobrien  x->base = base;
8190075Sobrien  x->nelt = nelt;
8290075Sobrien  x->size = size;
8390075Sobrien  x->cb = cb;
8490075Sobrien
8590075Sobrien  roots = x;
8690075Sobrien}
8790075Sobrien
8890075Sobrien/* Process a slot of an htab by deleting it if it has not been marked.  */
8990075Sobrien
9090075Sobrienstatic int
9190075Sobrienggc_htab_delete (slot, info)
9290075Sobrien     void **slot;
9390075Sobrien     void *info;
9490075Sobrien{
95117395Skan  const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
9690075Sobrien
9790075Sobrien  if (! (*r->marked_p) (*slot))
98117395Skan    htab_clear_slot (*r->base, slot);
99117395Skan  else
100117395Skan    (*r->cb) (*slot);
10190075Sobrien
10290075Sobrien  return 1;
10390075Sobrien}
10490075Sobrien
10590075Sobrien/* Iterate through all registered roots and mark each element.  */
10690075Sobrien
10790075Sobrienvoid
10890075Sobrienggc_mark_roots ()
10990075Sobrien{
11090075Sobrien  struct ggc_root *x;
111117395Skan  const struct ggc_root_tab *const *rt;
112117395Skan  const struct ggc_root_tab *rti;
113117395Skan  const struct ggc_cache_tab *const *ct;
114117395Skan  const struct ggc_cache_tab *cti;
115117395Skan  size_t i;
11690075Sobrien
117117395Skan  for (rt = gt_ggc_deletable_rtab; *rt; rt++)
118117395Skan    for (rti = *rt; rti->base != NULL; rti++)
119117395Skan      memset (rti->base, 0, rti->stride);
120117395Skan
121117395Skan  for (rt = gt_ggc_rtab; *rt; rt++)
122117395Skan    for (rti = *rt; rti->base != NULL; rti++)
123117395Skan      for (i = 0; i < rti->nelt; i++)
124117395Skan	(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
125117395Skan
12690075Sobrien  for (x = roots; x != NULL; x = x->next)
12790075Sobrien    {
12890075Sobrien      char *elt = x->base;
12990075Sobrien      int s = x->size, n = x->nelt;
13090075Sobrien      void (*cb) PARAMS ((void *)) = x->cb;
13190075Sobrien      int i;
13290075Sobrien
13390075Sobrien      for (i = 0; i < n; ++i, elt += s)
13490075Sobrien	(*cb)(elt);
13590075Sobrien    }
13690075Sobrien
13790075Sobrien  /* Now scan all hash tables that have objects which are to be deleted if
138117395Skan     they are not already marked.  */
139117395Skan  for (ct = gt_ggc_cache_rtab; *ct; ct++)
140117395Skan    for (cti = *ct; cti->base != NULL; cti++)
141117395Skan      if (*cti->base)
142117395Skan	htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
14390075Sobrien}
14490075Sobrien
145117395Skan/* Allocate a block of memory, then clear it.  */
146117395Skanvoid *
147117395Skanggc_alloc_cleared (size)
148117395Skan     size_t size;
14990075Sobrien{
150117395Skan  void *buf = ggc_alloc (size);
151117395Skan  memset (buf, 0, size);
152117395Skan  return buf;
15396263Sobrien}
15496263Sobrien
155117395Skan/* Resize a block of memory, possibly re-allocating it.  */
156117395Skanvoid *
157117395Skanggc_realloc (x, size)
158117395Skan     void *x;
159117395Skan     size_t size;
16096263Sobrien{
161117395Skan  void *r;
162117395Skan  size_t old_size;
16390075Sobrien
164117395Skan  if (x == NULL)
165117395Skan    return ggc_alloc (size);
16690075Sobrien
167117395Skan  old_size = ggc_get_size (x);
168117395Skan  if (size <= old_size)
16990075Sobrien    {
170117395Skan      /* Mark the unwanted memory as unaccessible.  We also need to make
171117395Skan	 the "new" size accessible, since ggc_get_size returns the size of
172117395Skan	 the pool, not the size of the individually allocated object, the
173117395Skan	 size which was previously made accessible.  Unfortunately, we
174117395Skan	 don't know that previously allocated size.  Without that
175117395Skan	 knowledge we have to lose some initialization-tracking for the
176117395Skan	 old parts of the object.  An alternative is to mark the whole
177117395Skan	 old_size as reachable, but that would lose tracking of writes
178117395Skan	 after the end of the object (by small offsets).  Discard the
179117395Skan	 handle to avoid handle leak.  */
180117395Skan      VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
181117395Skan						old_size - size));
182117395Skan      VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, size));
183117395Skan      return x;
18490075Sobrien    }
18590075Sobrien
186117395Skan  r = ggc_alloc (size);
18790075Sobrien
188117395Skan  /* Since ggc_get_size returns the size of the pool, not the size of the
189117395Skan     individually allocated object, we'd access parts of the old object
190117395Skan     that were marked invalid with the memcpy below.  We lose a bit of the
191117395Skan     initialization-tracking since some of it may be uninitialized.  */
192117395Skan  VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, old_size));
19390075Sobrien
194117395Skan  memcpy (r, x, old_size);
19590075Sobrien
196117395Skan  /* The old object is not supposed to be used anymore.  */
197117395Skan  VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (x, old_size));
19890075Sobrien
199117395Skan  return r;
20090075Sobrien}
20190075Sobrien
202117395Skan/* Like ggc_alloc_cleared, but performs a multiplication.  */
20390075Sobrienvoid *
204117395Skanggc_calloc (s1, s2)
205117395Skan     size_t s1, s2;
20690075Sobrien{
207117395Skan  return ggc_alloc_cleared (s1 * s2);
20890075Sobrien}
20990075Sobrien
21090075Sobrien/* Print statistics that are independent of the collector in use.  */
21190075Sobrien#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
21290075Sobrien		  ? (x) \
21390075Sobrien		  : ((x) < 1024*1024*10 \
21490075Sobrien		     ? (x) / 1024 \
21590075Sobrien		     : (x) / (1024*1024))))
21690075Sobrien#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
21790075Sobrien
21890075Sobrienvoid
21990075Sobrienggc_print_common_statistics (stream, stats)
22090075Sobrien     FILE *stream;
22190075Sobrien     ggc_statistics *stats;
22290075Sobrien{
22390075Sobrien  int code;
22490075Sobrien
22590075Sobrien  /* Set the pointer so that during collection we will actually gather
22690075Sobrien     the statistics.  */
22790075Sobrien  ggc_stats = stats;
22890075Sobrien
22990075Sobrien  /* Then do one collection to fill in the statistics.  */
23090075Sobrien  ggc_collect ();
23190075Sobrien
23290075Sobrien  /* Total the statistics.  */
23390075Sobrien  for (code = 0; code < MAX_TREE_CODES; ++code)
23490075Sobrien    {
23590075Sobrien      stats->total_num_trees += stats->num_trees[code];
23690075Sobrien      stats->total_size_trees += stats->size_trees[code];
23790075Sobrien    }
23890075Sobrien  for (code = 0; code < NUM_RTX_CODE; ++code)
23990075Sobrien    {
24090075Sobrien      stats->total_num_rtxs += stats->num_rtxs[code];
24190075Sobrien      stats->total_size_rtxs += stats->size_rtxs[code];
24290075Sobrien    }
24390075Sobrien
24490075Sobrien  /* Print the statistics for trees.  */
245117395Skan  fprintf (stream, "\n%-17s%10s %16s %10s\n", "Tree",
24690075Sobrien	   "Number", "Bytes", "% Total");
24790075Sobrien  for (code = 0; code < MAX_TREE_CODES; ++code)
248117395Skan    if (ggc_stats->num_trees[code])
24990075Sobrien      {
25090075Sobrien	fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
25190075Sobrien		 tree_code_name[code],
25290075Sobrien		 ggc_stats->num_trees[code],
25390075Sobrien		 SCALE (ggc_stats->size_trees[code]),
25490075Sobrien		 LABEL (ggc_stats->size_trees[code]),
255117395Skan		 (100 * ((double) ggc_stats->size_trees[code])
25690075Sobrien		  / ggc_stats->total_size_trees));
25790075Sobrien      }
25890075Sobrien  fprintf (stream,
25990075Sobrien	   "%-17s%10u%16ld%c\n", "Total",
26090075Sobrien	   ggc_stats->total_num_trees,
26190075Sobrien	   SCALE (ggc_stats->total_size_trees),
26290075Sobrien	   LABEL (ggc_stats->total_size_trees));
26390075Sobrien
26490075Sobrien  /* Print the statistics for RTL.  */
265117395Skan  fprintf (stream, "\n%-17s%10s %16s %10s\n", "RTX",
26690075Sobrien	   "Number", "Bytes", "% Total");
26790075Sobrien  for (code = 0; code < NUM_RTX_CODE; ++code)
268117395Skan    if (ggc_stats->num_rtxs[code])
26990075Sobrien      {
27090075Sobrien	fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
27190075Sobrien		 rtx_name[code],
27290075Sobrien		 ggc_stats->num_rtxs[code],
27390075Sobrien		 SCALE (ggc_stats->size_rtxs[code]),
27490075Sobrien		 LABEL (ggc_stats->size_rtxs[code]),
275117395Skan		 (100 * ((double) ggc_stats->size_rtxs[code])
27690075Sobrien		  / ggc_stats->total_size_rtxs));
27790075Sobrien      }
27890075Sobrien  fprintf (stream,
27990075Sobrien	   "%-17s%10u%16ld%c\n", "Total",
28090075Sobrien	   ggc_stats->total_num_rtxs,
28190075Sobrien	   SCALE (ggc_stats->total_size_rtxs),
28290075Sobrien	   LABEL (ggc_stats->total_size_rtxs));
28390075Sobrien
28490075Sobrien  /* Don't gather statistics any more.  */
28590075Sobrien  ggc_stats = NULL;
28690075Sobrien}
287117395Skan
288117395Skan/* Modify the bound based on rlimits.  Keep the smallest number found.  */
289117395Skanstatic double
290117395Skanggc_rlimit_bound (limit)
291117395Skan     double limit;
292117395Skan{
293117395Skan#if defined(HAVE_GETRLIMIT)
294117395Skan  struct rlimit rlim;
295117395Skan# ifdef RLIMIT_RSS
296117395Skan  if (getrlimit (RLIMIT_RSS, &rlim) == 0
297117395Skan      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
298117395Skan      && rlim.rlim_cur < limit)
299117395Skan    limit = rlim.rlim_cur;
300117395Skan# endif
301117395Skan# ifdef RLIMIT_DATA
302117395Skan  if (getrlimit (RLIMIT_DATA, &rlim) == 0
303117395Skan      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
304117395Skan      && rlim.rlim_cur < limit)
305117395Skan    limit = rlim.rlim_cur;
306117395Skan# endif
307117395Skan# ifdef RLIMIT_AS
308117395Skan  if (getrlimit (RLIMIT_AS, &rlim) == 0
309117395Skan      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
310117395Skan      && rlim.rlim_cur < limit)
311117395Skan    limit = rlim.rlim_cur;
312117395Skan# endif
313117395Skan#endif /* HAVE_GETRLIMIT */
314117395Skan
315117395Skan  return limit;
316117395Skan}
317117395Skan
318117395Skan/* Heuristic to set a default for GGC_MIN_EXPAND.  */
319117395Skanint
320117395Skanggc_min_expand_heuristic()
321117395Skan{
322117395Skan  double min_expand = physmem_total();
323117395Skan
324117395Skan  /* Adjust for rlimits.  */
325117395Skan  min_expand = ggc_rlimit_bound (min_expand);
326117395Skan
327117395Skan  /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
328117395Skan     a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB).  */
329117395Skan  min_expand /= 1024*1024*1024;
330117395Skan  min_expand *= 70;
331117395Skan  min_expand = MIN (min_expand, 70);
332117395Skan  min_expand += 30;
333117395Skan
334117395Skan  return min_expand;
335117395Skan}
336117395Skan
337117395Skan/* Heuristic to set a default for GGC_MIN_HEAPSIZE.  */
338117395Skanint
339117395Skanggc_min_heapsize_heuristic()
340117395Skan{
341117395Skan  double min_heap_kbytes = physmem_total();
342117395Skan
343117395Skan  /* Adjust for rlimits.  */
344117395Skan  min_heap_kbytes = ggc_rlimit_bound (min_heap_kbytes);
345117395Skan
346117395Skan  min_heap_kbytes /= 1024; /* convert to Kbytes. */
347117395Skan
348117395Skan  /* The heuristic is RAM/8, with a lower bound of 4M and an upper
349117395Skan     bound of 128M (when RAM >= 1GB).  */
350117395Skan  min_heap_kbytes /= 8;
351117395Skan  min_heap_kbytes = MAX (min_heap_kbytes, 4 * 1024);
352117395Skan  min_heap_kbytes = MIN (min_heap_kbytes, 128 * 1024);
353117395Skan
354117395Skan  return min_heap_kbytes;
355117395Skan}
356117395Skan
357117395Skanvoid
358117395Skaninit_ggc_heuristics ()
359117395Skan{
360117395Skan#ifndef ENABLE_GC_ALWAYS_COLLECT
361117395Skan  set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
362117395Skan  set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
363117395Skan#endif
364117395Skan}
365