OSDN Git Service

* expr.c (highest_pow2_factor_for_type): Rename into
[pf3gnuchains/gcc-fork.git] / gcc / ggc-common.c
1 /* Simple garbage collection for the GNU compiler.
2    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 /* Generic garbage collection (GC) functions and data, not specific to
23    any particular GC implementation.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "hashtab.h"
29 #include "ggc.h"
30 #include "toplev.h"
31 #include "params.h"
32 #include "hosthooks.h"
33
34 #ifdef HAVE_SYS_RESOURCE_H
35 # include <sys/resource.h>
36 #endif
37
38 #ifdef HAVE_MMAP_FILE
39 # include <sys/mman.h>
40 # ifdef HAVE_MINCORE
41 /* This is on Solaris.  */
42 #  include <sys/types.h> 
43 # endif
44 #endif
45
46 #ifndef MAP_FAILED
47 # define MAP_FAILED ((void *)-1)
48 #endif
49
50 #ifdef ENABLE_VALGRIND_CHECKING
51 # ifdef HAVE_VALGRIND_MEMCHECK_H
52 #  include <valgrind/memcheck.h>
53 # elif defined HAVE_MEMCHECK_H
54 #  include <memcheck.h>
55 # else
56 #  include <valgrind.h>
57 # endif
58 #else
59 /* Avoid #ifdef:s when we can help it.  */
60 #define VALGRIND_DISCARD(x)
61 #endif
62
63 /* Statistics about the allocation.  */
64 static ggc_statistics *ggc_stats;
65
66 struct traversal_state;
67
68 static int ggc_htab_delete (void **, void *);
69 static hashval_t saving_htab_hash (const void *);
70 static int saving_htab_eq (const void *, const void *);
71 static int call_count (void **, void *);
72 static int call_alloc (void **, void *);
73 static int compare_ptr_data (const void *, const void *);
74 static void relocate_ptrs (void *, void *);
75 static void write_pch_globals (const struct ggc_root_tab * const *tab,
76                                struct traversal_state *state);
77 static double ggc_rlimit_bound (double);
78
79 /* Maintain global roots that are preserved during GC.  */
80
81 /* Process a slot of an htab by deleting it if it has not been marked.  */
82
83 static int
84 ggc_htab_delete (void **slot, void *info)
85 {
86   const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
87
88   if (! (*r->marked_p) (*slot))
89     htab_clear_slot (*r->base, slot);
90   else
91     (*r->cb) (*slot);
92
93   return 1;
94 }
95
96 /* Iterate through all registered roots and mark each element.  */
97
98 void
99 ggc_mark_roots (void)
100 {
101   const struct ggc_root_tab *const *rt;
102   const struct ggc_root_tab *rti;
103   const struct ggc_cache_tab *const *ct;
104   const struct ggc_cache_tab *cti;
105   size_t i;
106
107   for (rt = gt_ggc_deletable_rtab; *rt; rt++)
108     for (rti = *rt; rti->base != NULL; rti++)
109       memset (rti->base, 0, rti->stride);
110
111   for (rt = gt_ggc_rtab; *rt; rt++)
112     for (rti = *rt; rti->base != NULL; rti++)
113       for (i = 0; i < rti->nelt; i++)
114         (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
115
116   ggc_mark_stringpool ();
117
118   /* Now scan all hash tables that have objects which are to be deleted if
119      they are not already marked.  */
120   for (ct = gt_ggc_cache_rtab; *ct; ct++)
121     for (cti = *ct; cti->base != NULL; cti++)
122       if (*cti->base)
123         {
124           ggc_set_mark (*cti->base);
125           htab_traverse_noresize (*cti->base, ggc_htab_delete, (void *) cti);
126           ggc_set_mark ((*cti->base)->entries);
127         }
128 }
129
130 /* Allocate a block of memory, then clear it.  */
131 void *
132 ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL)
133 {
134   void *buf = ggc_alloc_stat (size PASS_MEM_STAT);
135   memset (buf, 0, size);
136   return buf;
137 }
138
139 /* Resize a block of memory, possibly re-allocating it.  */
140 void *
141 ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
142 {
143   void *r;
144   size_t old_size;
145
146   if (x == NULL)
147     return ggc_alloc_stat (size PASS_MEM_STAT);
148
149   old_size = ggc_get_size (x);
150
151   if (size <= old_size)
152     {
153       /* Mark the unwanted memory as unaccessible.  We also need to make
154          the "new" size accessible, since ggc_get_size returns the size of
155          the pool, not the size of the individually allocated object, the
156          size which was previously made accessible.  Unfortunately, we
157          don't know that previously allocated size.  Without that
158          knowledge we have to lose some initialization-tracking for the
159          old parts of the object.  An alternative is to mark the whole
160          old_size as reachable, but that would lose tracking of writes
161          after the end of the object (by small offsets).  Discard the
162          handle to avoid handle leak.  */
163       VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
164                                                 old_size - size));
165       VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, size));
166       return x;
167     }
168
169   r = ggc_alloc_stat (size PASS_MEM_STAT);
170
171   /* Since ggc_get_size returns the size of the pool, not the size of the
172      individually allocated object, we'd access parts of the old object
173      that were marked invalid with the memcpy below.  We lose a bit of the
174      initialization-tracking since some of it may be uninitialized.  */
175   VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, old_size));
176
177   memcpy (r, x, old_size);
178
179   /* The old object is not supposed to be used anymore.  */
180   ggc_free (x);
181
182   return r;
183 }
184
185 /* Like ggc_alloc_cleared, but performs a multiplication.  */
186 void *
187 ggc_calloc (size_t s1, size_t s2)
188 {
189   return ggc_alloc_cleared (s1 * s2);
190 }
191
192 /* These are for splay_tree_new_ggc.  */
193 void *
194 ggc_splay_alloc (int sz, void *nl)
195 {
196   if (nl != NULL)
197     abort ();
198   return ggc_alloc (sz);
199 }
200
201 void
202 ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl)
203 {
204   if (nl != NULL)
205     abort ();
206 }
207
208 /* Print statistics that are independent of the collector in use.  */
209 #define SCALE(x) ((unsigned long) ((x) < 1024*10 \
210                   ? (x) \
211                   : ((x) < 1024*1024*10 \
212                      ? (x) / 1024 \
213                      : (x) / (1024*1024))))
214 #define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
215
216 void
217 ggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED,
218                              ggc_statistics *stats)
219 {
220   /* Set the pointer so that during collection we will actually gather
221      the statistics.  */
222   ggc_stats = stats;
223
224   /* Then do one collection to fill in the statistics.  */
225   ggc_collect ();
226
227   /* At present, we don't really gather any interesting statistics.  */
228
229   /* Don't gather statistics any more.  */
230   ggc_stats = NULL;
231 }
232 \f
233 /* Functions for saving and restoring GCable memory to disk.  */
234
235 static htab_t saving_htab;
236
237 struct ptr_data
238 {
239   void *obj;
240   void *note_ptr_cookie;
241   gt_note_pointers note_ptr_fn;
242   gt_handle_reorder reorder_fn;
243   size_t size;
244   void *new_addr;
245 };
246
247 #define POINTER_HASH(x) (hashval_t)((long)x >> 3)
248
249 /* Register an object in the hash table.  */
250
251 int
252 gt_pch_note_object (void *obj, void *note_ptr_cookie,
253                     gt_note_pointers note_ptr_fn)
254 {
255   struct ptr_data **slot;
256
257   if (obj == NULL || obj == (void *) 1)
258     return 0;
259
260   slot = (struct ptr_data **)
261     htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
262                               INSERT);
263   if (*slot != NULL)
264     {
265       if ((*slot)->note_ptr_fn != note_ptr_fn
266           || (*slot)->note_ptr_cookie != note_ptr_cookie)
267         abort ();
268       return 0;
269     }
270
271   *slot = xcalloc (sizeof (struct ptr_data), 1);
272   (*slot)->obj = obj;
273   (*slot)->note_ptr_fn = note_ptr_fn;
274   (*slot)->note_ptr_cookie = note_ptr_cookie;
275   if (note_ptr_fn == gt_pch_p_S)
276     (*slot)->size = strlen (obj) + 1;
277   else
278     (*slot)->size = ggc_get_size (obj);
279   return 1;
280 }
281
282 /* Register an object in the hash table.  */
283
284 void
285 gt_pch_note_reorder (void *obj, void *note_ptr_cookie,
286                      gt_handle_reorder reorder_fn)
287 {
288   struct ptr_data *data;
289
290   if (obj == NULL || obj == (void *) 1)
291     return;
292
293   data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
294   if (data == NULL
295       || data->note_ptr_cookie != note_ptr_cookie)
296     abort ();
297
298   data->reorder_fn = reorder_fn;
299 }
300
301 /* Hash and equality functions for saving_htab, callbacks for htab_create.  */
302
303 static hashval_t
304 saving_htab_hash (const void *p)
305 {
306   return POINTER_HASH (((struct ptr_data *)p)->obj);
307 }
308
309 static int
310 saving_htab_eq (const void *p1, const void *p2)
311 {
312   return ((struct ptr_data *)p1)->obj == p2;
313 }
314
315 /* Handy state for the traversal functions.  */
316
317 struct traversal_state
318 {
319   FILE *f;
320   struct ggc_pch_data *d;
321   size_t count;
322   struct ptr_data **ptrs;
323   size_t ptrs_i;
324 };
325
326 /* Callbacks for htab_traverse.  */
327
328 static int
329 call_count (void **slot, void *state_p)
330 {
331   struct ptr_data *d = (struct ptr_data *)*slot;
332   struct traversal_state *state = (struct traversal_state *)state_p;
333
334   ggc_pch_count_object (state->d, d->obj, d->size, d->note_ptr_fn == gt_pch_p_S);
335   state->count++;
336   return 1;
337 }
338
339 static int
340 call_alloc (void **slot, void *state_p)
341 {
342   struct ptr_data *d = (struct ptr_data *)*slot;
343   struct traversal_state *state = (struct traversal_state *)state_p;
344
345   d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size, d->note_ptr_fn == gt_pch_p_S);
346   state->ptrs[state->ptrs_i++] = d;
347   return 1;
348 }
349
350 /* Callback for qsort.  */
351
352 static int
353 compare_ptr_data (const void *p1_p, const void *p2_p)
354 {
355   struct ptr_data *p1 = *(struct ptr_data *const *)p1_p;
356   struct ptr_data *p2 = *(struct ptr_data *const *)p2_p;
357   return (((size_t)p1->new_addr > (size_t)p2->new_addr)
358           - ((size_t)p1->new_addr < (size_t)p2->new_addr));
359 }
360
361 /* Callbacks for note_ptr_fn.  */
362
363 static void
364 relocate_ptrs (void *ptr_p, void *state_p)
365 {
366   void **ptr = (void **)ptr_p;
367   struct traversal_state *state ATTRIBUTE_UNUSED
368     = (struct traversal_state *)state_p;
369   struct ptr_data *result;
370
371   if (*ptr == NULL || *ptr == (void *)1)
372     return;
373
374   result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
375   if (result == NULL)
376     abort ();
377   *ptr = result->new_addr;
378 }
379
380 /* Write out, after relocation, the pointers in TAB.  */
381 static void
382 write_pch_globals (const struct ggc_root_tab * const *tab,
383                    struct traversal_state *state)
384 {
385   const struct ggc_root_tab *const *rt;
386   const struct ggc_root_tab *rti;
387   size_t i;
388
389   for (rt = tab; *rt; rt++)
390     for (rti = *rt; rti->base != NULL; rti++)
391       for (i = 0; i < rti->nelt; i++)
392         {
393           void *ptr = *(void **)((char *)rti->base + rti->stride * i);
394           struct ptr_data *new_ptr;
395           if (ptr == NULL || ptr == (void *)1)
396             {
397               if (fwrite (&ptr, sizeof (void *), 1, state->f)
398                   != 1)
399                 fatal_error ("can't write PCH file: %m");
400             }
401           else
402             {
403               new_ptr = htab_find_with_hash (saving_htab, ptr,
404                                              POINTER_HASH (ptr));
405               if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
406                   != 1)
407                 fatal_error ("can't write PCH file: %m");
408             }
409         }
410 }
411
412 /* Hold the information we need to mmap the file back in.  */
413
414 struct mmap_info
415 {
416   size_t offset;
417   size_t size;
418   void *preferred_base;
419 };
420
421 /* Write out the state of the compiler to F.  */
422
423 void
424 gt_pch_save (FILE *f)
425 {
426   const struct ggc_root_tab *const *rt;
427   const struct ggc_root_tab *rti;
428   size_t i;
429   struct traversal_state state;
430   char *this_object = NULL;
431   size_t this_object_size = 0;
432   struct mmap_info mmi;
433   size_t page_size = getpagesize();
434
435   gt_pch_save_stringpool ();
436
437   saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
438
439   for (rt = gt_ggc_rtab; *rt; rt++)
440     for (rti = *rt; rti->base != NULL; rti++)
441       for (i = 0; i < rti->nelt; i++)
442         (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
443
444   for (rt = gt_pch_cache_rtab; *rt; rt++)
445     for (rti = *rt; rti->base != NULL; rti++)
446       for (i = 0; i < rti->nelt; i++)
447         (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
448
449   /* Prepare the objects for writing, determine addresses and such.  */
450   state.f = f;
451   state.d = init_ggc_pch();
452   state.count = 0;
453   htab_traverse (saving_htab, call_count, &state);
454
455   mmi.size = ggc_pch_total_size (state.d);
456
457   /* Try to arrange things so that no relocation is necessary, but
458      don't try very hard.  On most platforms, this will always work,
459      and on the rest it's a lot of work to do better.  
460      (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and
461      HOST_HOOKS_GT_PCH_USE_ADDRESS.)  */
462   mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size);
463       
464 #if HAVE_MMAP_FILE
465   if (mmi.preferred_base == NULL)
466     {
467       mmi.preferred_base = mmap (NULL, mmi.size,
468                                  PROT_READ | PROT_WRITE, MAP_PRIVATE,
469                                  fileno (state.f), 0);
470       if (mmi.preferred_base == (void *) MAP_FAILED)
471         mmi.preferred_base = NULL;
472       else
473         munmap (mmi.preferred_base, mmi.size);
474     }
475 #endif /* HAVE_MMAP_FILE */
476
477   ggc_pch_this_base (state.d, mmi.preferred_base);
478
479   state.ptrs = xmalloc (state.count * sizeof (*state.ptrs));
480   state.ptrs_i = 0;
481   htab_traverse (saving_htab, call_alloc, &state);
482   qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
483
484   /* Write out all the scalar variables.  */
485   for (rt = gt_pch_scalar_rtab; *rt; rt++)
486     for (rti = *rt; rti->base != NULL; rti++)
487       if (fwrite (rti->base, rti->stride, 1, f) != 1)
488         fatal_error ("can't write PCH file: %m");
489
490   /* Write out all the global pointers, after translation.  */
491   write_pch_globals (gt_ggc_rtab, &state);
492   write_pch_globals (gt_pch_cache_rtab, &state);
493
494   ggc_pch_prepare_write (state.d, state.f);
495
496   /* Pad the PCH file so that the mmapped area starts on a page boundary.  */
497   {
498     long o;
499     o = ftell (state.f) + sizeof (mmi);
500     if (o == -1)
501       fatal_error ("can't get position in PCH file: %m");
502     mmi.offset = page_size - o % page_size;
503     if (mmi.offset == page_size)
504       mmi.offset = 0;
505     mmi.offset += o;
506   }
507   if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1)
508     fatal_error ("can't write PCH file: %m");
509   if (mmi.offset != 0
510       && fseek (state.f, mmi.offset, SEEK_SET) != 0)
511     fatal_error ("can't write padding to PCH file: %m");
512
513   /* Actually write out the objects.  */
514   for (i = 0; i < state.count; i++)
515     {
516       if (this_object_size < state.ptrs[i]->size)
517         {
518           this_object_size = state.ptrs[i]->size;
519           this_object = xrealloc (this_object, this_object_size);
520         }
521       memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
522       if (state.ptrs[i]->reorder_fn != NULL)
523         state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
524                                    state.ptrs[i]->note_ptr_cookie,
525                                    relocate_ptrs, &state);
526       state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj,
527                                   state.ptrs[i]->note_ptr_cookie,
528                                   relocate_ptrs, &state);
529       ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
530                             state.ptrs[i]->new_addr, state.ptrs[i]->size, state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
531       if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
532         memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
533     }
534   ggc_pch_finish (state.d, state.f);
535   gt_pch_fixup_stringpool ();
536
537   free (state.ptrs);
538   htab_delete (saving_htab);
539 }
540
541 /* Read the state of the compiler back in from F.  */
542
543 void
544 gt_pch_restore (FILE *f)
545 {
546   const struct ggc_root_tab *const *rt;
547   const struct ggc_root_tab *rti;
548   size_t i;
549   struct mmap_info mmi;
550   void *addr;
551   bool needs_read;
552
553   /* Delete any deletable objects.  This makes ggc_pch_read much
554      faster, as it can be sure that no GCable objects remain other
555      than the ones just read in.  */
556   for (rt = gt_ggc_deletable_rtab; *rt; rt++)
557     for (rti = *rt; rti->base != NULL; rti++)
558       memset (rti->base, 0, rti->stride);
559
560   /* Read in all the scalar variables.  */
561   for (rt = gt_pch_scalar_rtab; *rt; rt++)
562     for (rti = *rt; rti->base != NULL; rti++)
563       if (fread (rti->base, rti->stride, 1, f) != 1)
564         fatal_error ("can't read PCH file: %m");
565
566   /* Read in all the global pointers, in 6 easy loops.  */
567   for (rt = gt_ggc_rtab; *rt; rt++)
568     for (rti = *rt; rti->base != NULL; rti++)
569       for (i = 0; i < rti->nelt; i++)
570         if (fread ((char *)rti->base + rti->stride * i,
571                    sizeof (void *), 1, f) != 1)
572           fatal_error ("can't read PCH file: %m");
573
574   for (rt = gt_pch_cache_rtab; *rt; rt++)
575     for (rti = *rt; rti->base != NULL; rti++)
576       for (i = 0; i < rti->nelt; i++)
577         if (fread ((char *)rti->base + rti->stride * i,
578                    sizeof (void *), 1, f) != 1)
579           fatal_error ("can't read PCH file: %m");
580
581   if (fread (&mmi, sizeof (mmi), 1, f) != 1)
582     fatal_error ("can't read PCH file: %m");
583
584   if (host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size))
585     {
586 #if HAVE_MMAP_FILE
587       void *mmap_result;
588
589       mmap_result = mmap (mmi.preferred_base, mmi.size,
590                           PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
591                           fileno (f), mmi.offset);
592
593       /* The file might not be mmap-able.  */
594       needs_read = mmap_result == (void *) MAP_FAILED;
595
596       /* Sanity check for broken MAP_FIXED.  */
597       if (! needs_read && mmap_result != mmi.preferred_base)
598         abort ();
599 #else
600       needs_read = true;
601 #endif
602       addr = mmi.preferred_base;
603     }
604   else
605     {
606 #if HAVE_MMAP_FILE
607       addr = mmap (mmi.preferred_base, mmi.size,
608                    PROT_READ | PROT_WRITE, MAP_PRIVATE,
609                    fileno (f), mmi.offset);
610
611 #if HAVE_MINCORE
612       if (addr != mmi.preferred_base)
613         {
614           size_t page_size = getpagesize();
615           char one_byte;
616
617           /* We really want to be mapped at mmi.preferred_base
618              so we're going to resort to MAP_FIXED.  But before,
619              make sure that we can do so without destroying a
620              previously mapped area, by looping over all pages
621              that would be affected by the fixed mapping.  */
622           errno = 0;
623
624           for (i = 0; i < mmi.size; i+= page_size)
625             if (mincore ((char *)mmi.preferred_base + i, page_size, 
626                          (void *)&one_byte) == -1
627                 && errno == ENOMEM)
628               continue; /* The page is not mapped.  */
629             else
630               break;
631
632           if (i >= mmi.size)
633             {
634               if (addr != (void *) MAP_FAILED)
635                 munmap (addr, mmi.size);
636
637               addr = mmap (mmi.preferred_base, mmi.size, 
638                            PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
639                            fileno (f), mmi.offset);
640             }
641         }
642 #endif /* HAVE_MINCORE */
643
644       needs_read = addr == (void *) MAP_FAILED;
645
646 #else /* HAVE_MMAP_FILE */
647       needs_read = true;
648 #endif /* HAVE_MMAP_FILE */
649       if (needs_read)
650         addr = xmalloc (mmi.size);
651     }
652
653   if (needs_read)
654     {
655       if (fseek (f, mmi.offset, SEEK_SET) != 0
656           || fread (addr, mmi.size, 1, f) != 1)
657         fatal_error ("can't read PCH file: %m");
658     }
659   else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
660     fatal_error ("can't read PCH file: %m");
661
662   ggc_pch_read (f, addr);
663
664   if (addr != mmi.preferred_base)
665     {
666       for (rt = gt_ggc_rtab; *rt; rt++)
667         for (rti = *rt; rti->base != NULL; rti++)
668           for (i = 0; i < rti->nelt; i++)
669             {
670               char **ptr = (char **)((char *)rti->base + rti->stride * i);
671               if (*ptr != NULL)
672                 *ptr += (size_t)addr - (size_t)mmi.preferred_base;
673             }
674
675       for (rt = gt_pch_cache_rtab; *rt; rt++)
676         for (rti = *rt; rti->base != NULL; rti++)
677           for (i = 0; i < rti->nelt; i++)
678             {
679               char **ptr = (char **)((char *)rti->base + rti->stride * i);
680               if (*ptr != NULL)
681                 *ptr += (size_t)addr - (size_t)mmi.preferred_base;
682             }
683
684       fatal_error ("had to relocate PCH");
685     }
686
687   gt_pch_restore_stringpool ();
688 }
689
690 /* Modify the bound based on rlimits.  Keep the smallest number found.  */
691 static double
692 ggc_rlimit_bound (double limit)
693 {
694 #if defined(HAVE_GETRLIMIT)
695   struct rlimit rlim;
696 # ifdef RLIMIT_RSS
697   if (getrlimit (RLIMIT_RSS, &rlim) == 0
698       && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
699       && rlim.rlim_cur < limit)
700     limit = rlim.rlim_cur;
701 # endif
702 # ifdef RLIMIT_DATA
703   if (getrlimit (RLIMIT_DATA, &rlim) == 0
704       && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
705       && rlim.rlim_cur < limit)
706     limit = rlim.rlim_cur;
707 # endif
708 # ifdef RLIMIT_AS
709   if (getrlimit (RLIMIT_AS, &rlim) == 0
710       && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
711       && rlim.rlim_cur < limit)
712     limit = rlim.rlim_cur;
713 # endif
714 #endif /* HAVE_GETRLIMIT */
715
716   return limit;
717 }
718
719 /* Heuristic to set a default for GGC_MIN_EXPAND.  */
720 int
721 ggc_min_expand_heuristic (void)
722 {
723   double min_expand = physmem_total();
724
725   /* Adjust for rlimits.  */
726   min_expand = ggc_rlimit_bound (min_expand);
727
728   /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
729      a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB).  */
730   min_expand /= 1024*1024*1024;
731   min_expand *= 70;
732   min_expand = MIN (min_expand, 70);
733   min_expand += 30;
734
735   return min_expand;
736 }
737
738 /* Heuristic to set a default for GGC_MIN_HEAPSIZE.  */
739 int
740 ggc_min_heapsize_heuristic (void)
741 {
742   double min_heap_kbytes = physmem_total();
743
744   /* Adjust for rlimits.  */
745   min_heap_kbytes = ggc_rlimit_bound (min_heap_kbytes);
746
747   min_heap_kbytes /= 1024; /* Convert to Kbytes.  */
748
749   /* The heuristic is RAM/8, with a lower bound of 4M and an upper
750      bound of 128M (when RAM >= 1GB).  */
751   min_heap_kbytes /= 8;
752   min_heap_kbytes = MAX (min_heap_kbytes, 4 * 1024);
753   min_heap_kbytes = MIN (min_heap_kbytes, 128 * 1024);
754
755   return min_heap_kbytes;
756 }
757
758 void
759 init_ggc_heuristics (void)
760 {
761 #if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT
762   set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
763   set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
764 #endif
765 }
766
767 #ifdef GATHER_STATISTICS
768
769 /* Datastructure used to store per-call-site statistics.  */
770 struct loc_descriptor
771 {
772   const char *file;
773   int line;
774   const char *function;
775   int times;
776   size_t allocated;
777   size_t overhead;
778 };
779
780 /* Hashtable used for statistics.  */
781 static htab_t loc_hash;
782
783 /* Hash table helpers functions.  */
784 static hashval_t
785 hash_descriptor (const void *p)
786 {
787   const struct loc_descriptor *d = p;
788
789   return htab_hash_pointer (d->function) | d->line;
790 }
791
792 static int
793 eq_descriptor (const void *p1, const void *p2)
794 {
795   const struct loc_descriptor *d = p1;
796   const struct loc_descriptor *d2 = p2;
797
798   return (d->file == d2->file && d->line == d2->line
799           && d->function == d2->function);
800 }
801
802 /* Return descriptor for given call site, create new one if needed.  */
803 static struct loc_descriptor *
804 loc_descriptor (const char *name, int line, const char *function)
805 {
806   struct loc_descriptor loc;
807   struct loc_descriptor **slot;
808
809   loc.file = name;
810   loc.line = line;
811   loc.function = function;
812   if (!loc_hash)
813     loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
814
815   slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1);
816   if (*slot)
817     return *slot;
818   *slot = xcalloc (sizeof (**slot), 1);
819   (*slot)->file = name;
820   (*slot)->line = line;
821   (*slot)->function = function;
822   return *slot;
823 }
824
825 /* Record ALLOCATED and OVERHEAD bytes to descritor NAME:LINE (FUNCTION).  */
826 void ggc_record_overhead (size_t allocated, size_t overhead,
827                           const char *name, int line, const char *function)
828 {
829   struct loc_descriptor *loc = loc_descriptor (name, line, function);
830
831   loc->times++;
832   loc->allocated+=allocated;
833   loc->overhead+=overhead;
834 }
835
836 /* Helper for qsort; sort descriptors by amount of memory consumed.  */
837 static int
838 cmp_statistic (const void *loc1, const void *loc2)
839 {
840   struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
841   struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
842   return (l1->allocated + l1->overhead) - (l2->allocated + l2->overhead);
843 }
844
845 /* Collect array of the descriptors from hashtable.  */
846 struct loc_descriptor **loc_array;
847 static int
848 add_statistics (void **slot, void *b)
849 {
850   int *n = (int *)b;
851   loc_array[*n] = (struct loc_descriptor *) *slot;
852   (*n)++;
853   return 1;
854 }
855
856 /* Dump per-site memory statistics.  */
857 #endif
858 void dump_ggc_loc_statistics (void)
859 {
860 #ifdef GATHER_STATISTICS
861   int nentries = 0;
862   char s[4096];
863   size_t count, size, overhead;
864   int i;
865
866   loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements);
867   fprintf (stderr, "-------------------------------------------------------\n");
868   fprintf (stderr, "\n%-60s %10s %10s %10s\n",
869            "source location", "Times", "Allocated", "Overhead");
870   fprintf (stderr, "-------------------------------------------------------\n");
871   count = 0;
872   size = 0;
873   overhead = 0;
874   htab_traverse (loc_hash, add_statistics, &nentries);
875   qsort (loc_array, nentries, sizeof (*loc_array), cmp_statistic);
876   for (i = 0; i < nentries; i++)
877     {
878       struct loc_descriptor *d = loc_array[i];
879       size += d->allocated;
880       count += d->times;
881       overhead += d->overhead;
882     }
883   for (i = 0; i < nentries; i++)
884     {
885       struct loc_descriptor *d = loc_array[i];
886       if (d->allocated)
887         {
888           const char *s1 = d->file;
889           const char *s2;
890           while ((s2 = strstr (s1, "gcc/")))
891             s1 = s2 + 4;
892           sprintf (s, "%s:%i (%s)", s1, d->line, d->function);
893           fprintf (stderr, "%-60s %10i %10li %10li:%.3f%%\n", s,
894                    d->times, (long)d->allocated, (long)d->overhead,
895                    (d->allocated + d->overhead) *100.0 / (size + overhead));
896         }
897     }
898   fprintf (stderr, "%-60s %10ld %10ld %10ld\n",
899            "Total", (long)count, (long)size, (long)overhead);
900   fprintf (stderr, "-------------------------------------------------------\n");
901 #endif
902 }