]> gcc.gnu.org Git - gcc.git/blame - gcc/ggc-common.c
function.h (struct rtl_data): Remove struct and accessor macros.
[gcc.git] / gcc / ggc-common.c
CommitLineData
b49a6a90 1/* Simple garbage collection for the GNU compiler.
5624e564 2 Copyright (C) 1999-2015 Free Software Foundation, Inc.
b49a6a90 3
1322177d 4This file is part of GCC.
b49a6a90 5
1322177d
LB
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1322177d 9version.
b49a6a90 10
1322177d
LB
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
14a774a9
RK
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
b49a6a90 15
14a774a9 16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
b49a6a90
AS
19
20/* Generic garbage collection (GC) functions and data, not specific to
21 any particular GC implementation. */
22
23#include "config.h"
24#include "system.h"
4977bab6 25#include "coretypes.h"
a9429e29 26#include "ggc-internal.h"
718f9c0f 27#include "diagnostic-core.h"
9ac121af 28#include "params.h"
18c81520 29#include "hosthooks.h"
4d0c31e6 30#include "hosthooks-def.h"
ae2392a9 31#include "plugin.h"
10d43c2d 32#include "timevar.h"
17211ab5 33
07724022
JH
34/* When set, ggc_collect will do collection. */
35bool ggc_force_collect;
36
dae4174e
TT
37/* When true, protect the contents of the identifier hash table. */
38bool ggc_protect_identifiers = true;
39
3277221c
MM
40/* Statistics about the allocation. */
41static ggc_statistics *ggc_stats;
42
17211ab5
GK
43struct traversal_state;
44
20c1dc5e
AJ
45static int compare_ptr_data (const void *, const void *);
46static void relocate_ptrs (void *, void *);
47static void write_pch_globals (const struct ggc_root_tab * const *tab,
48 struct traversal_state *state);
b49a6a90
AS
49
50/* Maintain global roots that are preserved during GC. */
51
ae2392a9
BS
52/* This extra vector of dynamically registered root_tab-s is used by
53 ggc_mark_roots and gives the ability to dynamically add new GGC root
32c9b4e9
DS
54 tables, for instance from some plugins; this vector is on the heap
55 since it is used by GGC internally. */
56typedef const struct ggc_root_tab *const_ggc_root_tab_t;
9771b263 57static vec<const_ggc_root_tab_t> extra_root_vec;
ae2392a9 58
ae2392a9
BS
59/* Dynamically register a new GGC root table RT. This is useful for
60 plugins. */
61
b8698a0f 62void
ae2392a9
BS
63ggc_register_root_tab (const struct ggc_root_tab* rt)
64{
32c9b4e9 65 if (rt)
9771b263 66 extra_root_vec.safe_push (rt);
ae2392a9
BS
67}
68
71bb2d86
NF
69/* Mark all the roots in the table RT. */
70
71static void
72ggc_mark_root_tab (const_ggc_root_tab_t rt)
73{
74 size_t i;
75
76 for ( ; rt->base != NULL; rt++)
77 for (i = 0; i < rt->nelt; i++)
78 (*rt->cb) (*(void **) ((char *)rt->base + rt->stride * i));
79}
80
cb2ec151
RH
81/* Iterate through all registered roots and mark each element. */
82
b49a6a90 83void
20c1dc5e 84ggc_mark_roots (void)
96df4529 85{
e2500fed 86 const struct ggc_root_tab *const *rt;
71bb2d86 87 const_ggc_root_tab_t rtp, rti;
e2500fed 88 size_t i;
589005ff 89
e2500fed
GK
90 for (rt = gt_ggc_deletable_rtab; *rt; rt++)
91 for (rti = *rt; rti->base != NULL; rti++)
92 memset (rti->base, 0, rti->stride);
93
94 for (rt = gt_ggc_rtab; *rt; rt++)
71bb2d86 95 ggc_mark_root_tab (*rt);
ae2392a9 96
9771b263 97 FOR_EACH_VEC_ELT (extra_root_vec, i, rtp)
71bb2d86 98 ggc_mark_root_tab (rtp);
bedda2da 99
dae4174e
TT
100 if (ggc_protect_identifiers)
101 ggc_mark_stringpool ();
bedda2da 102
aebf76a2
TS
103 gt_clear_caches ();
104
dae4174e
TT
105 if (! ggc_protect_identifiers)
106 ggc_purge_stringpool ();
ae2392a9
BS
107
108 /* Some plugins may call ggc_set_mark from here. */
109 invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL);
96df4529
AS
110}
111
e2500fed
GK
112/* Allocate a block of memory, then clear it. */
113void *
de49ce19
TS
114ggc_internal_cleared_alloc (size_t size, void (*f)(void *), size_t s, size_t n
115 MEM_STAT_DECL)
ef8288f7 116{
de49ce19 117 void *buf = ggc_internal_alloc (size, f, s, n PASS_MEM_STAT);
e2500fed
GK
118 memset (buf, 0, size);
119 return buf;
ef8288f7
RH
120}
121
e2500fed
GK
122/* Resize a block of memory, possibly re-allocating it. */
123void *
231120e5 124ggc_realloc (void *x, size_t size MEM_STAT_DECL)
ef8288f7 125{
e2500fed
GK
126 void *r;
127 size_t old_size;
ef8288f7 128
e2500fed 129 if (x == NULL)
231120e5 130 return ggc_internal_alloc (size PASS_MEM_STAT);
ef8288f7 131
e2500fed 132 old_size = ggc_get_size (x);
685fe032 133
e2500fed 134 if (size <= old_size)
9a0a7d5d
HPN
135 {
136 /* Mark the unwanted memory as unaccessible. We also need to make
137 the "new" size accessible, since ggc_get_size returns the size of
138 the pool, not the size of the individually allocated object, the
139 size which was previously made accessible. Unfortunately, we
140 don't know that previously allocated size. Without that
141 knowledge we have to lose some initialization-tracking for the
142 old parts of the object. An alternative is to mark the whole
20c1dc5e 143 old_size as reachable, but that would lose tracking of writes
9a0a7d5d
HPN
144 after the end of the object (by small offsets). Discard the
145 handle to avoid handle leak. */
35dee980
HPN
146 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *) x + size,
147 old_size - size));
148 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (x, size));
9a0a7d5d
HPN
149 return x;
150 }
ef8288f7 151
231120e5 152 r = ggc_internal_alloc (size PASS_MEM_STAT);
9a0a7d5d
HPN
153
154 /* Since ggc_get_size returns the size of the pool, not the size of the
155 individually allocated object, we'd access parts of the old object
156 that were marked invalid with the memcpy below. We lose a bit of the
157 initialization-tracking since some of it may be uninitialized. */
35dee980 158 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (x, old_size));
9a0a7d5d 159
e2500fed 160 memcpy (r, x, old_size);
9a0a7d5d
HPN
161
162 /* The old object is not supposed to be used anymore. */
685fe032 163 ggc_free (x);
9a0a7d5d 164
e2500fed 165 return r;
ef8288f7
RH
166}
167
f8a83ee3 168void *
a9429e29
LB
169ggc_cleared_alloc_htab_ignore_args (size_t c ATTRIBUTE_UNUSED,
170 size_t n ATTRIBUTE_UNUSED)
f8a83ee3 171{
a9429e29 172 gcc_assert (c * n == sizeof (struct htab));
766090c2 173 return ggc_cleared_alloc<htab> ();
a9429e29
LB
174}
175
176/* TODO: once we actually use type information in GGC, create a new tag
177 gt_gcc_ptr_array and use it for pointer arrays. */
178void *
179ggc_cleared_alloc_ptr_array_two_args (size_t c, size_t n)
180{
181 gcc_assert (sizeof (PTR *) == n);
766090c2 182 return ggc_cleared_vec_alloc<PTR *> (c);
f8a83ee3
ZW
183}
184
17211ab5 185/* These are for splay_tree_new_ggc. */
20c1dc5e 186void *
cd030c07 187ggc_splay_alloc (int sz, void *nl)
17211ab5 188{
282899df 189 gcc_assert (!nl);
a9429e29 190 return ggc_internal_alloc (sz);
17211ab5
GK
191}
192
193void
20c1dc5e 194ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl)
17211ab5 195{
282899df 196 gcc_assert (!nl);
17211ab5
GK
197}
198
3277221c 199/* Print statistics that are independent of the collector in use. */
fba0bfd4
ZW
200#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
201 ? (x) \
202 : ((x) < 1024*1024*10 \
203 ? (x) / 1024 \
204 : (x) / (1024*1024))))
205#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
3277221c
MM
206
207void
20c1dc5e
AJ
208ggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED,
209 ggc_statistics *stats)
3277221c 210{
3277221c
MM
211 /* Set the pointer so that during collection we will actually gather
212 the statistics. */
213 ggc_stats = stats;
214
215 /* Then do one collection to fill in the statistics. */
216 ggc_collect ();
217
17211ab5
GK
218 /* At present, we don't really gather any interesting statistics. */
219
220 /* Don't gather statistics any more. */
221 ggc_stats = NULL;
222}
223\f
224/* Functions for saving and restoring GCable memory to disk. */
225
20c1dc5e 226struct ptr_data
17211ab5
GK
227{
228 void *obj;
229 void *note_ptr_cookie;
230 gt_note_pointers note_ptr_fn;
231 gt_handle_reorder reorder_fn;
232 size_t size;
233 void *new_addr;
234};
235
9204da15 236#define POINTER_HASH(x) (hashval_t)((intptr_t)x >> 3)
17211ab5 237
4a8fb1a1
LC
238/* Helper for hashing saving_htab. */
239
240struct saving_hasher : typed_free_remove <ptr_data>
241{
67f58944
TS
242 typedef ptr_data *value_type;
243 typedef void *compare_type;
244 static inline hashval_t hash (const ptr_data *);
245 static inline bool equal (const ptr_data *, const void *);
4a8fb1a1
LC
246};
247
248inline hashval_t
67f58944 249saving_hasher::hash (const ptr_data *p)
4a8fb1a1
LC
250{
251 return POINTER_HASH (p->obj);
252}
253
254inline bool
67f58944 255saving_hasher::equal (const ptr_data *p1, const void *p2)
4a8fb1a1
LC
256{
257 return p1->obj == p2;
258}
259
c203e8a7 260static hash_table<saving_hasher> *saving_htab;
4a8fb1a1 261
17211ab5
GK
262/* Register an object in the hash table. */
263
264int
20c1dc5e 265gt_pch_note_object (void *obj, void *note_ptr_cookie,
cd030c07 266 gt_note_pointers note_ptr_fn)
17211ab5
GK
267{
268 struct ptr_data **slot;
20c1dc5e 269
17211ab5
GK
270 if (obj == NULL || obj == (void *) 1)
271 return 0;
272
273 slot = (struct ptr_data **)
c203e8a7 274 saving_htab->find_slot_with_hash (obj, POINTER_HASH (obj), INSERT);
17211ab5
GK
275 if (*slot != NULL)
276 {
282899df
NS
277 gcc_assert ((*slot)->note_ptr_fn == note_ptr_fn
278 && (*slot)->note_ptr_cookie == note_ptr_cookie);
17211ab5
GK
279 return 0;
280 }
20c1dc5e 281
d3bfe4de 282 *slot = XCNEW (struct ptr_data);
17211ab5
GK
283 (*slot)->obj = obj;
284 (*slot)->note_ptr_fn = note_ptr_fn;
285 (*slot)->note_ptr_cookie = note_ptr_cookie;
286 if (note_ptr_fn == gt_pch_p_S)
d3bfe4de 287 (*slot)->size = strlen ((const char *)obj) + 1;
17211ab5
GK
288 else
289 (*slot)->size = ggc_get_size (obj);
290 return 1;
291}
292
293/* Register an object in the hash table. */
294
295void
20c1dc5e
AJ
296gt_pch_note_reorder (void *obj, void *note_ptr_cookie,
297 gt_handle_reorder reorder_fn)
17211ab5
GK
298{
299 struct ptr_data *data;
20c1dc5e 300
17211ab5
GK
301 if (obj == NULL || obj == (void *) 1)
302 return;
303
d3bfe4de 304 data = (struct ptr_data *)
c203e8a7 305 saving_htab->find_with_hash (obj, POINTER_HASH (obj));
282899df 306 gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie);
20c1dc5e 307
17211ab5
GK
308 data->reorder_fn = reorder_fn;
309}
310
17211ab5
GK
311/* Handy state for the traversal functions. */
312
20c1dc5e 313struct traversal_state
17211ab5
GK
314{
315 FILE *f;
316 struct ggc_pch_data *d;
317 size_t count;
318 struct ptr_data **ptrs;
319 size_t ptrs_i;
320};
321
322/* Callbacks for htab_traverse. */
323
4a8fb1a1
LC
324int
325ggc_call_count (ptr_data **slot, traversal_state *state)
17211ab5 326{
4a8fb1a1 327 struct ptr_data *d = *slot;
20c1dc5e 328
08cee789 329 ggc_pch_count_object (state->d, d->obj, d->size,
cd030c07 330 d->note_ptr_fn == gt_pch_p_S);
17211ab5
GK
331 state->count++;
332 return 1;
333}
334
4a8fb1a1
LC
335int
336ggc_call_alloc (ptr_data **slot, traversal_state *state)
17211ab5 337{
4a8fb1a1 338 struct ptr_data *d = *slot;
20c1dc5e 339
08cee789 340 d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size,
cd030c07 341 d->note_ptr_fn == gt_pch_p_S);
17211ab5
GK
342 state->ptrs[state->ptrs_i++] = d;
343 return 1;
344}
345
346/* Callback for qsort. */
347
348static int
20c1dc5e 349compare_ptr_data (const void *p1_p, const void *p2_p)
17211ab5 350{
58f9752a
KG
351 const struct ptr_data *const p1 = *(const struct ptr_data *const *)p1_p;
352 const struct ptr_data *const p2 = *(const struct ptr_data *const *)p2_p;
17211ab5
GK
353 return (((size_t)p1->new_addr > (size_t)p2->new_addr)
354 - ((size_t)p1->new_addr < (size_t)p2->new_addr));
355}
356
357/* Callbacks for note_ptr_fn. */
358
359static void
20c1dc5e 360relocate_ptrs (void *ptr_p, void *state_p)
17211ab5
GK
361{
362 void **ptr = (void **)ptr_p;
20c1dc5e 363 struct traversal_state *state ATTRIBUTE_UNUSED
17211ab5
GK
364 = (struct traversal_state *)state_p;
365 struct ptr_data *result;
366
367 if (*ptr == NULL || *ptr == (void *)1)
368 return;
20c1dc5e 369
d3bfe4de 370 result = (struct ptr_data *)
c203e8a7 371 saving_htab->find_with_hash (*ptr, POINTER_HASH (*ptr));
282899df 372 gcc_assert (result);
17211ab5
GK
373 *ptr = result->new_addr;
374}
375
376/* Write out, after relocation, the pointers in TAB. */
377static void
20c1dc5e
AJ
378write_pch_globals (const struct ggc_root_tab * const *tab,
379 struct traversal_state *state)
17211ab5
GK
380{
381 const struct ggc_root_tab *const *rt;
382 const struct ggc_root_tab *rti;
383 size_t i;
384
385 for (rt = tab; *rt; rt++)
386 for (rti = *rt; rti->base != NULL; rti++)
387 for (i = 0; i < rti->nelt; i++)
388 {
389 void *ptr = *(void **)((char *)rti->base + rti->stride * i);
390 struct ptr_data *new_ptr;
391 if (ptr == NULL || ptr == (void *)1)
392 {
20c1dc5e 393 if (fwrite (&ptr, sizeof (void *), 1, state->f)
17211ab5 394 != 1)
40fecdd6 395 fatal_error (input_location, "can%'t write PCH file: %m");
17211ab5
GK
396 }
397 else
398 {
d3bfe4de 399 new_ptr = (struct ptr_data *)
c203e8a7 400 saving_htab->find_with_hash (ptr, POINTER_HASH (ptr));
20c1dc5e 401 if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
17211ab5 402 != 1)
40fecdd6 403 fatal_error (input_location, "can%'t write PCH file: %m");
17211ab5
GK
404 }
405 }
406}
407
408/* Hold the information we need to mmap the file back in. */
409
20c1dc5e 410struct mmap_info
17211ab5
GK
411{
412 size_t offset;
413 size_t size;
414 void *preferred_base;
415};
416
417/* Write out the state of the compiler to F. */
418
419void
20c1dc5e 420gt_pch_save (FILE *f)
17211ab5
GK
421{
422 const struct ggc_root_tab *const *rt;
423 const struct ggc_root_tab *rti;
424 size_t i;
425 struct traversal_state state;
426 char *this_object = NULL;
427 size_t this_object_size = 0;
428 struct mmap_info mmi;
c3284718 429 const size_t mmap_offset_alignment = host_hooks.gt_pch_alloc_granularity ();
17211ab5
GK
430
431 gt_pch_save_stringpool ();
432
10d43c2d 433 timevar_push (TV_PCH_PTR_REALLOC);
c203e8a7 434 saving_htab = new hash_table<saving_hasher> (50000);
17211ab5
GK
435
436 for (rt = gt_ggc_rtab; *rt; rt++)
437 for (rti = *rt; rti->base != NULL; rti++)
438 for (i = 0; i < rti->nelt; i++)
439 (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
440
17211ab5
GK
441 /* Prepare the objects for writing, determine addresses and such. */
442 state.f = f;
a9429e29 443 state.d = init_ggc_pch ();
17211ab5 444 state.count = 0;
c203e8a7 445 saving_htab->traverse <traversal_state *, ggc_call_count> (&state);
17211ab5
GK
446
447 mmi.size = ggc_pch_total_size (state.d);
448
18c81520
GK
449 /* Try to arrange things so that no relocation is necessary, but
450 don't try very hard. On most platforms, this will always work,
b8698a0f 451 and on the rest it's a lot of work to do better.
18c81520
GK
452 (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and
453 HOST_HOOKS_GT_PCH_USE_ADDRESS.) */
4d0c31e6 454 mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f));
b8698a0f 455
17211ab5
GK
456 ggc_pch_this_base (state.d, mmi.preferred_base);
457
5ed6ace5 458 state.ptrs = XNEWVEC (struct ptr_data *, state.count);
17211ab5 459 state.ptrs_i = 0;
10d43c2d 460
c203e8a7 461 saving_htab->traverse <traversal_state *, ggc_call_alloc> (&state);
10d43c2d
DN
462 timevar_pop (TV_PCH_PTR_REALLOC);
463
464 timevar_push (TV_PCH_PTR_SORT);
17211ab5 465 qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
10d43c2d 466 timevar_pop (TV_PCH_PTR_SORT);
17211ab5
GK
467
468 /* Write out all the scalar variables. */
469 for (rt = gt_pch_scalar_rtab; *rt; rt++)
470 for (rti = *rt; rti->base != NULL; rti++)
471 if (fwrite (rti->base, rti->stride, 1, f) != 1)
40fecdd6 472 fatal_error (input_location, "can%'t write PCH file: %m");
17211ab5
GK
473
474 /* Write out all the global pointers, after translation. */
475 write_pch_globals (gt_ggc_rtab, &state);
17211ab5 476
90aa6719
DS
477 /* Pad the PCH file so that the mmapped area starts on an allocation
478 granularity (usually page) boundary. */
17211ab5 479 {
70f8b89f
KG
480 long o;
481 o = ftell (state.f) + sizeof (mmi);
482 if (o == -1)
40fecdd6 483 fatal_error (input_location, "can%'t get position in PCH file: %m");
90aa6719
DS
484 mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment;
485 if (mmi.offset == mmap_offset_alignment)
17211ab5
GK
486 mmi.offset = 0;
487 mmi.offset += o;
488 }
489 if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1)
40fecdd6 490 fatal_error (input_location, "can%'t write PCH file: %m");
17211ab5
GK
491 if (mmi.offset != 0
492 && fseek (state.f, mmi.offset, SEEK_SET) != 0)
40fecdd6 493 fatal_error (input_location, "can%'t write padding to PCH file: %m");
17211ab5 494
08cee789
DJ
495 ggc_pch_prepare_write (state.d, state.f);
496
0b50e654
JJ
497#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
498 vec<char> vbits = vNULL;
499#endif
500
17211ab5
GK
501 /* Actually write out the objects. */
502 for (i = 0; i < state.count; i++)
3277221c 503 {
17211ab5
GK
504 if (this_object_size < state.ptrs[i]->size)
505 {
506 this_object_size = state.ptrs[i]->size;
d3bfe4de 507 this_object = XRESIZEVAR (char, this_object, this_object_size);
17211ab5 508 }
0b50e654
JJ
509#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
510 /* obj might contain uninitialized bytes, e.g. in the trailing
511 padding of the object. Avoid warnings by making the memory
512 temporarily defined and then restoring previous state. */
513 int get_vbits = 0;
514 size_t valid_size = state.ptrs[i]->size;
515 if (__builtin_expect (RUNNING_ON_VALGRIND, 0))
516 {
517 if (vbits.length () < valid_size)
518 vbits.safe_grow (valid_size);
519 get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
520 vbits.address (), valid_size);
521 if (get_vbits == 3)
522 {
523 /* We assume that first part of obj is addressable, and
524 the rest is unaddressable. Find out where the boundary is
525 using binary search. */
526 size_t lo = 0, hi = valid_size;
527 while (hi > lo)
528 {
529 size_t mid = (lo + hi) / 2;
530 get_vbits = VALGRIND_GET_VBITS ((char *) state.ptrs[i]->obj
531 + mid, vbits.address (),
532 1);
533 if (get_vbits == 3)
534 hi = mid;
535 else if (get_vbits == 1)
536 lo = mid + 1;
537 else
538 break;
539 }
540 if (get_vbits == 1 || get_vbits == 3)
541 {
542 valid_size = lo;
543 get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
544 vbits.address (),
545 valid_size);
546 }
547 }
548 if (get_vbits == 1)
549 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (state.ptrs[i]->obj,
550 state.ptrs[i]->size));
551 }
552#endif
17211ab5
GK
553 memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
554 if (state.ptrs[i]->reorder_fn != NULL)
20c1dc5e 555 state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
17211ab5
GK
556 state.ptrs[i]->note_ptr_cookie,
557 relocate_ptrs, &state);
20c1dc5e 558 state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj,
17211ab5
GK
559 state.ptrs[i]->note_ptr_cookie,
560 relocate_ptrs, &state);
561 ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
4d0c31e6
RH
562 state.ptrs[i]->new_addr, state.ptrs[i]->size,
563 state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
17211ab5
GK
564 if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
565 memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
0b50e654
JJ
566#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
567 if (__builtin_expect (get_vbits == 1, 0))
568 {
569 (void) VALGRIND_SET_VBITS (state.ptrs[i]->obj, vbits.address (),
570 valid_size);
571 if (valid_size != state.ptrs[i]->size)
572 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS ((char *)
573 state.ptrs[i]->obj
574 + valid_size,
575 state.ptrs[i]->size
576 - valid_size));
577 }
578#endif
3277221c 579 }
0b50e654
JJ
580#if defined ENABLE_VALGRIND_CHECKING && defined VALGRIND_GET_VBITS
581 vbits.release ();
582#endif
583
17211ab5 584 ggc_pch_finish (state.d, state.f);
d24ecd21 585 gt_pch_fixup_stringpool ();
17211ab5 586
0b50e654
JJ
587 XDELETE (state.ptrs);
588 XDELETE (this_object);
c203e8a7
TS
589 delete saving_htab;
590 saving_htab = NULL;
17211ab5
GK
591}
592
593/* Read the state of the compiler back in from F. */
594
595void
20c1dc5e 596gt_pch_restore (FILE *f)
17211ab5
GK
597{
598 const struct ggc_root_tab *const *rt;
599 const struct ggc_root_tab *rti;
600 size_t i;
601 struct mmap_info mmi;
4d0c31e6 602 int result;
17211ab5
GK
603
604 /* Delete any deletable objects. This makes ggc_pch_read much
605 faster, as it can be sure that no GCable objects remain other
606 than the ones just read in. */
607 for (rt = gt_ggc_deletable_rtab; *rt; rt++)
608 for (rti = *rt; rti->base != NULL; rti++)
609 memset (rti->base, 0, rti->stride);
610
611 /* Read in all the scalar variables. */
612 for (rt = gt_pch_scalar_rtab; *rt; rt++)
613 for (rti = *rt; rti->base != NULL; rti++)
614 if (fread (rti->base, rti->stride, 1, f) != 1)
40fecdd6 615 fatal_error (input_location, "can%'t read PCH file: %m");
17211ab5
GK
616
617 /* Read in all the global pointers, in 6 easy loops. */
618 for (rt = gt_ggc_rtab; *rt; rt++)
619 for (rti = *rt; rti->base != NULL; rti++)
620 for (i = 0; i < rti->nelt; i++)
621 if (fread ((char *)rti->base + rti->stride * i,
622 sizeof (void *), 1, f) != 1)
40fecdd6 623 fatal_error (input_location, "can%'t read PCH file: %m");
17211ab5 624
17211ab5 625 if (fread (&mmi, sizeof (mmi), 1, f) != 1)
40fecdd6 626 fatal_error (input_location, "can%'t read PCH file: %m");
20c1dc5e 627
4d0c31e6
RH
628 result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size,
629 fileno (f), mmi.offset);
630 if (result < 0)
40fecdd6 631 fatal_error (input_location, "had to relocate PCH");
4d0c31e6 632 if (result == 0)
18c81520 633 {
4d0c31e6
RH
634 if (fseek (f, mmi.offset, SEEK_SET) != 0
635 || fread (mmi.preferred_base, mmi.size, 1, f) != 1)
40fecdd6 636 fatal_error (input_location, "can%'t read PCH file: %m");
4d0c31e6
RH
637 }
638 else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
40fecdd6 639 fatal_error (input_location, "can%'t read PCH file: %m");
8eb6a092 640
4d0c31e6 641 ggc_pch_read (f, mmi.preferred_base);
18c81520 642
4d0c31e6
RH
643 gt_pch_restore_stringpool ();
644}
18c81520 645
4d0c31e6
RH
646/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
647 Select no address whatsoever, and let gt_pch_save choose what it will with
648 malloc, presumably. */
ee0d75ef 649
4d0c31e6
RH
650void *
651default_gt_pch_get_address (size_t size ATTRIBUTE_UNUSED,
652 int fd ATTRIBUTE_UNUSED)
653{
654 return NULL;
655}
ee0d75ef 656
4d0c31e6
RH
657/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is not present.
658 Allocate SIZE bytes with malloc. Return 0 if the address we got is the
659 same as base, indicating that the memory has been allocated but needs to
660 be read in from the file. Return -1 if the address differs, to relocation
661 of the PCH file would be required. */
662
663int
664default_gt_pch_use_address (void *base, size_t size, int fd ATTRIBUTE_UNUSED,
665 size_t offset ATTRIBUTE_UNUSED)
666{
667 void *addr = xmalloc (size);
668 return (addr == base) - 1;
669}
ee0d75ef 670
90aa6719
DS
671/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS. Return the
672 alignment required for allocating virtual memory. Usually this is the
673 same as pagesize. */
674
675size_t
676default_gt_pch_alloc_granularity (void)
677{
c3284718 678 return getpagesize ();
90aa6719
DS
679}
680
4d0c31e6
RH
681#if HAVE_MMAP_FILE
682/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is present.
683 We temporarily allocate SIZE bytes, and let the kernel place the data
d1a6adeb 684 wherever it will. If it worked, that's our spot, if not we're likely
4d0c31e6 685 to be in trouble. */
8eb6a092 686
4d0c31e6
RH
687void *
688mmap_gt_pch_get_address (size_t size, int fd)
689{
690 void *ret;
18c81520 691
4d0c31e6
RH
692 ret = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
693 if (ret == (void *) MAP_FAILED)
694 ret = NULL;
695 else
bba09b5a 696 munmap ((caddr_t) ret, size);
3277221c 697
4d0c31e6
RH
698 return ret;
699}
3277221c 700
4d0c31e6 701/* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is present.
b8698a0f 702 Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at
4d0c31e6 703 mapping the data at BASE, -1 if we couldn't.
20c1dc5e 704
4d0c31e6
RH
705 This version assumes that the kernel honors the START operand of mmap
706 even without MAP_FIXED if START through START+SIZE are not currently
707 mapped with something. */
17211ab5 708
4d0c31e6
RH
709int
710mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset)
711{
712 void *addr;
17211ab5 713
4d0c31e6
RH
714 /* We're called with size == 0 if we're not planning to load a PCH
715 file at all. This allows the hook to free any static space that
716 we might have allocated at link time. */
717 if (size == 0)
718 return -1;
719
bba09b5a 720 addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
4d0c31e6
RH
721 fd, offset);
722
723 return addr == base ? 1 : -1;
3277221c 724}
4d0c31e6 725#endif /* HAVE_MMAP_FILE */
9ac121af 726
e4dfaf72
LB
727#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT
728
d37e6b50 729/* Modify the bound based on rlimits. */
16226f1e 730static double
20c1dc5e 731ggc_rlimit_bound (double limit)
16226f1e
KG
732{
733#if defined(HAVE_GETRLIMIT)
734 struct rlimit rlim;
d37e6b50
GK
735# if defined (RLIMIT_AS)
736 /* RLIMIT_AS is what POSIX says is the limit on mmap. Presumably
737 any OS which has RLIMIT_AS also has a working mmap that GCC will use. */
738 if (getrlimit (RLIMIT_AS, &rlim) == 0
a2581175 739 && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
16226f1e
KG
740 && rlim.rlim_cur < limit)
741 limit = rlim.rlim_cur;
d37e6b50
GK
742# elif defined (RLIMIT_DATA)
743 /* ... but some older OSs bound mmap based on RLIMIT_DATA, or we
744 might be on an OS that has a broken mmap. (Others don't bound
745 mmap at all, apparently.) */
16226f1e 746 if (getrlimit (RLIMIT_DATA, &rlim) == 0
a2581175 747 && rlim.rlim_cur != (rlim_t) RLIM_INFINITY
d37e6b50
GK
748 && rlim.rlim_cur < limit
749 /* Darwin has this horribly bogus default setting of
750 RLIMIT_DATA, to 6144Kb. No-one notices because RLIMIT_DATA
751 appears to be ignored. Ignore such silliness. If a limit
752 this small was actually effective for mmap, GCC wouldn't even
753 start up. */
754 && rlim.rlim_cur >= 8 * 1024 * 1024)
16226f1e 755 limit = rlim.rlim_cur;
d37e6b50 756# endif /* RLIMIT_AS or RLIMIT_DATA */
16226f1e
KG
757#endif /* HAVE_GETRLIMIT */
758
759 return limit;
760}
761
9ac121af 762/* Heuristic to set a default for GGC_MIN_EXPAND. */
e4dfaf72 763static int
20c1dc5e 764ggc_min_expand_heuristic (void)
9ac121af 765{
c3284718 766 double min_expand = physmem_total ();
16226f1e
KG
767
768 /* Adjust for rlimits. */
769 min_expand = ggc_rlimit_bound (min_expand);
20c1dc5e 770
9ac121af
KG
771 /* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
772 a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB). */
773 min_expand /= 1024*1024*1024;
774 min_expand *= 70;
775 min_expand = MIN (min_expand, 70);
776 min_expand += 30;
777
778 return min_expand;
779}
780
781/* Heuristic to set a default for GGC_MIN_HEAPSIZE. */
e4dfaf72 782static int
20c1dc5e 783ggc_min_heapsize_heuristic (void)
9ac121af 784{
c3284718 785 double phys_kbytes = physmem_total ();
d37e6b50 786 double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2);
16226f1e 787
d37e6b50
GK
788 phys_kbytes /= 1024; /* Convert to Kbytes. */
789 limit_kbytes /= 1024;
20c1dc5e 790
9ac121af
KG
791 /* The heuristic is RAM/8, with a lower bound of 4M and an upper
792 bound of 128M (when RAM >= 1GB). */
d37e6b50
GK
793 phys_kbytes /= 8;
794
795#if defined(HAVE_GETRLIMIT) && defined (RLIMIT_RSS)
b8698a0f 796 /* Try not to overrun the RSS limit while doing garbage collection.
d37e6b50
GK
797 The RSS limit is only advisory, so no margin is subtracted. */
798 {
799 struct rlimit rlim;
800 if (getrlimit (RLIMIT_RSS, &rlim) == 0
801 && rlim.rlim_cur != (rlim_t) RLIM_INFINITY)
802 phys_kbytes = MIN (phys_kbytes, rlim.rlim_cur / 1024);
803 }
804# endif
805
806 /* Don't blindly run over our data limit; do GC at least when the
ded5f8f4
NF
807 *next* GC would be within 20Mb of the limit or within a quarter of
808 the limit, whichever is larger. If GCC does hit the data limit,
809 compilation will fail, so this tries to be conservative. */
810 limit_kbytes = MAX (0, limit_kbytes - MAX (limit_kbytes / 4, 20 * 1024));
a9429e29 811 limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic ());
d37e6b50
GK
812 phys_kbytes = MIN (phys_kbytes, limit_kbytes);
813
814 phys_kbytes = MAX (phys_kbytes, 4 * 1024);
815 phys_kbytes = MIN (phys_kbytes, 128 * 1024);
9ac121af 816
d37e6b50 817 return phys_kbytes;
9ac121af 818}
e4dfaf72 819#endif
9ac121af
KG
820
821void
20c1dc5e 822init_ggc_heuristics (void)
9ac121af 823{
d85a0aae 824#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT
128dc8e2
JM
825 set_default_param_value (GGC_MIN_EXPAND, ggc_min_expand_heuristic ());
826 set_default_param_value (GGC_MIN_HEAPSIZE, ggc_min_heapsize_heuristic ());
9ac121af
KG
827#endif
828}
b9dcdee4 829
2d44c7de
ML
830/* GGC memory usage. */
831struct ggc_usage: public mem_usage
b9dcdee4 832{
2d44c7de
ML
833 /* Default constructor. */
834 ggc_usage (): m_freed (0), m_collected (0), m_overhead (0) {}
835 /* Constructor. */
836 ggc_usage (size_t allocated, size_t times, size_t peak,
837 size_t freed, size_t collected, size_t overhead)
838 : mem_usage (allocated, times, peak),
839 m_freed (freed), m_collected (collected), m_overhead (overhead) {}
b9dcdee4 840
2d44c7de 841 /* Comparison operator. */
80a4fe78
ML
842 inline bool
843 operator< (const ggc_usage &second) const
2d44c7de
ML
844 {
845 return (get_balance () == second.get_balance () ?
846 (m_peak == second.m_peak ? m_times < second.m_times
847 : m_peak < second.m_peak)
848 : get_balance () < second.get_balance ());
849 }
b9dcdee4 850
2d44c7de 851 /* Register overhead of ALLOCATED and OVERHEAD bytes. */
80a4fe78
ML
852 inline void
853 register_overhead (size_t allocated, size_t overhead)
2d44c7de
ML
854 {
855 m_allocated += allocated;
856 m_overhead += overhead;
857 m_times++;
858 }
b9dcdee4 859
2d44c7de 860 /* Release overhead of SIZE bytes. */
80a4fe78
ML
861 inline void
862 release_overhead (size_t size)
2d44c7de
ML
863 {
864 m_freed += size;
865 }
b9dcdee4 866
2d44c7de 867 /* Sum the usage with SECOND usage. */
80a4fe78
ML
868 ggc_usage
869 operator+ (const ggc_usage &second)
2d44c7de
ML
870 {
871 return ggc_usage (m_allocated + second.m_allocated,
872 m_times + second.m_times,
873 m_peak + second.m_peak,
874 m_freed + second.m_freed,
875 m_collected + second.m_collected,
876 m_overhead + second.m_overhead);
877 }
b9dcdee4 878
2d44c7de 879 /* Dump usage with PREFIX, where TOTAL is sum of all rows. */
80a4fe78
ML
880 inline void
881 dump (const char *prefix, ggc_usage &total) const
2d44c7de
ML
882 {
883 long balance = get_balance ();
884 fprintf (stderr,
885 "%-48s %10li:%5.1f%%%10li:%5.1f%%"
886 "%10li:%5.1f%%%10li:%5.1f%%%10li\n",
887 prefix, (long)m_collected,
888 get_percent (m_collected, total.m_collected),
889 (long)m_freed, get_percent (m_freed, total.m_freed),
890 (long)balance, get_percent (balance, total.get_balance ()),
891 (long)m_overhead, get_percent (m_overhead, total.m_overhead),
892 (long)m_times);
893 }
4a8fb1a1 894
2d44c7de 895 /* Dump usage coupled to LOC location, where TOTAL is sum of all rows. */
80a4fe78
ML
896 inline void
897 dump (mem_location *loc, ggc_usage &total) const
2d44c7de 898 {
ac059261 899 char *location_string = loc->to_string ();
07724022 900
ac059261
ML
901 dump (location_string, total);
902
903 free (location_string);
2d44c7de 904 }
4a8fb1a1 905
2d44c7de 906 /* Dump footer. */
80a4fe78
ML
907 inline void
908 dump_footer ()
2d44c7de
ML
909 {
910 print_dash_line ();
911 dump ("Total", *this);
912 print_dash_line ();
913 }
07724022 914
2d44c7de 915 /* Get balance which is GGC allocation leak. */
80a4fe78
ML
916 inline long
917 get_balance () const
2d44c7de
ML
918 {
919 return m_allocated + m_overhead - m_collected - m_freed;
920 }
07724022 921
2d44c7de 922 typedef std::pair<mem_location *, ggc_usage *> mem_pair_t;
07724022 923
2d44c7de 924 /* Compare wrapper used by qsort method. */
80a4fe78
ML
925 static int
926 compare (const void *first, const void *second)
2d44c7de
ML
927 {
928 const mem_pair_t f = *(const mem_pair_t *)first;
929 const mem_pair_t s = *(const mem_pair_t *)second;
4a8fb1a1 930
2d44c7de
ML
931 return (*f.second) < (*s.second);
932 }
933
934 /* Compare rows in final GGC summary dump. */
80a4fe78
ML
935 static int
936 compare_final (const void *first, const void *second)
937 {
938 typedef std::pair<mem_location *, ggc_usage *> mem_pair_t;
2d44c7de
ML
939
940 const ggc_usage *f = ((const mem_pair_t *)first)->second;
941 const ggc_usage *s = ((const mem_pair_t *)second)->second;
942
943 size_t a = f->m_allocated + f->m_overhead - f->m_freed;
944 size_t b = s->m_allocated + s->m_overhead - s->m_freed;
945
946 return a == b ? 0 : (a < b ? 1 : -1);
947 }
948
949 /* Dump header with NAME. */
80a4fe78
ML
950 static inline void
951 dump_header (const char *name)
2d44c7de
ML
952 {
953 fprintf (stderr, "%-48s %11s%17s%17s%16s%17s\n", name, "Garbage", "Freed",
954 "Leak", "Overhead", "Times");
955 print_dash_line ();
956 }
957
958 /* Freed memory in bytes. */
959 size_t m_freed;
960 /* Collected memory in bytes. */
961 size_t m_collected;
962 /* Overhead memory in bytes. */
963 size_t m_overhead;
964};
965
966/* GCC memory description. */
967static mem_alloc_description<ggc_usage> ggc_mem_desc;
968
969/* Dump per-site memory statistics. */
b9dcdee4 970
d1a6adeb 971void
2d44c7de 972dump_ggc_loc_statistics (bool final)
b9dcdee4 973{
2d44c7de
ML
974 if (! GATHER_STATISTICS)
975 return;
b9dcdee4 976
2d44c7de
ML
977 ggc_force_collect = true;
978 ggc_collect ();
979
643e0a30 980 ggc_mem_desc.dump (GGC_ORIGIN, final ? ggc_usage::compare_final : NULL);
2d44c7de
ML
981
982 ggc_force_collect = false;
07724022
JH
983}
984
2d44c7de 985/* Record ALLOCATED and OVERHEAD bytes to descriptor NAME:LINE (FUNCTION). */
07724022 986void
2d44c7de 987ggc_record_overhead (size_t allocated, size_t overhead, void *ptr MEM_STAT_DECL)
07724022 988{
643e0a30 989 ggc_usage *usage = ggc_mem_desc.register_descriptor (ptr, GGC_ORIGIN, false
2d44c7de
ML
990 FINAL_PASS_MEM_STAT);
991
992 ggc_mem_desc.register_object_overhead (usage, allocated + overhead, ptr);
993 usage->register_overhead (allocated, overhead);
07724022
JH
994}
995
996/* Notice that the pointer has been freed. */
83f676b3
RS
997void
998ggc_free_overhead (void *ptr)
07724022 999{
2d44c7de 1000 ggc_mem_desc.release_object_overhead (ptr);
a5573239
JH
1001}
1002
2d44c7de
ML
1003/* After live values has been marked, walk all recorded pointers and see if
1004 they are still live. */
83f676b3 1005void
2d44c7de 1006ggc_prune_overhead_list (void)
b9dcdee4 1007{
2d44c7de 1008 typedef hash_map<const void *, std::pair<ggc_usage *, size_t > > map_t;
b9dcdee4 1009
2d44c7de 1010 map_t::iterator it = ggc_mem_desc.m_reverse_object_map->begin ();
7aa6d18a 1011
2d44c7de
ML
1012 for (; it != ggc_mem_desc.m_reverse_object_map->end (); ++it)
1013 if (!ggc_marked_p ((*it).first))
1014 (*it).second.first->m_collected += (*it).second.second;
07724022 1015
2d44c7de
ML
1016 delete ggc_mem_desc.m_reverse_object_map;
1017 ggc_mem_desc.m_reverse_object_map = new map_t (13, false, false);
b9dcdee4 1018}
This page took 4.763327 seconds and 5 git commands to generate.