190075Sobrien/* Simple garbage collection for the GNU compiler.
2169689Skan   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3132718Skan   Free Software Foundation, Inc.
490075Sobrien
590075SobrienThis file is part of GCC.
690075Sobrien
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1190075Sobrien
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1690075Sobrien
1790075SobrienYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2190075Sobrien
2290075Sobrien/* Generic garbage collection (GC) functions and data, not specific to
2390075Sobrien   any particular GC implementation.  */
2490075Sobrien
2590075Sobrien#include "config.h"
2690075Sobrien#include "system.h"
27132718Skan#include "coretypes.h"
2890075Sobrien#include "hashtab.h"
2990075Sobrien#include "ggc.h"
30132718Skan#include "toplev.h"
31117395Skan#include "params.h"
32132718Skan#include "hosthooks.h"
33161651Skan#include "hosthooks-def.h"
34132718Skan
35117395Skan#ifdef HAVE_SYS_RESOURCE_H
36117395Skan# include <sys/resource.h>
37117395Skan#endif
38132718Skan
39132718Skan#ifdef HAVE_MMAP_FILE
40132718Skan# include <sys/mman.h>
41132718Skan# ifdef HAVE_MINCORE
42132718Skan/* This is on Solaris.  */
43132718Skan#  include <sys/types.h>
44132718Skan# endif
45132718Skan#endif
46132718Skan
47132718Skan#ifndef MAP_FAILED
48132718Skan# define MAP_FAILED ((void *)-1)
49132718Skan#endif
50132718Skan
51117395Skan#ifdef ENABLE_VALGRIND_CHECKING
52132718Skan# ifdef HAVE_VALGRIND_MEMCHECK_H
53132718Skan#  include <valgrind/memcheck.h>
54132718Skan# elif defined HAVE_MEMCHECK_H
55132718Skan#  include <memcheck.h>
56132718Skan# else
57132718Skan#  include <valgrind.h>
58132718Skan# endif
59117395Skan#else
60117395Skan/* Avoid #ifdef:s when we can help it.  */
61117395Skan#define VALGRIND_DISCARD(x)
62117395Skan#endif
6390075Sobrien
64169689Skan/* When set, ggc_collect will do collection.  */
65169689Skanbool ggc_force_collect;
66169689Skan
6790075Sobrien/* Statistics about the allocation.  */
6890075Sobrienstatic ggc_statistics *ggc_stats;
6990075Sobrien
70132718Skanstruct traversal_state;
7190075Sobrien
72132718Skanstatic int ggc_htab_delete (void **, void *);
73132718Skanstatic hashval_t saving_htab_hash (const void *);
74132718Skanstatic int saving_htab_eq (const void *, const void *);
75132718Skanstatic int call_count (void **, void *);
76132718Skanstatic int call_alloc (void **, void *);
77132718Skanstatic int compare_ptr_data (const void *, const void *);
78132718Skanstatic void relocate_ptrs (void *, void *);
79132718Skanstatic void write_pch_globals (const struct ggc_root_tab * const *tab,
80132718Skan			       struct traversal_state *state);
81132718Skanstatic double ggc_rlimit_bound (double);
82132718Skan
8390075Sobrien/* Maintain global roots that are preserved during GC.  */
8490075Sobrien
8590075Sobrien/* Process a slot of an htab by deleting it if it has not been marked.  */
8690075Sobrien
8790075Sobrienstatic int
88132718Skanggc_htab_delete (void **slot, void *info)
8990075Sobrien{
90117395Skan  const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
9190075Sobrien
9290075Sobrien  if (! (*r->marked_p) (*slot))
93117395Skan    htab_clear_slot (*r->base, slot);
94117395Skan  else
95117395Skan    (*r->cb) (*slot);
9690075Sobrien
9790075Sobrien  return 1;
9890075Sobrien}
9990075Sobrien
10090075Sobrien/* Iterate through all registered roots and mark each element.  */
10190075Sobrien
10290075Sobrienvoid
103132718Skanggc_mark_roots (void)
10490075Sobrien{
105117395Skan  const struct ggc_root_tab *const *rt;
106117395Skan  const struct ggc_root_tab *rti;
107117395Skan  const struct ggc_cache_tab *const *ct;
108117395Skan  const struct ggc_cache_tab *cti;
109117395Skan  size_t i;
11090075Sobrien
111117395Skan  for (rt = gt_ggc_deletable_rtab; *rt; rt++)
112117395Skan    for (rti = *rt; rti->base != NULL; rti++)
113117395Skan      memset (rti->base, 0, rti->stride);
114117395Skan
115117395Skan  for (rt = gt_ggc_rtab; *rt; rt++)
116117395Skan    for (rti = *rt; rti->base != NULL; rti++)
117117395Skan      for (i = 0; i < rti->nelt; i++)
118117395Skan	(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
119117395Skan
120132718Skan  ggc_mark_stringpool ();
12190075Sobrien
12290075Sobrien  /* Now scan all hash tables that have objects which are to be deleted if
123117395Skan     they are not already marked.  */
124117395Skan  for (ct = gt_ggc_cache_rtab; *ct; ct++)
125117395Skan    for (cti = *ct; cti->base != NULL; cti++)
126117395Skan      if (*cti->base)
127132718Skan	{
128132718Skan	  ggc_set_mark (*cti->base);
129132718Skan	  htab_traverse_noresize (*cti->base, ggc_htab_delete, (void *) cti);
130132718Skan	  ggc_set_mark ((*cti->base)->entries);
131132718Skan	}
13290075Sobrien}
13390075Sobrien
134117395Skan/* Allocate a block of memory, then clear it.  */
135117395Skanvoid *
136169689Skanggc_alloc_cleared_stat (size_t size MEM_STAT_DECL)
13790075Sobrien{
138169689Skan  void *buf = ggc_alloc_stat (size PASS_MEM_STAT);
139117395Skan  memset (buf, 0, size);
140117395Skan  return buf;
14196263Sobrien}
14296263Sobrien
143117395Skan/* Resize a block of memory, possibly re-allocating it.  */
144117395Skanvoid *
145169689Skanggc_realloc_stat (void *x, size_t size MEM_STAT_DECL)
14696263Sobrien{
147117395Skan  void *r;
148117395Skan  size_t old_size;
14990075Sobrien
150117395Skan  if (x == NULL)
151169689Skan    return ggc_alloc_stat (size PASS_MEM_STAT);
15290075Sobrien
153117395Skan  old_size = ggc_get_size (x);
154169689Skan
155117395Skan  if (size <= old_size)
15690075Sobrien    {
157117395Skan      /* Mark the unwanted memory as unaccessible.  We also need to make
158117395Skan	 the "new" size accessible, since ggc_get_size returns the size of
159117395Skan	 the pool, not the size of the individually allocated object, the
160117395Skan	 size which was previously made accessible.  Unfortunately, we
161117395Skan	 don't know that previously allocated size.  Without that
162117395Skan	 knowledge we have to lose some initialization-tracking for the
163117395Skan	 old parts of the object.  An alternative is to mark the whole
164132718Skan	 old_size as reachable, but that would lose tracking of writes
165117395Skan	 after the end of the object (by small offsets).  Discard the
166117395Skan	 handle to avoid handle leak.  */
167117395Skan      VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
168117395Skan						old_size - size));
169117395Skan      VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, size));
170117395Skan      return x;
17190075Sobrien    }
17290075Sobrien
173169689Skan  r = ggc_alloc_stat (size PASS_MEM_STAT);
17490075Sobrien
175117395Skan  /* Since ggc_get_size returns the size of the pool, not the size of the
176117395Skan     individually allocated object, we'd access parts of the old object
177117395Skan     that were marked invalid with the memcpy below.  We lose a bit of the
178117395Skan     initialization-tracking since some of it may be uninitialized.  */
179117395Skan  VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (x, old_size));
18090075Sobrien
181117395Skan  memcpy (r, x, old_size);
18290075Sobrien
183117395Skan  /* The old object is not supposed to be used anymore.  */
184169689Skan  ggc_free (x);
18590075Sobrien
186117395Skan  return r;
18790075Sobrien}
18890075Sobrien
189117395Skan/* Like ggc_alloc_cleared, but performs a multiplication.  */
19090075Sobrienvoid *
191132718Skanggc_calloc (size_t s1, size_t s2)
19290075Sobrien{
193117395Skan  return ggc_alloc_cleared (s1 * s2);
19490075Sobrien}
19590075Sobrien
196132718Skan/* These are for splay_tree_new_ggc.  */
197132718Skanvoid *
198132718Skanggc_splay_alloc (int sz, void *nl)
199132718Skan{
200169689Skan  gcc_assert (!nl);
201132718Skan  return ggc_alloc (sz);
202132718Skan}
203132718Skan
204132718Skanvoid
205132718Skanggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl)
206132718Skan{
207169689Skan  gcc_assert (!nl);
208132718Skan}
209132718Skan
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
219132718Skanggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED,
220132718Skan			     ggc_statistics *stats)
22190075Sobrien{
22290075Sobrien  /* Set the pointer so that during collection we will actually gather
22390075Sobrien     the statistics.  */
22490075Sobrien  ggc_stats = stats;
22590075Sobrien
22690075Sobrien  /* Then do one collection to fill in the statistics.  */
22790075Sobrien  ggc_collect ();
22890075Sobrien
229132718Skan  /* At present, we don't really gather any interesting statistics.  */
230132718Skan
231132718Skan  /* Don't gather statistics any more.  */
232132718Skan  ggc_stats = NULL;
233132718Skan}
234132718Skan
235132718Skan/* Functions for saving and restoring GCable memory to disk.  */
236132718Skan
237132718Skanstatic htab_t saving_htab;
238132718Skan
239132718Skanstruct ptr_data
240132718Skan{
241132718Skan  void *obj;
242132718Skan  void *note_ptr_cookie;
243132718Skan  gt_note_pointers note_ptr_fn;
244132718Skan  gt_handle_reorder reorder_fn;
245132718Skan  size_t size;
246132718Skan  void *new_addr;
247169689Skan  enum gt_types_enum type;
248132718Skan};
249132718Skan
250132718Skan#define POINTER_HASH(x) (hashval_t)((long)x >> 3)
251132718Skan
252132718Skan/* Register an object in the hash table.  */
253132718Skan
254132718Skanint
255132718Skangt_pch_note_object (void *obj, void *note_ptr_cookie,
256169689Skan		    gt_note_pointers note_ptr_fn,
257169689Skan		    enum gt_types_enum type)
258132718Skan{
259132718Skan  struct ptr_data **slot;
260132718Skan
261132718Skan  if (obj == NULL || obj == (void *) 1)
262132718Skan    return 0;
263132718Skan
264132718Skan  slot = (struct ptr_data **)
265132718Skan    htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
266132718Skan			      INSERT);
267132718Skan  if (*slot != NULL)
26890075Sobrien    {
269169689Skan      gcc_assert ((*slot)->note_ptr_fn == note_ptr_fn
270169689Skan		  && (*slot)->note_ptr_cookie == note_ptr_cookie);
271132718Skan      return 0;
27290075Sobrien    }
273132718Skan
274132718Skan  *slot = xcalloc (sizeof (struct ptr_data), 1);
275132718Skan  (*slot)->obj = obj;
276132718Skan  (*slot)->note_ptr_fn = note_ptr_fn;
277132718Skan  (*slot)->note_ptr_cookie = note_ptr_cookie;
278132718Skan  if (note_ptr_fn == gt_pch_p_S)
279132718Skan    (*slot)->size = strlen (obj) + 1;
280132718Skan  else
281132718Skan    (*slot)->size = ggc_get_size (obj);
282169689Skan  (*slot)->type = type;
283132718Skan  return 1;
284132718Skan}
285132718Skan
286132718Skan/* Register an object in the hash table.  */
287132718Skan
288132718Skanvoid
289132718Skangt_pch_note_reorder (void *obj, void *note_ptr_cookie,
290132718Skan		     gt_handle_reorder reorder_fn)
291132718Skan{
292132718Skan  struct ptr_data *data;
293132718Skan
294132718Skan  if (obj == NULL || obj == (void *) 1)
295132718Skan    return;
296132718Skan
297132718Skan  data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
298169689Skan  gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie);
299132718Skan
300132718Skan  data->reorder_fn = reorder_fn;
301132718Skan}
302132718Skan
303132718Skan/* Hash and equality functions for saving_htab, callbacks for htab_create.  */
304132718Skan
305132718Skanstatic hashval_t
306132718Skansaving_htab_hash (const void *p)
307132718Skan{
308132718Skan  return POINTER_HASH (((struct ptr_data *)p)->obj);
309132718Skan}
310132718Skan
311132718Skanstatic int
312132718Skansaving_htab_eq (const void *p1, const void *p2)
313132718Skan{
314132718Skan  return ((struct ptr_data *)p1)->obj == p2;
315132718Skan}
316132718Skan
317132718Skan/* Handy state for the traversal functions.  */
318132718Skan
319132718Skanstruct traversal_state
320132718Skan{
321132718Skan  FILE *f;
322132718Skan  struct ggc_pch_data *d;
323132718Skan  size_t count;
324132718Skan  struct ptr_data **ptrs;
325132718Skan  size_t ptrs_i;
326132718Skan};
327132718Skan
328132718Skan/* Callbacks for htab_traverse.  */
329132718Skan
330132718Skanstatic int
331132718Skancall_count (void **slot, void *state_p)
332132718Skan{
333132718Skan  struct ptr_data *d = (struct ptr_data *)*slot;
334132718Skan  struct traversal_state *state = (struct traversal_state *)state_p;
335132718Skan
336169689Skan  ggc_pch_count_object (state->d, d->obj, d->size,
337169689Skan			d->note_ptr_fn == gt_pch_p_S,
338169689Skan			d->type);
339132718Skan  state->count++;
340132718Skan  return 1;
341132718Skan}
342132718Skan
343132718Skanstatic int
344132718Skancall_alloc (void **slot, void *state_p)
345132718Skan{
346132718Skan  struct ptr_data *d = (struct ptr_data *)*slot;
347132718Skan  struct traversal_state *state = (struct traversal_state *)state_p;
348132718Skan
349169689Skan  d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size,
350169689Skan				      d->note_ptr_fn == gt_pch_p_S,
351169689Skan				      d->type);
352132718Skan  state->ptrs[state->ptrs_i++] = d;
353132718Skan  return 1;
354132718Skan}
355132718Skan
356132718Skan/* Callback for qsort.  */
357132718Skan
358132718Skanstatic int
359132718Skancompare_ptr_data (const void *p1_p, const void *p2_p)
360132718Skan{
361132718Skan  struct ptr_data *p1 = *(struct ptr_data *const *)p1_p;
362132718Skan  struct ptr_data *p2 = *(struct ptr_data *const *)p2_p;
363132718Skan  return (((size_t)p1->new_addr > (size_t)p2->new_addr)
364132718Skan	  - ((size_t)p1->new_addr < (size_t)p2->new_addr));
365132718Skan}
366132718Skan
367132718Skan/* Callbacks for note_ptr_fn.  */
368132718Skan
369132718Skanstatic void
370132718Skanrelocate_ptrs (void *ptr_p, void *state_p)
371132718Skan{
372132718Skan  void **ptr = (void **)ptr_p;
373132718Skan  struct traversal_state *state ATTRIBUTE_UNUSED
374132718Skan    = (struct traversal_state *)state_p;
375132718Skan  struct ptr_data *result;
376132718Skan
377132718Skan  if (*ptr == NULL || *ptr == (void *)1)
378132718Skan    return;
379132718Skan
380132718Skan  result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
381169689Skan  gcc_assert (result);
382132718Skan  *ptr = result->new_addr;
383132718Skan}
384132718Skan
385132718Skan/* Write out, after relocation, the pointers in TAB.  */
386132718Skanstatic void
387132718Skanwrite_pch_globals (const struct ggc_root_tab * const *tab,
388132718Skan		   struct traversal_state *state)
389132718Skan{
390132718Skan  const struct ggc_root_tab *const *rt;
391132718Skan  const struct ggc_root_tab *rti;
392132718Skan  size_t i;
393132718Skan
394132718Skan  for (rt = tab; *rt; rt++)
395132718Skan    for (rti = *rt; rti->base != NULL; rti++)
396132718Skan      for (i = 0; i < rti->nelt; i++)
397132718Skan	{
398132718Skan	  void *ptr = *(void **)((char *)rti->base + rti->stride * i);
399132718Skan	  struct ptr_data *new_ptr;
400132718Skan	  if (ptr == NULL || ptr == (void *)1)
401132718Skan	    {
402132718Skan	      if (fwrite (&ptr, sizeof (void *), 1, state->f)
403132718Skan		  != 1)
404132718Skan		fatal_error ("can't write PCH file: %m");
405132718Skan	    }
406132718Skan	  else
407132718Skan	    {
408132718Skan	      new_ptr = htab_find_with_hash (saving_htab, ptr,
409132718Skan					     POINTER_HASH (ptr));
410132718Skan	      if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
411132718Skan		  != 1)
412132718Skan		fatal_error ("can't write PCH file: %m");
413132718Skan	    }
414132718Skan	}
415132718Skan}
416132718Skan
417132718Skan/* Hold the information we need to mmap the file back in.  */
418132718Skan
419132718Skanstruct mmap_info
420132718Skan{
421132718Skan  size_t offset;
422132718Skan  size_t size;
423132718Skan  void *preferred_base;
424132718Skan};
425132718Skan
426132718Skan/* Write out the state of the compiler to F.  */
427132718Skan
428132718Skanvoid
429132718Skangt_pch_save (FILE *f)
430132718Skan{
431132718Skan  const struct ggc_root_tab *const *rt;
432132718Skan  const struct ggc_root_tab *rti;
433132718Skan  size_t i;
434132718Skan  struct traversal_state state;
435132718Skan  char *this_object = NULL;
436132718Skan  size_t this_object_size = 0;
437132718Skan  struct mmap_info mmi;
438169689Skan  const size_t mmap_offset_alignment = host_hooks.gt_pch_alloc_granularity();
439132718Skan
440132718Skan  gt_pch_save_stringpool ();
441132718Skan
442132718Skan  saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
443132718Skan
444132718Skan  for (rt = gt_ggc_rtab; *rt; rt++)
445132718Skan    for (rti = *rt; rti->base != NULL; rti++)
446132718Skan      for (i = 0; i < rti->nelt; i++)
447132718Skan	(*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
448132718Skan
449132718Skan  for (rt = gt_pch_cache_rtab; *rt; rt++)
450132718Skan    for (rti = *rt; rti->base != NULL; rti++)
451132718Skan      for (i = 0; i < rti->nelt; i++)
452132718Skan	(*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
453132718Skan
454132718Skan  /* Prepare the objects for writing, determine addresses and such.  */
455132718Skan  state.f = f;
456132718Skan  state.d = init_ggc_pch();
457132718Skan  state.count = 0;
458132718Skan  htab_traverse (saving_htab, call_count, &state);
459132718Skan
460132718Skan  mmi.size = ggc_pch_total_size (state.d);
461132718Skan
462132718Skan  /* Try to arrange things so that no relocation is necessary, but
463132718Skan     don't try very hard.  On most platforms, this will always work,
464132718Skan     and on the rest it's a lot of work to do better.
465132718Skan     (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and
466132718Skan     HOST_HOOKS_GT_PCH_USE_ADDRESS.)  */
467161651Skan  mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f));
468132718Skan
469132718Skan  ggc_pch_this_base (state.d, mmi.preferred_base);
47090075Sobrien
471169689Skan  state.ptrs = XNEWVEC (struct ptr_data *, state.count);
472132718Skan  state.ptrs_i = 0;
473132718Skan  htab_traverse (saving_htab, call_alloc, &state);
474132718Skan  qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
47590075Sobrien
476132718Skan  /* Write out all the scalar variables.  */
477132718Skan  for (rt = gt_pch_scalar_rtab; *rt; rt++)
478132718Skan    for (rti = *rt; rti->base != NULL; rti++)
479132718Skan      if (fwrite (rti->base, rti->stride, 1, f) != 1)
480132718Skan	fatal_error ("can't write PCH file: %m");
481132718Skan
482132718Skan  /* Write out all the global pointers, after translation.  */
483132718Skan  write_pch_globals (gt_ggc_rtab, &state);
484132718Skan  write_pch_globals (gt_pch_cache_rtab, &state);
485132718Skan
486169689Skan  /* Pad the PCH file so that the mmapped area starts on an allocation
487169689Skan     granularity (usually page) boundary.  */
488132718Skan  {
489132718Skan    long o;
490132718Skan    o = ftell (state.f) + sizeof (mmi);
491132718Skan    if (o == -1)
492132718Skan      fatal_error ("can't get position in PCH file: %m");
493169689Skan    mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment;
494169689Skan    if (mmi.offset == mmap_offset_alignment)
495132718Skan      mmi.offset = 0;
496132718Skan    mmi.offset += o;
497132718Skan  }
498132718Skan  if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1)
499132718Skan    fatal_error ("can't write PCH file: %m");
500132718Skan  if (mmi.offset != 0
501132718Skan      && fseek (state.f, mmi.offset, SEEK_SET) != 0)
502132718Skan    fatal_error ("can't write padding to PCH file: %m");
503132718Skan
504169689Skan  ggc_pch_prepare_write (state.d, state.f);
505169689Skan
506132718Skan  /* Actually write out the objects.  */
507132718Skan  for (i = 0; i < state.count; i++)
508132718Skan    {
509132718Skan      if (this_object_size < state.ptrs[i]->size)
510132718Skan	{
511132718Skan	  this_object_size = state.ptrs[i]->size;
512132718Skan	  this_object = xrealloc (this_object, this_object_size);
513132718Skan	}
514132718Skan      memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
515132718Skan      if (state.ptrs[i]->reorder_fn != NULL)
516132718Skan	state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
517132718Skan				   state.ptrs[i]->note_ptr_cookie,
518132718Skan				   relocate_ptrs, &state);
519132718Skan      state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj,
520132718Skan				  state.ptrs[i]->note_ptr_cookie,
521132718Skan				  relocate_ptrs, &state);
522132718Skan      ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
523161651Skan			    state.ptrs[i]->new_addr, state.ptrs[i]->size,
524161651Skan			    state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
525132718Skan      if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
526132718Skan	memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
527132718Skan    }
528132718Skan  ggc_pch_finish (state.d, state.f);
529132718Skan  gt_pch_fixup_stringpool ();
530132718Skan
531132718Skan  free (state.ptrs);
532132718Skan  htab_delete (saving_htab);
53390075Sobrien}
534117395Skan
535132718Skan/* Read the state of the compiler back in from F.  */
536132718Skan
537132718Skanvoid
538132718Skangt_pch_restore (FILE *f)
539132718Skan{
540132718Skan  const struct ggc_root_tab *const *rt;
541132718Skan  const struct ggc_root_tab *rti;
542132718Skan  size_t i;
543132718Skan  struct mmap_info mmi;
544161651Skan  int result;
545132718Skan
546132718Skan  /* Delete any deletable objects.  This makes ggc_pch_read much
547132718Skan     faster, as it can be sure that no GCable objects remain other
548132718Skan     than the ones just read in.  */
549132718Skan  for (rt = gt_ggc_deletable_rtab; *rt; rt++)
550132718Skan    for (rti = *rt; rti->base != NULL; rti++)
551132718Skan      memset (rti->base, 0, rti->stride);
552132718Skan
553132718Skan  /* Read in all the scalar variables.  */
554132718Skan  for (rt = gt_pch_scalar_rtab; *rt; rt++)
555132718Skan    for (rti = *rt; rti->base != NULL; rti++)
556132718Skan      if (fread (rti->base, rti->stride, 1, f) != 1)
557132718Skan	fatal_error ("can't read PCH file: %m");
558132718Skan
559132718Skan  /* Read in all the global pointers, in 6 easy loops.  */
560132718Skan  for (rt = gt_ggc_rtab; *rt; rt++)
561132718Skan    for (rti = *rt; rti->base != NULL; rti++)
562132718Skan      for (i = 0; i < rti->nelt; i++)
563132718Skan	if (fread ((char *)rti->base + rti->stride * i,
564132718Skan		   sizeof (void *), 1, f) != 1)
565132718Skan	  fatal_error ("can't read PCH file: %m");
566132718Skan
567132718Skan  for (rt = gt_pch_cache_rtab; *rt; rt++)
568132718Skan    for (rti = *rt; rti->base != NULL; rti++)
569132718Skan      for (i = 0; i < rti->nelt; i++)
570132718Skan	if (fread ((char *)rti->base + rti->stride * i,
571132718Skan		   sizeof (void *), 1, f) != 1)
572132718Skan	  fatal_error ("can't read PCH file: %m");
573132718Skan
574132718Skan  if (fread (&mmi, sizeof (mmi), 1, f) != 1)
575132718Skan    fatal_error ("can't read PCH file: %m");
576132718Skan
577161651Skan  result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size,
578161651Skan					  fileno (f), mmi.offset);
579161651Skan  if (result < 0)
580161651Skan    fatal_error ("had to relocate PCH");
581161651Skan  if (result == 0)
582132718Skan    {
583132718Skan      if (fseek (f, mmi.offset, SEEK_SET) != 0
584161651Skan	  || fread (mmi.preferred_base, mmi.size, 1, f) != 1)
585132718Skan	fatal_error ("can't read PCH file: %m");
586132718Skan    }
587132718Skan  else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
588132718Skan    fatal_error ("can't read PCH file: %m");
589132718Skan
590161651Skan  ggc_pch_read (f, mmi.preferred_base);
591132718Skan
592161651Skan  gt_pch_restore_stringpool ();
593161651Skan}
594132718Skan
595161651Skan/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
596161651Skan   Select no address whatsoever, and let gt_pch_save choose what it will with
597161651Skan   malloc, presumably.  */
598132718Skan
599161651Skanvoid *
600161651Skandefault_gt_pch_get_address (size_t size ATTRIBUTE_UNUSED,
601161651Skan			    int fd ATTRIBUTE_UNUSED)
602161651Skan{
603161651Skan  return NULL;
604161651Skan}
605132718Skan
606161651Skan/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is not present.
607161651Skan   Allocate SIZE bytes with malloc.  Return 0 if the address we got is the
608161651Skan   same as base, indicating that the memory has been allocated but needs to
609161651Skan   be read in from the file.  Return -1 if the address differs, to relocation
610161651Skan   of the PCH file would be required.  */
611161651Skan
612161651Skanint
613161651Skandefault_gt_pch_use_address (void *base, size_t size, int fd ATTRIBUTE_UNUSED,
614161651Skan			    size_t offset ATTRIBUTE_UNUSED)
615161651Skan{
616161651Skan  void *addr = xmalloc (size);
617161651Skan  return (addr == base) - 1;
618132718Skan}
619132718Skan
620169689Skan/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS.   Return the
621169689Skan   alignment required for allocating virtual memory. Usually this is the
622169689Skan   same as pagesize.  */
623169689Skan
624169689Skansize_t
625169689Skandefault_gt_pch_alloc_granularity (void)
626169689Skan{
627169689Skan  return getpagesize();
628169689Skan}
629169689Skan
630161651Skan#if HAVE_MMAP_FILE
631161651Skan/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is present.
632161651Skan   We temporarily allocate SIZE bytes, and let the kernel place the data
633169689Skan   wherever it will.  If it worked, that's our spot, if not we're likely
634161651Skan   to be in trouble.  */
635169689Skan
636161651Skanvoid *
637161651Skanmmap_gt_pch_get_address (size_t size, int fd)
638161651Skan{
639161651Skan  void *ret;
640169689Skan
641161651Skan  ret = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
642161651Skan  if (ret == (void *) MAP_FAILED)
643161651Skan    ret = NULL;
644161651Skan  else
645161651Skan    munmap (ret, size);
646169689Skan
647161651Skan  return ret;
648161651Skan}
649161651Skan
650161651Skan/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is present.
651161651Skan   Map SIZE bytes of FD+OFFSET at BASE.  Return 1 if we succeeded at
652161651Skan   mapping the data at BASE, -1 if we couldn't.
653169689Skan
654161651Skan   This version assumes that the kernel honors the START operand of mmap
655161651Skan   even without MAP_FIXED if START through START+SIZE are not currently
656161651Skan   mapped with something.  */
657169689Skan
658161651Skanint
659161651Skanmmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
660161651Skan{
661161651Skan  void *addr;
662169689Skan
663161651Skan  /* We're called with size == 0 if we're not planning to load a PCH
664161651Skan     file at all.  This allows the hook to free any static space that
665161651Skan     we might have allocated at link time.  */
666161651Skan  if (size == 0)
667161651Skan    return -1;
668169689Skan
669161651Skan  addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
670161651Skan	       fd, offset);
671161651Skan
672161651Skan  return addr == base ? 1 : -1;
673169689Skan}
674161651Skan#endif /* HAVE_MMAP_FILE */
675161651Skan
676169689Skan/* Modify the bound based on rlimits.  */
677117395Skanstatic double
678132718Skanggc_rlimit_bound (double limit)
679117395Skan{
680117395Skan#if defined(HAVE_GETRLIMIT)
681117395Skan  struct rlimit rlim;
682169689Skan# if defined (RLIMIT_AS)
683169689Skan  /* RLIMIT_AS is what POSIX says is the limit on mmap.  Presumably
684169689Skan     any OS which has RLIMIT_AS also has a working mmap that GCC will use.  */
685169689Skan  if (getrlimit (RLIMIT_AS, &rlim) == 0
686117395Skan      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
687117395Skan      && rlim.rlim_cur < limit)
688117395Skan    limit = rlim.rlim_cur;
689169689Skan# elif defined (RLIMIT_DATA)
690169689Skan  /* ... but some older OSs bound mmap based on RLIMIT_DATA, or we
691169689Skan     might be on an OS that has a broken mmap.  (Others don't bound
692169689Skan     mmap at all, apparently.)  */
693117395Skan  if (getrlimit (RLIMIT_DATA, &rlim) == 0
694117395Skan      && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
695169689Skan      && rlim.rlim_cur < limit
696169689Skan      /* Darwin has this horribly bogus default setting of
697169689Skan	 RLIMIT_DATA, to 6144Kb.  No-one notices because RLIMIT_DATA
698169689Skan	 appears to be ignored.  Ignore such silliness.  If a limit
699169689Skan	 this small was actually effective for mmap, GCC wouldn't even
700169689Skan	 start up.  */
701169689Skan      && rlim.rlim_cur >= 8 * 1024 * 1024)
702117395Skan    limit = rlim.rlim_cur;
703169689Skan# endif /* RLIMIT_AS or RLIMIT_DATA */
704117395Skan#endif /* HAVE_GETRLIMIT */
705117395Skan
706117395Skan  return limit;
707117395Skan}
708117395Skan
709117395Skan/* Heuristic to set a default for GGC_MIN_EXPAND.  */
710117395Skanint
711132718Skanggc_min_expand_heuristic (void)
712117395Skan{
713117395Skan  double min_expand = physmem_total();
714117395Skan
715117395Skan  /* Adjust for rlimits.  */
716117395Skan  min_expand = ggc_rlimit_bound (min_expand);
717132718Skan
718117395Skan  /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
719117395Skan     a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB).  */
720117395Skan  min_expand /= 1024*1024*1024;
721117395Skan  min_expand *= 70;
722117395Skan  min_expand = MIN (min_expand, 70);
723117395Skan  min_expand += 30;
724117395Skan
725117395Skan  return min_expand;
726117395Skan}
727117395Skan
728117395Skan/* Heuristic to set a default for GGC_MIN_HEAPSIZE.  */
729117395Skanint
730132718Skanggc_min_heapsize_heuristic (void)
731117395Skan{
732169689Skan  double phys_kbytes = physmem_total();
733169689Skan  double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2);
734117395Skan
735169689Skan  phys_kbytes /= 1024; /* Convert to Kbytes.  */
736169689Skan  limit_kbytes /= 1024;
737117395Skan
738117395Skan  /* The heuristic is RAM/8, with a lower bound of 4M and an upper
739117395Skan     bound of 128M (when RAM >= 1GB).  */
740169689Skan  phys_kbytes /= 8;
741117395Skan
742169689Skan#if defined(HAVE_GETRLIMIT) && defined (RLIMIT_RSS)
743169689Skan  /* Try not to overrun the RSS limit while doing garbage collection.
744169689Skan     The RSS limit is only advisory, so no margin is subtracted.  */
745169689Skan {
746169689Skan   struct rlimit rlim;
747169689Skan   if (getrlimit (RLIMIT_RSS, &rlim) == 0
748169689Skan       && rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
749169689Skan     phys_kbytes = MIN (phys_kbytes, rlim.rlim_cur / 1024);
750169689Skan }
751169689Skan# endif
752169689Skan
753169689Skan  /* Don't blindly run over our data limit; do GC at least when the
754169689Skan     *next* GC would be within 16Mb of the limit.  If GCC does hit the
755169689Skan     data limit, compilation will fail, so this tries to be
756169689Skan     conservative.  */
757169689Skan  limit_kbytes = MAX (0, limit_kbytes - 16 * 1024);
758169689Skan  limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic());
759169689Skan  phys_kbytes = MIN (phys_kbytes, limit_kbytes);
760169689Skan
761169689Skan  phys_kbytes = MAX (phys_kbytes, 4 * 1024);
762169689Skan  phys_kbytes = MIN (phys_kbytes, 128 * 1024);
763169689Skan
764169689Skan  return phys_kbytes;
765117395Skan}
766117395Skan
767117395Skanvoid
768132718Skaninit_ggc_heuristics (void)
769117395Skan{
770132718Skan#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT
771117395Skan  set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
772117395Skan  set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
773117395Skan#endif
774117395Skan}
775169689Skan
776169689Skan#ifdef GATHER_STATISTICS
777169689Skan
778169689Skan/* Datastructure used to store per-call-site statistics.  */
779169689Skanstruct loc_descriptor
780169689Skan{
781169689Skan  const char *file;
782169689Skan  int line;
783169689Skan  const char *function;
784169689Skan  int times;
785169689Skan  size_t allocated;
786169689Skan  size_t overhead;
787169689Skan  size_t freed;
788169689Skan  size_t collected;
789169689Skan};
790169689Skan
791169689Skan/* Hashtable used for statistics.  */
792169689Skanstatic htab_t loc_hash;
793169689Skan
794169689Skan/* Hash table helpers functions.  */
795169689Skanstatic hashval_t
796169689Skanhash_descriptor (const void *p)
797169689Skan{
798169689Skan  const struct loc_descriptor *d = p;
799169689Skan
800169689Skan  return htab_hash_pointer (d->function) | d->line;
801169689Skan}
802169689Skan
803169689Skanstatic int
804169689Skaneq_descriptor (const void *p1, const void *p2)
805169689Skan{
806169689Skan  const struct loc_descriptor *d = p1;
807169689Skan  const struct loc_descriptor *d2 = p2;
808169689Skan
809169689Skan  return (d->file == d2->file && d->line == d2->line
810169689Skan	  && d->function == d2->function);
811169689Skan}
812169689Skan
813169689Skan/* Hashtable converting address of allocated field to loc descriptor.  */
814169689Skanstatic htab_t ptr_hash;
815169689Skanstruct ptr_hash_entry
816169689Skan{
817169689Skan  void *ptr;
818169689Skan  struct loc_descriptor *loc;
819169689Skan  size_t size;
820169689Skan};
821169689Skan
822169689Skan/* Hash table helpers functions.  */
823169689Skanstatic hashval_t
824169689Skanhash_ptr (const void *p)
825169689Skan{
826169689Skan  const struct ptr_hash_entry *d = p;
827169689Skan
828169689Skan  return htab_hash_pointer (d->ptr);
829169689Skan}
830169689Skan
831169689Skanstatic int
832169689Skaneq_ptr (const void *p1, const void *p2)
833169689Skan{
834169689Skan  const struct ptr_hash_entry *p = p1;
835169689Skan
836169689Skan  return (p->ptr == p2);
837169689Skan}
838169689Skan
839169689Skan/* Return descriptor for given call site, create new one if needed.  */
840169689Skanstatic struct loc_descriptor *
841169689Skanloc_descriptor (const char *name, int line, const char *function)
842169689Skan{
843169689Skan  struct loc_descriptor loc;
844169689Skan  struct loc_descriptor **slot;
845169689Skan
846169689Skan  loc.file = name;
847169689Skan  loc.line = line;
848169689Skan  loc.function = function;
849169689Skan  if (!loc_hash)
850169689Skan    loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
851169689Skan
852169689Skan  slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1);
853169689Skan  if (*slot)
854169689Skan    return *slot;
855169689Skan  *slot = xcalloc (sizeof (**slot), 1);
856169689Skan  (*slot)->file = name;
857169689Skan  (*slot)->line = line;
858169689Skan  (*slot)->function = function;
859169689Skan  return *slot;
860169689Skan}
861169689Skan
862169689Skan/* Record ALLOCATED and OVERHEAD bytes to descriptor NAME:LINE (FUNCTION).  */
863169689Skanvoid
864169689Skanggc_record_overhead (size_t allocated, size_t overhead, void *ptr,
865169689Skan		     const char *name, int line, const char *function)
866169689Skan{
867169689Skan  struct loc_descriptor *loc = loc_descriptor (name, line, function);
868169689Skan  struct ptr_hash_entry *p = XNEW (struct ptr_hash_entry);
869169689Skan  PTR *slot;
870169689Skan
871169689Skan  p->ptr = ptr;
872169689Skan  p->loc = loc;
873169689Skan  p->size = allocated + overhead;
874169689Skan  if (!ptr_hash)
875169689Skan    ptr_hash = htab_create (10, hash_ptr, eq_ptr, NULL);
876169689Skan  slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), INSERT);
877169689Skan  gcc_assert (!*slot);
878169689Skan  *slot = p;
879169689Skan
880169689Skan  loc->times++;
881169689Skan  loc->allocated+=allocated;
882169689Skan  loc->overhead+=overhead;
883169689Skan}
884169689Skan
885169689Skan/* Helper function for prune_overhead_list.  See if SLOT is still marked and
886169689Skan   remove it from hashtable if it is not.  */
887169689Skanstatic int
888169689Skanggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED)
889169689Skan{
890169689Skan  struct ptr_hash_entry *p = *slot;
891169689Skan  if (!ggc_marked_p (p->ptr))
892169689Skan    {
893169689Skan      p->loc->collected += p->size;
894169689Skan      htab_clear_slot (ptr_hash, slot);
895169689Skan      free (p);
896169689Skan    }
897169689Skan  return 1;
898169689Skan}
899169689Skan
900169689Skan/* After live values has been marked, walk all recorded pointers and see if
901169689Skan   they are still live.  */
902169689Skanvoid
903169689Skanggc_prune_overhead_list (void)
904169689Skan{
905169689Skan  htab_traverse (ptr_hash, ggc_prune_ptr, NULL);
906169689Skan}
907169689Skan
908169689Skan/* Notice that the pointer has been freed.  */
909169689Skanvoid
910169689Skanggc_free_overhead (void *ptr)
911169689Skan{
912169689Skan  PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr),
913169689Skan					NO_INSERT);
914169689Skan  struct ptr_hash_entry *p = *slot;
915169689Skan  p->loc->freed += p->size;
916169689Skan  htab_clear_slot (ptr_hash, slot);
917169689Skan  free (p);
918169689Skan}
919169689Skan
920169689Skan/* Helper for qsort; sort descriptors by amount of memory consumed.  */
921169689Skanstatic int
922169689Skancmp_statistic (const void *loc1, const void *loc2)
923169689Skan{
924169689Skan  struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1;
925169689Skan  struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2;
926169689Skan  return ((l1->allocated + l1->overhead - l1->freed) -
927169689Skan	  (l2->allocated + l2->overhead - l2->freed));
928169689Skan}
929169689Skan
930169689Skan/* Collect array of the descriptors from hashtable.  */
931169689Skanstruct loc_descriptor **loc_array;
932169689Skanstatic int
933169689Skanadd_statistics (void **slot, void *b)
934169689Skan{
935169689Skan  int *n = (int *)b;
936169689Skan  loc_array[*n] = (struct loc_descriptor *) *slot;
937169689Skan  (*n)++;
938169689Skan  return 1;
939169689Skan}
940169689Skan
941169689Skan/* Dump per-site memory statistics.  */
942169689Skan#endif
943169689Skanvoid
944169689Skandump_ggc_loc_statistics (void)
945169689Skan{
946169689Skan#ifdef GATHER_STATISTICS
947169689Skan  int nentries = 0;
948169689Skan  char s[4096];
949169689Skan  size_t collected = 0, freed = 0, allocated = 0, overhead = 0, times = 0;
950169689Skan  int i;
951169689Skan
952169689Skan  ggc_force_collect = true;
953169689Skan  ggc_collect ();
954169689Skan
955169689Skan  loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements);
956169689Skan  fprintf (stderr, "-------------------------------------------------------\n");
957169689Skan  fprintf (stderr, "\n%-48s %10s       %10s       %10s       %10s       %10s\n",
958169689Skan	   "source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
959169689Skan  fprintf (stderr, "-------------------------------------------------------\n");
960169689Skan  htab_traverse (loc_hash, add_statistics, &nentries);
961169689Skan  qsort (loc_array, nentries, sizeof (*loc_array), cmp_statistic);
962169689Skan  for (i = 0; i < nentries; i++)
963169689Skan    {
964169689Skan      struct loc_descriptor *d = loc_array[i];
965169689Skan      allocated += d->allocated;
966169689Skan      times += d->times;
967169689Skan      freed += d->freed;
968169689Skan      collected += d->collected;
969169689Skan      overhead += d->overhead;
970169689Skan    }
971169689Skan  for (i = 0; i < nentries; i++)
972169689Skan    {
973169689Skan      struct loc_descriptor *d = loc_array[i];
974169689Skan      if (d->allocated)
975169689Skan	{
976169689Skan	  const char *s1 = d->file;
977169689Skan	  const char *s2;
978169689Skan	  while ((s2 = strstr (s1, "gcc/")))
979169689Skan	    s1 = s2 + 4;
980169689Skan	  sprintf (s, "%s:%i (%s)", s1, d->line, d->function);
981169689Skan	  s[48] = 0;
982169689Skan	  fprintf (stderr, "%-48s %10li:%4.1f%% %10li:%4.1f%% %10li:%4.1f%% %10li:%4.1f%% %10li\n", s,
983169689Skan		   (long)d->collected,
984169689Skan		   (d->collected) * 100.0 / collected,
985169689Skan		   (long)d->freed,
986169689Skan		   (d->freed) * 100.0 / freed,
987169689Skan		   (long)(d->allocated + d->overhead - d->freed - d->collected),
988169689Skan		   (d->allocated + d->overhead - d->freed - d->collected) * 100.0
989169689Skan		   / (allocated + overhead - freed - collected),
990169689Skan		   (long)d->overhead,
991169689Skan		   d->overhead * 100.0 / overhead,
992169689Skan		   (long)d->times);
993169689Skan	}
994169689Skan    }
995169689Skan  fprintf (stderr, "%-48s %10ld       %10ld       %10ld       %10ld       %10ld\n",
996169689Skan	   "Total", (long)collected, (long)freed,
997169689Skan	   (long)(allocated + overhead - freed - collected), (long)overhead,
998169689Skan	   (long)times);
999169689Skan  fprintf (stderr, "%-48s %10s       %10s       %10s       %10s       %10s\n",
1000169689Skan	   "source location", "Garbage", "Freed", "Leak", "Overhead", "Times");
1001169689Skan  fprintf (stderr, "-------------------------------------------------------\n");
1002169689Skan#endif
1003169689Skan}
1004