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