* Makefile.am (nat_source_files): Remove
[official-gcc.git] / gcc / ggc-common.c
blob5b0e330ecfdb74832aad7392d782c6f288dbaaf2
1 /* Simple garbage collection for the GNU compiler.
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 /* Generic garbage collection (GC) functions and data, not specific to
22 any particular GC implementation. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "hashtab.h"
28 #include "ggc.h"
29 #include "toplev.h"
30 #include "params.h"
32 #ifdef HAVE_SYS_RESOURCE_H
33 # include <sys/resource.h>
34 #endif
36 #ifdef HAVE_MMAP_FILE
37 # include <sys/mman.h>
38 #endif
40 #ifdef ENABLE_VALGRIND_CHECKING
41 #include <valgrind.h>
42 #else
43 /* Avoid #ifdef:s when we can help it. */
44 #define VALGRIND_DISCARD(x)
45 #endif
47 /* Statistics about the allocation. */
48 static ggc_statistics *ggc_stats;
50 struct traversal_state;
52 static int ggc_htab_delete PARAMS ((void **, void *));
53 static hashval_t saving_htab_hash PARAMS ((const PTR));
54 static int saving_htab_eq PARAMS ((const PTR, const PTR));
55 static int call_count PARAMS ((void **, void *));
56 static int call_alloc PARAMS ((void **, void *));
57 static int compare_ptr_data PARAMS ((const void *, const void *));
58 static void relocate_ptrs PARAMS ((void *, void *));
59 static void write_pch_globals PARAMS ((const struct ggc_root_tab * const *tab,
60 struct traversal_state *state));
61 static double ggc_rlimit_bound PARAMS ((double));
63 /* Maintain global roots that are preserved during GC. */
65 /* Process a slot of an htab by deleting it if it has not been marked. */
67 static int
68 ggc_htab_delete (slot, info)
69 void **slot;
70 void *info;
72 const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
74 if (! (*r->marked_p) (*slot))
75 htab_clear_slot (*r->base, slot);
76 else
77 (*r->cb) (*slot);
79 return 1;
82 /* Iterate through all registered roots and mark each element. */
84 void
85 ggc_mark_roots ()
87 const struct ggc_root_tab *const *rt;
88 const struct ggc_root_tab *rti;
89 const struct ggc_cache_tab *const *ct;
90 const struct ggc_cache_tab *cti;
91 size_t i;
93 for (rt = gt_ggc_deletable_rtab; *rt; rt++)
94 for (rti = *rt; rti->base != NULL; rti++)
95 memset (rti->base, 0, rti->stride);
97 for (rt = gt_ggc_rtab; *rt; rt++)
98 for (rti = *rt; rti->base != NULL; rti++)
99 for (i = 0; i < rti->nelt; i++)
100 (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
102 ggc_mark_stringpool ();
104 /* Now scan all hash tables that have objects which are to be deleted if
105 they are not already marked. */
106 for (ct = gt_ggc_cache_rtab; *ct; ct++)
107 for (cti = *ct; cti->base != NULL; cti++)
108 if (*cti->base)
110 ggc_set_mark (*cti->base);
111 htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
112 ggc_set_mark ((*cti->base)->entries);
116 /* Allocate a block of memory, then clear it. */
117 void *
118 ggc_alloc_cleared (size)
119 size_t size;
121 void *buf = ggc_alloc (size);
122 memset (buf, 0, size);
123 return buf;
126 /* Resize a block of memory, possibly re-allocating it. */
127 void *
128 ggc_realloc (x, size)
129 void *x;
130 size_t size;
132 void *r;
133 size_t old_size;
135 if (x == NULL)
136 return ggc_alloc (size);
138 old_size = ggc_get_size (x);
139 if (size <= old_size)
141 /* Mark the unwanted memory as unaccessible. We also need to make
142 the "new" size accessible, since ggc_get_size returns the size of
143 the pool, not the size of the individually allocated object, the
144 size which was previously made accessible. Unfortunately, we
145 don't know that previously allocated size. Without that
146 knowledge we have to lose some initialization-tracking for the
147 old parts of the object. An alternative is to mark the whole
148 old_size as reachable, but that would lose tracking of writes
149 after the end of the object (by small offsets). Discard the
150 handle to avoid handle leak. */
151 VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
152 old_size - size));
153 VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, size));
154 return x;
157 r = ggc_alloc (size);
159 /* Since ggc_get_size returns the size of the pool, not the size of the
160 individually allocated object, we'd access parts of the old object
161 that were marked invalid with the memcpy below. We lose a bit of the
162 initialization-tracking since some of it may be uninitialized. */
163 VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, old_size));
165 memcpy (r, x, old_size);
167 /* The old object is not supposed to be used anymore. */
168 VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (x, old_size));
170 return r;
173 /* Like ggc_alloc_cleared, but performs a multiplication. */
174 void *
175 ggc_calloc (s1, s2)
176 size_t s1, s2;
178 return ggc_alloc_cleared (s1 * s2);
181 /* These are for splay_tree_new_ggc. */
182 PTR
183 ggc_splay_alloc (sz, nl)
184 int sz;
185 PTR nl;
187 if (nl != NULL)
188 abort ();
189 return ggc_alloc (sz);
192 void
193 ggc_splay_dont_free (x, nl)
194 PTR x ATTRIBUTE_UNUSED;
195 PTR nl;
197 if (nl != NULL)
198 abort ();
201 /* Print statistics that are independent of the collector in use. */
202 #define SCALE(x) ((unsigned long) ((x) < 1024*10 \
203 ? (x) \
204 : ((x) < 1024*1024*10 \
205 ? (x) / 1024 \
206 : (x) / (1024*1024))))
207 #define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
209 void
210 ggc_print_common_statistics (stream, stats)
211 FILE *stream ATTRIBUTE_UNUSED;
212 ggc_statistics *stats;
214 /* Set the pointer so that during collection we will actually gather
215 the statistics. */
216 ggc_stats = stats;
218 /* Then do one collection to fill in the statistics. */
219 ggc_collect ();
221 /* At present, we don't really gather any interesting statistics. */
223 /* Don't gather statistics any more. */
224 ggc_stats = NULL;
227 /* Functions for saving and restoring GCable memory to disk. */
229 static htab_t saving_htab;
231 struct ptr_data
233 void *obj;
234 void *note_ptr_cookie;
235 gt_note_pointers note_ptr_fn;
236 gt_handle_reorder reorder_fn;
237 size_t size;
238 void *new_addr;
241 #define POINTER_HASH(x) (hashval_t)((long)x >> 3)
243 /* Register an object in the hash table. */
246 gt_pch_note_object (obj, note_ptr_cookie, note_ptr_fn)
247 void *obj;
248 void *note_ptr_cookie;
249 gt_note_pointers note_ptr_fn;
251 struct ptr_data **slot;
253 if (obj == NULL || obj == (void *) 1)
254 return 0;
256 slot = (struct ptr_data **)
257 htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
258 INSERT);
259 if (*slot != NULL)
261 if ((*slot)->note_ptr_fn != note_ptr_fn
262 || (*slot)->note_ptr_cookie != note_ptr_cookie)
263 abort ();
264 return 0;
267 *slot = xcalloc (sizeof (struct ptr_data), 1);
268 (*slot)->obj = obj;
269 (*slot)->note_ptr_fn = note_ptr_fn;
270 (*slot)->note_ptr_cookie = note_ptr_cookie;
271 if (note_ptr_fn == gt_pch_p_S)
272 (*slot)->size = strlen (obj) + 1;
273 else
274 (*slot)->size = ggc_get_size (obj);
275 return 1;
278 /* Register an object in the hash table. */
280 void
281 gt_pch_note_reorder (obj, note_ptr_cookie, reorder_fn)
282 void *obj;
283 void *note_ptr_cookie;
284 gt_handle_reorder reorder_fn;
286 struct ptr_data *data;
288 if (obj == NULL || obj == (void *) 1)
289 return;
291 data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
292 if (data == NULL
293 || data->note_ptr_cookie != note_ptr_cookie)
294 abort ();
296 data->reorder_fn = reorder_fn;
299 /* Hash and equality functions for saving_htab, callbacks for htab_create. */
301 static hashval_t
302 saving_htab_hash (p)
303 const PTR p;
305 return POINTER_HASH (((struct ptr_data *)p)->obj);
308 static int
309 saving_htab_eq (p1, p2)
310 const PTR p1;
311 const PTR p2;
313 return ((struct ptr_data *)p1)->obj == p2;
316 /* Handy state for the traversal functions. */
318 struct traversal_state
320 FILE *f;
321 struct ggc_pch_data *d;
322 size_t count;
323 struct ptr_data **ptrs;
324 size_t ptrs_i;
327 /* Callbacks for htab_traverse. */
329 static int
330 call_count (slot, state_p)
331 void **slot;
332 void *state_p;
334 struct ptr_data *d = (struct ptr_data *)*slot;
335 struct traversal_state *state = (struct traversal_state *)state_p;
337 ggc_pch_count_object (state->d, d->obj, d->size);
338 state->count++;
339 return 1;
342 static int
343 call_alloc (slot, state_p)
344 void **slot;
345 void *state_p;
347 struct ptr_data *d = (struct ptr_data *)*slot;
348 struct traversal_state *state = (struct traversal_state *)state_p;
350 d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size);
351 state->ptrs[state->ptrs_i++] = d;
352 return 1;
355 /* Callback for qsort. */
357 static int
358 compare_ptr_data (p1_p, p2_p)
359 const void *p1_p;
360 const void *p2_p;
362 struct ptr_data *p1 = *(struct ptr_data *const *)p1_p;
363 struct ptr_data *p2 = *(struct ptr_data *const *)p2_p;
364 return (((size_t)p1->new_addr > (size_t)p2->new_addr)
365 - ((size_t)p1->new_addr < (size_t)p2->new_addr));
368 /* Callbacks for note_ptr_fn. */
370 static void
371 relocate_ptrs (ptr_p, state_p)
372 void *ptr_p;
373 void *state_p;
375 void **ptr = (void **)ptr_p;
376 struct traversal_state *state ATTRIBUTE_UNUSED
377 = (struct traversal_state *)state_p;
378 struct ptr_data *result;
380 if (*ptr == NULL || *ptr == (void *)1)
381 return;
383 result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
384 if (result == NULL)
385 abort ();
386 *ptr = result->new_addr;
389 /* Write out, after relocation, the pointers in TAB. */
390 static void
391 write_pch_globals (tab, state)
392 const struct ggc_root_tab * const *tab;
393 struct traversal_state *state;
395 const struct ggc_root_tab *const *rt;
396 const struct ggc_root_tab *rti;
397 size_t i;
399 for (rt = tab; *rt; rt++)
400 for (rti = *rt; rti->base != NULL; rti++)
401 for (i = 0; i < rti->nelt; i++)
403 void *ptr = *(void **)((char *)rti->base + rti->stride * i);
404 struct ptr_data *new_ptr;
405 if (ptr == NULL || ptr == (void *)1)
407 if (fwrite (&ptr, sizeof (void *), 1, state->f)
408 != 1)
409 fatal_io_error ("can't write PCH file");
411 else
413 new_ptr = htab_find_with_hash (saving_htab, ptr,
414 POINTER_HASH (ptr));
415 if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
416 != 1)
417 fatal_io_error ("can't write PCH file");
422 /* Hold the information we need to mmap the file back in. */
424 struct mmap_info
426 size_t offset;
427 size_t size;
428 void *preferred_base;
431 /* Write out the state of the compiler to F. */
433 void
434 gt_pch_save (f)
435 FILE *f;
437 const struct ggc_root_tab *const *rt;
438 const struct ggc_root_tab *rti;
439 size_t i;
440 struct traversal_state state;
441 char *this_object = NULL;
442 size_t this_object_size = 0;
443 struct mmap_info mmi;
444 size_t page_size = getpagesize();
446 gt_pch_save_stringpool ();
448 saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
450 for (rt = gt_ggc_rtab; *rt; rt++)
451 for (rti = *rt; rti->base != NULL; rti++)
452 for (i = 0; i < rti->nelt; i++)
453 (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
455 for (rt = gt_pch_cache_rtab; *rt; rt++)
456 for (rti = *rt; rti->base != NULL; rti++)
457 for (i = 0; i < rti->nelt; i++)
458 (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
460 /* Prepare the objects for writing, determine addresses and such. */
461 state.f = f;
462 state.d = init_ggc_pch();
463 state.count = 0;
464 htab_traverse (saving_htab, call_count, &state);
466 mmi.size = ggc_pch_total_size (state.d);
468 /* Try to arrange things so that no relocation is necessary,
469 but don't try very hard. On most platforms, this will always work,
470 and on the rest it's a lot of work to do better. */
471 #if HAVE_MMAP_FILE
472 mmi.preferred_base = mmap (NULL, mmi.size,
473 PROT_READ | PROT_WRITE, MAP_PRIVATE,
474 fileno (state.f), 0);
475 if (mmi.preferred_base == (void *)-1)
476 mmi.preferred_base = NULL;
477 else
478 munmap (mmi.preferred_base, mmi.size);
479 #else /* HAVE_MMAP_FILE */
480 mmi.preferred_base = NULL;
481 #endif /* HAVE_MMAP_FILE */
483 ggc_pch_this_base (state.d, mmi.preferred_base);
485 state.ptrs = xmalloc (state.count * sizeof (*state.ptrs));
486 state.ptrs_i = 0;
487 htab_traverse (saving_htab, call_alloc, &state);
488 qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
490 /* Write out all the scalar variables. */
491 for (rt = gt_pch_scalar_rtab; *rt; rt++)
492 for (rti = *rt; rti->base != NULL; rti++)
493 if (fwrite (rti->base, rti->stride, 1, f) != 1)
494 fatal_io_error ("can't write PCH file");
496 /* Write out all the global pointers, after translation. */
497 write_pch_globals (gt_ggc_rtab, &state);
498 write_pch_globals (gt_pch_cache_rtab, &state);
500 ggc_pch_prepare_write (state.d, state.f);
502 /* Pad the PCH file so that the mmaped area starts on a page boundary. */
504 long o;
505 o = ftell (state.f) + sizeof (mmi);
506 if (o == -1)
507 fatal_io_error ("can't get position in PCH file");
508 mmi.offset = page_size - o % page_size;
509 if (mmi.offset == page_size)
510 mmi.offset = 0;
511 mmi.offset += o;
513 if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1)
514 fatal_io_error ("can't write PCH file");
515 if (mmi.offset != 0
516 && fseek (state.f, mmi.offset, SEEK_SET) != 0)
517 fatal_io_error ("can't write padding to PCH file");
519 /* Actually write out the objects. */
520 for (i = 0; i < state.count; i++)
522 if (this_object_size < state.ptrs[i]->size)
524 this_object_size = state.ptrs[i]->size;
525 this_object = xrealloc (this_object, this_object_size);
527 memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
528 if (state.ptrs[i]->reorder_fn != NULL)
529 state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
530 state.ptrs[i]->note_ptr_cookie,
531 relocate_ptrs, &state);
532 state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj,
533 state.ptrs[i]->note_ptr_cookie,
534 relocate_ptrs, &state);
535 ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
536 state.ptrs[i]->new_addr, state.ptrs[i]->size);
537 if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
538 memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
540 ggc_pch_finish (state.d, state.f);
542 free (state.ptrs);
543 htab_delete (saving_htab);
546 /* Read the state of the compiler back in from F. */
548 void
549 gt_pch_restore (f)
550 FILE *f;
552 const struct ggc_root_tab *const *rt;
553 const struct ggc_root_tab *rti;
554 size_t i;
555 struct mmap_info mmi;
556 void *addr;
558 /* Delete any deletable objects. This makes ggc_pch_read much
559 faster, as it can be sure that no GCable objects remain other
560 than the ones just read in. */
561 for (rt = gt_ggc_deletable_rtab; *rt; rt++)
562 for (rti = *rt; rti->base != NULL; rti++)
563 memset (rti->base, 0, rti->stride);
565 /* Read in all the scalar variables. */
566 for (rt = gt_pch_scalar_rtab; *rt; rt++)
567 for (rti = *rt; rti->base != NULL; rti++)
568 if (fread (rti->base, rti->stride, 1, f) != 1)
569 fatal_io_error ("can't read PCH file");
571 /* Read in all the global pointers, in 6 easy loops. */
572 for (rt = gt_ggc_rtab; *rt; rt++)
573 for (rti = *rt; rti->base != NULL; rti++)
574 for (i = 0; i < rti->nelt; i++)
575 if (fread ((char *)rti->base + rti->stride * i,
576 sizeof (void *), 1, f) != 1)
577 fatal_io_error ("can't read PCH file");
579 for (rt = gt_pch_cache_rtab; *rt; rt++)
580 for (rti = *rt; rti->base != NULL; rti++)
581 for (i = 0; i < rti->nelt; i++)
582 if (fread ((char *)rti->base + rti->stride * i,
583 sizeof (void *), 1, f) != 1)
584 fatal_io_error ("can't read PCH file");
586 if (fread (&mmi, sizeof (mmi), 1, f) != 1)
587 fatal_io_error ("can't read PCH file");
589 #if HAVE_MMAP_FILE
590 addr = mmap (mmi.preferred_base, mmi.size,
591 PROT_READ | PROT_WRITE, MAP_PRIVATE,
592 fileno (f), mmi.offset);
593 #else
594 addr = (void *)-1;
595 #endif
596 if (addr == (void *)-1)
598 addr = xmalloc (mmi.size);
599 if (fseek (f, mmi.offset, SEEK_SET) != 0
600 || fread (&mmi, mmi.size, 1, f) != 1)
601 fatal_io_error ("can't read PCH file");
603 else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
604 fatal_io_error ("can't read PCH file");
606 ggc_pch_read (f, addr);
608 if (addr != mmi.preferred_base)
610 for (rt = gt_ggc_rtab; *rt; rt++)
611 for (rti = *rt; rti->base != NULL; rti++)
612 for (i = 0; i < rti->nelt; i++)
614 char **ptr = (char **)((char *)rti->base + rti->stride * i);
615 if (*ptr != NULL)
616 *ptr += (size_t)addr - (size_t)mmi.preferred_base;
619 for (rt = gt_pch_cache_rtab; *rt; rt++)
620 for (rti = *rt; rti->base != NULL; rti++)
621 for (i = 0; i < rti->nelt; i++)
623 char **ptr = (char **)((char *)rti->base + rti->stride * i);
624 if (*ptr != NULL)
625 *ptr += (size_t)addr - (size_t)mmi.preferred_base;
628 sorry ("had to relocate PCH");
631 gt_pch_restore_stringpool ();
634 /* Modify the bound based on rlimits. Keep the smallest number found. */
635 static double
636 ggc_rlimit_bound (limit)
637 double limit;
639 #if defined(HAVE_GETRLIMIT)
640 struct rlimit rlim;
641 # ifdef RLIMIT_RSS
642 if (getrlimit (RLIMIT_RSS, &rlim) == 0
643 && rlim.rlim_cur != RLIM_INFINITY
644 && rlim.rlim_cur < limit)
645 limit = rlim.rlim_cur;
646 # endif
647 # ifdef RLIMIT_DATA
648 if (getrlimit (RLIMIT_DATA, &rlim) == 0
649 && rlim.rlim_cur != RLIM_INFINITY
650 && rlim.rlim_cur < limit)
651 limit = rlim.rlim_cur;
652 # endif
653 # ifdef RLIMIT_AS
654 if (getrlimit (RLIMIT_AS, &rlim) == 0
655 && rlim.rlim_cur != RLIM_INFINITY
656 && rlim.rlim_cur < limit)
657 limit = rlim.rlim_cur;
658 # endif
659 #endif /* HAVE_GETRLIMIT */
661 return limit;
664 /* Heuristic to set a default for GGC_MIN_EXPAND. */
666 ggc_min_expand_heuristic()
668 double min_expand = physmem_total();
670 /* Adjust for rlimits. */
671 min_expand = ggc_rlimit_bound (min_expand);
673 /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
674 a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB). */
675 min_expand /= 1024*1024*1024;
676 min_expand *= 70;
677 min_expand = MIN (min_expand, 70);
678 min_expand += 30;
680 return min_expand;
683 /* Heuristic to set a default for GGC_MIN_HEAPSIZE. */
685 ggc_min_heapsize_heuristic()
687 double min_heap_kbytes = physmem_total();
689 /* Adjust for rlimits. */
690 min_heap_kbytes = ggc_rlimit_bound (min_heap_kbytes);
692 min_heap_kbytes /= 1024; /* convert to Kbytes. */
694 /* The heuristic is RAM/8, with a lower bound of 4M and an upper
695 bound of 128M (when RAM >= 1GB). */
696 min_heap_kbytes /= 8;
697 min_heap_kbytes = MAX (min_heap_kbytes, 4 * 1024);
698 min_heap_kbytes = MIN (min_heap_kbytes, 128 * 1024);
700 return min_heap_kbytes;
703 void
704 init_ggc_heuristics ()
706 #ifndef ENABLE_GC_ALWAYS_COLLECT
707 set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
708 set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
709 #endif