Mercurial > hg > CbC > CbC_gcc
comparison gcc/ggc-common.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Simple garbage collection for the GNU compiler. | 1 /* Simple garbage collection for the GNU compiler. |
2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 | 2 Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, |
3 Free Software Foundation, Inc. | 3 2009, 2010 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 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 | 8 the terms of the GNU General Public License as published by the Free |
24 #include "config.h" | 24 #include "config.h" |
25 #include "system.h" | 25 #include "system.h" |
26 #include "coretypes.h" | 26 #include "coretypes.h" |
27 #include "hashtab.h" | 27 #include "hashtab.h" |
28 #include "ggc.h" | 28 #include "ggc.h" |
29 #include "toplev.h" | 29 #include "ggc-internal.h" |
30 #include "diagnostic-core.h" | |
30 #include "params.h" | 31 #include "params.h" |
31 #include "hosthooks.h" | 32 #include "hosthooks.h" |
32 #include "hosthooks-def.h" | 33 #include "hosthooks-def.h" |
33 #include "plugin.h" | 34 #include "plugin.h" |
34 #include "vec.h" | 35 #include "vec.h" |
35 #include "timevar.h" | 36 #include "timevar.h" |
36 | |
37 #ifdef HAVE_SYS_RESOURCE_H | |
38 # include <sys/resource.h> | |
39 #endif | |
40 | |
41 #ifdef HAVE_MMAP_FILE | |
42 # include <sys/mman.h> | |
43 # ifdef HAVE_MINCORE | |
44 /* This is on Solaris. */ | |
45 # include <sys/types.h> | |
46 # endif | |
47 #endif | |
48 | |
49 #ifndef MAP_FAILED | |
50 # define MAP_FAILED ((void *)-1) | |
51 #endif | |
52 | 37 |
53 /* When set, ggc_collect will do collection. */ | 38 /* When set, ggc_collect will do collection. */ |
54 bool ggc_force_collect; | 39 bool ggc_force_collect; |
55 | 40 |
56 /* When true, protect the contents of the identifier hash table. */ | 41 /* When true, protect the contents of the identifier hash table. */ |
68 static int call_alloc (void **, void *); | 53 static int call_alloc (void **, void *); |
69 static int compare_ptr_data (const void *, const void *); | 54 static int compare_ptr_data (const void *, const void *); |
70 static void relocate_ptrs (void *, void *); | 55 static void relocate_ptrs (void *, void *); |
71 static void write_pch_globals (const struct ggc_root_tab * const *tab, | 56 static void write_pch_globals (const struct ggc_root_tab * const *tab, |
72 struct traversal_state *state); | 57 struct traversal_state *state); |
73 static double ggc_rlimit_bound (double); | |
74 | 58 |
75 /* Maintain global roots that are preserved during GC. */ | 59 /* Maintain global roots that are preserved during GC. */ |
76 | 60 |
77 /* Process a slot of an htab by deleting it if it has not been marked. */ | 61 /* Process a slot of an htab by deleting it if it has not been marked. */ |
78 | 62 |
144 CONST_CAST (void *, (const void *)cti)); | 128 CONST_CAST (void *, (const void *)cti)); |
145 ggc_set_mark ((*cti->base)->entries); | 129 ggc_set_mark ((*cti->base)->entries); |
146 } | 130 } |
147 } | 131 } |
148 | 132 |
133 /* Mark all the roots in the table RT. */ | |
134 | |
135 static void | |
136 ggc_mark_root_tab (const_ggc_root_tab_t rt) | |
137 { | |
138 size_t i; | |
139 | |
140 for ( ; rt->base != NULL; rt++) | |
141 for (i = 0; i < rt->nelt; i++) | |
142 (*rt->cb) (*(void **) ((char *)rt->base + rt->stride * i)); | |
143 } | |
144 | |
149 /* Iterate through all registered roots and mark each element. */ | 145 /* Iterate through all registered roots and mark each element. */ |
150 | 146 |
151 void | 147 void |
152 ggc_mark_roots (void) | 148 ggc_mark_roots (void) |
153 { | 149 { |
154 const struct ggc_root_tab *const *rt; | 150 const struct ggc_root_tab *const *rt; |
155 const struct ggc_root_tab *rti; | 151 const_ggc_root_tab_t rtp, rti; |
156 const_ggc_root_tab_t rtp; | |
157 const struct ggc_cache_tab *const *ct; | 152 const struct ggc_cache_tab *const *ct; |
158 const_ggc_cache_tab_t ctp; | 153 const_ggc_cache_tab_t ctp; |
159 size_t i; | 154 size_t i; |
160 | 155 |
161 for (rt = gt_ggc_deletable_rtab; *rt; rt++) | 156 for (rt = gt_ggc_deletable_rtab; *rt; rt++) |
162 for (rti = *rt; rti->base != NULL; rti++) | 157 for (rti = *rt; rti->base != NULL; rti++) |
163 memset (rti->base, 0, rti->stride); | 158 memset (rti->base, 0, rti->stride); |
164 | 159 |
165 for (rt = gt_ggc_rtab; *rt; rt++) | 160 for (rt = gt_ggc_rtab; *rt; rt++) |
166 for (rti = *rt; rti->base != NULL; rti++) | 161 ggc_mark_root_tab (*rt); |
167 for (i = 0; i < rti->nelt; i++) | 162 |
168 (*rti->cb) (*(void **)((char *)rti->base + rti->stride * i)); | 163 FOR_EACH_VEC_ELT (const_ggc_root_tab_t, extra_root_vec, i, rtp) |
169 | 164 ggc_mark_root_tab (rtp); |
170 for (i = 0; VEC_iterate (const_ggc_root_tab_t, extra_root_vec, i, rtp); i++) | |
171 { | |
172 for (rti = rtp; rti->base != NULL; rti++) | |
173 for (i = 0; i < rti->nelt; i++) | |
174 (*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i)); | |
175 } | |
176 | 165 |
177 if (ggc_protect_identifiers) | 166 if (ggc_protect_identifiers) |
178 ggc_mark_stringpool (); | 167 ggc_mark_stringpool (); |
179 | 168 |
180 /* Now scan all hash tables that have objects which are to be deleted if | 169 /* Now scan all hash tables that have objects which are to be deleted if |
181 they are not already marked. */ | 170 they are not already marked. */ |
182 for (ct = gt_ggc_cache_rtab; *ct; ct++) | 171 for (ct = gt_ggc_cache_rtab; *ct; ct++) |
183 ggc_scan_cache_tab (*ct); | 172 ggc_scan_cache_tab (*ct); |
184 | 173 |
185 for (i = 0; VEC_iterate (const_ggc_cache_tab_t, extra_cache_vec, i, ctp); i++) | 174 FOR_EACH_VEC_ELT (const_ggc_cache_tab_t, extra_cache_vec, i, ctp) |
186 ggc_scan_cache_tab (ctp); | 175 ggc_scan_cache_tab (ctp); |
187 | 176 |
188 if (! ggc_protect_identifiers) | 177 if (! ggc_protect_identifiers) |
189 ggc_purge_stringpool (); | 178 ggc_purge_stringpool (); |
190 | 179 |
192 invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL); | 181 invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL); |
193 } | 182 } |
194 | 183 |
195 /* Allocate a block of memory, then clear it. */ | 184 /* Allocate a block of memory, then clear it. */ |
196 void * | 185 void * |
197 ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL) | 186 ggc_internal_cleared_alloc_stat (size_t size MEM_STAT_DECL) |
198 { | 187 { |
199 void *buf = ggc_alloc_stat (size PASS_MEM_STAT); | 188 void *buf = ggc_internal_alloc_stat (size PASS_MEM_STAT); |
200 memset (buf, 0, size); | 189 memset (buf, 0, size); |
201 return buf; | 190 return buf; |
202 } | 191 } |
203 | 192 |
204 /* Resize a block of memory, possibly re-allocating it. */ | 193 /* Resize a block of memory, possibly re-allocating it. */ |
207 { | 196 { |
208 void *r; | 197 void *r; |
209 size_t old_size; | 198 size_t old_size; |
210 | 199 |
211 if (x == NULL) | 200 if (x == NULL) |
212 return ggc_alloc_stat (size PASS_MEM_STAT); | 201 return ggc_internal_alloc_stat (size PASS_MEM_STAT); |
213 | 202 |
214 old_size = ggc_get_size (x); | 203 old_size = ggc_get_size (x); |
215 | 204 |
216 if (size <= old_size) | 205 if (size <= old_size) |
217 { | 206 { |
229 old_size - size)); | 218 old_size - size)); |
230 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (x, size)); | 219 VALGRIND_DISCARD (VALGRIND_MAKE_MEM_DEFINED (x, size)); |
231 return x; | 220 return x; |
232 } | 221 } |
233 | 222 |
234 r = ggc_alloc_stat (size PASS_MEM_STAT); | 223 r = ggc_internal_alloc_stat (size PASS_MEM_STAT); |
235 | 224 |
236 /* Since ggc_get_size returns the size of the pool, not the size of the | 225 /* Since ggc_get_size returns the size of the pool, not the size of the |
237 individually allocated object, we'd access parts of the old object | 226 individually allocated object, we'd access parts of the old object |
238 that were marked invalid with the memcpy below. We lose a bit of the | 227 that were marked invalid with the memcpy below. We lose a bit of the |
239 initialization-tracking since some of it may be uninitialized. */ | 228 initialization-tracking since some of it may be uninitialized. */ |
245 ggc_free (x); | 234 ggc_free (x); |
246 | 235 |
247 return r; | 236 return r; |
248 } | 237 } |
249 | 238 |
250 /* Like ggc_alloc_cleared, but performs a multiplication. */ | |
251 void * | 239 void * |
252 ggc_calloc (size_t s1, size_t s2) | 240 ggc_cleared_alloc_htab_ignore_args (size_t c ATTRIBUTE_UNUSED, |
253 { | 241 size_t n ATTRIBUTE_UNUSED) |
254 return ggc_alloc_cleared (s1 * s2); | 242 { |
243 gcc_assert (c * n == sizeof (struct htab)); | |
244 return ggc_alloc_cleared_htab (); | |
245 } | |
246 | |
247 /* TODO: once we actually use type information in GGC, create a new tag | |
248 gt_gcc_ptr_array and use it for pointer arrays. */ | |
249 void * | |
250 ggc_cleared_alloc_ptr_array_two_args (size_t c, size_t n) | |
251 { | |
252 gcc_assert (sizeof (PTR *) == n); | |
253 return ggc_internal_cleared_vec_alloc (sizeof (PTR *), c); | |
255 } | 254 } |
256 | 255 |
257 /* These are for splay_tree_new_ggc. */ | 256 /* These are for splay_tree_new_ggc. */ |
258 void * | 257 void * |
259 ggc_splay_alloc (int sz, void *nl) | 258 ggc_splay_alloc (enum gt_types_enum obj_type ATTRIBUTE_UNUSED, int sz, |
259 void *nl) | |
260 { | 260 { |
261 gcc_assert (!nl); | 261 gcc_assert (!nl); |
262 return ggc_alloc (sz); | 262 return ggc_internal_alloc (sz); |
263 } | 263 } |
264 | 264 |
265 void | 265 void |
266 ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl) | 266 ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl) |
267 { | 267 { |
462 struct ptr_data *new_ptr; | 462 struct ptr_data *new_ptr; |
463 if (ptr == NULL || ptr == (void *)1) | 463 if (ptr == NULL || ptr == (void *)1) |
464 { | 464 { |
465 if (fwrite (&ptr, sizeof (void *), 1, state->f) | 465 if (fwrite (&ptr, sizeof (void *), 1, state->f) |
466 != 1) | 466 != 1) |
467 fatal_error ("can't write PCH file: %m"); | 467 fatal_error ("can%'t write PCH file: %m"); |
468 } | 468 } |
469 else | 469 else |
470 { | 470 { |
471 new_ptr = (struct ptr_data *) | 471 new_ptr = (struct ptr_data *) |
472 htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr)); | 472 htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr)); |
473 if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f) | 473 if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f) |
474 != 1) | 474 != 1) |
475 fatal_error ("can't write PCH file: %m"); | 475 fatal_error ("can%'t write PCH file: %m"); |
476 } | 476 } |
477 } | 477 } |
478 } | 478 } |
479 | 479 |
480 /* Hold the information we need to mmap the file back in. */ | 480 /* Hold the information we need to mmap the file back in. */ |
515 for (i = 0; i < rti->nelt; i++) | 515 for (i = 0; i < rti->nelt; i++) |
516 (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i)); | 516 (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i)); |
517 | 517 |
518 /* Prepare the objects for writing, determine addresses and such. */ | 518 /* Prepare the objects for writing, determine addresses and such. */ |
519 state.f = f; | 519 state.f = f; |
520 state.d = init_ggc_pch(); | 520 state.d = init_ggc_pch (); |
521 state.count = 0; | 521 state.count = 0; |
522 htab_traverse (saving_htab, call_count, &state); | 522 htab_traverse (saving_htab, call_count, &state); |
523 | 523 |
524 mmi.size = ggc_pch_total_size (state.d); | 524 mmi.size = ggc_pch_total_size (state.d); |
525 | 525 |
544 | 544 |
545 /* Write out all the scalar variables. */ | 545 /* Write out all the scalar variables. */ |
546 for (rt = gt_pch_scalar_rtab; *rt; rt++) | 546 for (rt = gt_pch_scalar_rtab; *rt; rt++) |
547 for (rti = *rt; rti->base != NULL; rti++) | 547 for (rti = *rt; rti->base != NULL; rti++) |
548 if (fwrite (rti->base, rti->stride, 1, f) != 1) | 548 if (fwrite (rti->base, rti->stride, 1, f) != 1) |
549 fatal_error ("can't write PCH file: %m"); | 549 fatal_error ("can%'t write PCH file: %m"); |
550 | 550 |
551 /* Write out all the global pointers, after translation. */ | 551 /* Write out all the global pointers, after translation. */ |
552 write_pch_globals (gt_ggc_rtab, &state); | 552 write_pch_globals (gt_ggc_rtab, &state); |
553 write_pch_globals (gt_pch_cache_rtab, &state); | 553 write_pch_globals (gt_pch_cache_rtab, &state); |
554 | 554 |
556 granularity (usually page) boundary. */ | 556 granularity (usually page) boundary. */ |
557 { | 557 { |
558 long o; | 558 long o; |
559 o = ftell (state.f) + sizeof (mmi); | 559 o = ftell (state.f) + sizeof (mmi); |
560 if (o == -1) | 560 if (o == -1) |
561 fatal_error ("can't get position in PCH file: %m"); | 561 fatal_error ("can%'t get position in PCH file: %m"); |
562 mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment; | 562 mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment; |
563 if (mmi.offset == mmap_offset_alignment) | 563 if (mmi.offset == mmap_offset_alignment) |
564 mmi.offset = 0; | 564 mmi.offset = 0; |
565 mmi.offset += o; | 565 mmi.offset += o; |
566 } | 566 } |
567 if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1) | 567 if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1) |
568 fatal_error ("can't write PCH file: %m"); | 568 fatal_error ("can%'t write PCH file: %m"); |
569 if (mmi.offset != 0 | 569 if (mmi.offset != 0 |
570 && fseek (state.f, mmi.offset, SEEK_SET) != 0) | 570 && fseek (state.f, mmi.offset, SEEK_SET) != 0) |
571 fatal_error ("can't write padding to PCH file: %m"); | 571 fatal_error ("can%'t write padding to PCH file: %m"); |
572 | 572 |
573 ggc_pch_prepare_write (state.d, state.f); | 573 ggc_pch_prepare_write (state.d, state.f); |
574 | 574 |
575 /* Actually write out the objects. */ | 575 /* Actually write out the objects. */ |
576 for (i = 0; i < state.count; i++) | 576 for (i = 0; i < state.count; i++) |
621 | 621 |
622 /* Read in all the scalar variables. */ | 622 /* Read in all the scalar variables. */ |
623 for (rt = gt_pch_scalar_rtab; *rt; rt++) | 623 for (rt = gt_pch_scalar_rtab; *rt; rt++) |
624 for (rti = *rt; rti->base != NULL; rti++) | 624 for (rti = *rt; rti->base != NULL; rti++) |
625 if (fread (rti->base, rti->stride, 1, f) != 1) | 625 if (fread (rti->base, rti->stride, 1, f) != 1) |
626 fatal_error ("can't read PCH file: %m"); | 626 fatal_error ("can%'t read PCH file: %m"); |
627 | 627 |
628 /* Read in all the global pointers, in 6 easy loops. */ | 628 /* Read in all the global pointers, in 6 easy loops. */ |
629 for (rt = gt_ggc_rtab; *rt; rt++) | 629 for (rt = gt_ggc_rtab; *rt; rt++) |
630 for (rti = *rt; rti->base != NULL; rti++) | 630 for (rti = *rt; rti->base != NULL; rti++) |
631 for (i = 0; i < rti->nelt; i++) | 631 for (i = 0; i < rti->nelt; i++) |
632 if (fread ((char *)rti->base + rti->stride * i, | 632 if (fread ((char *)rti->base + rti->stride * i, |
633 sizeof (void *), 1, f) != 1) | 633 sizeof (void *), 1, f) != 1) |
634 fatal_error ("can't read PCH file: %m"); | 634 fatal_error ("can%'t read PCH file: %m"); |
635 | 635 |
636 for (rt = gt_pch_cache_rtab; *rt; rt++) | 636 for (rt = gt_pch_cache_rtab; *rt; rt++) |
637 for (rti = *rt; rti->base != NULL; rti++) | 637 for (rti = *rt; rti->base != NULL; rti++) |
638 for (i = 0; i < rti->nelt; i++) | 638 for (i = 0; i < rti->nelt; i++) |
639 if (fread ((char *)rti->base + rti->stride * i, | 639 if (fread ((char *)rti->base + rti->stride * i, |
640 sizeof (void *), 1, f) != 1) | 640 sizeof (void *), 1, f) != 1) |
641 fatal_error ("can't read PCH file: %m"); | 641 fatal_error ("can%'t read PCH file: %m"); |
642 | 642 |
643 if (fread (&mmi, sizeof (mmi), 1, f) != 1) | 643 if (fread (&mmi, sizeof (mmi), 1, f) != 1) |
644 fatal_error ("can't read PCH file: %m"); | 644 fatal_error ("can%'t read PCH file: %m"); |
645 | 645 |
646 result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size, | 646 result = host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size, |
647 fileno (f), mmi.offset); | 647 fileno (f), mmi.offset); |
648 if (result < 0) | 648 if (result < 0) |
649 fatal_error ("had to relocate PCH"); | 649 fatal_error ("had to relocate PCH"); |
650 if (result == 0) | 650 if (result == 0) |
651 { | 651 { |
652 if (fseek (f, mmi.offset, SEEK_SET) != 0 | 652 if (fseek (f, mmi.offset, SEEK_SET) != 0 |
653 || fread (mmi.preferred_base, mmi.size, 1, f) != 1) | 653 || fread (mmi.preferred_base, mmi.size, 1, f) != 1) |
654 fatal_error ("can't read PCH file: %m"); | 654 fatal_error ("can%'t read PCH file: %m"); |
655 } | 655 } |
656 else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0) | 656 else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0) |
657 fatal_error ("can't read PCH file: %m"); | 657 fatal_error ("can%'t read PCH file: %m"); |
658 | 658 |
659 ggc_pch_read (f, mmi.preferred_base); | 659 ggc_pch_read (f, mmi.preferred_base); |
660 | 660 |
661 gt_pch_restore_stringpool (); | 661 gt_pch_restore_stringpool (); |
662 } | 662 } |
739 fd, offset); | 739 fd, offset); |
740 | 740 |
741 return addr == base ? 1 : -1; | 741 return addr == base ? 1 : -1; |
742 } | 742 } |
743 #endif /* HAVE_MMAP_FILE */ | 743 #endif /* HAVE_MMAP_FILE */ |
744 | |
745 #if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT | |
744 | 746 |
745 /* Modify the bound based on rlimits. */ | 747 /* Modify the bound based on rlimits. */ |
746 static double | 748 static double |
747 ggc_rlimit_bound (double limit) | 749 ggc_rlimit_bound (double limit) |
748 { | 750 { |
774 | 776 |
775 return limit; | 777 return limit; |
776 } | 778 } |
777 | 779 |
778 /* Heuristic to set a default for GGC_MIN_EXPAND. */ | 780 /* Heuristic to set a default for GGC_MIN_EXPAND. */ |
779 int | 781 static int |
780 ggc_min_expand_heuristic (void) | 782 ggc_min_expand_heuristic (void) |
781 { | 783 { |
782 double min_expand = physmem_total(); | 784 double min_expand = physmem_total(); |
783 | 785 |
784 /* Adjust for rlimits. */ | 786 /* Adjust for rlimits. */ |
793 | 795 |
794 return min_expand; | 796 return min_expand; |
795 } | 797 } |
796 | 798 |
797 /* Heuristic to set a default for GGC_MIN_HEAPSIZE. */ | 799 /* Heuristic to set a default for GGC_MIN_HEAPSIZE. */ |
798 int | 800 static int |
799 ggc_min_heapsize_heuristic (void) | 801 ggc_min_heapsize_heuristic (void) |
800 { | 802 { |
801 double phys_kbytes = physmem_total(); | 803 double phys_kbytes = physmem_total(); |
802 double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2); | 804 double limit_kbytes = ggc_rlimit_bound (phys_kbytes * 2); |
803 | 805 |
822 /* Don't blindly run over our data limit; do GC at least when the | 824 /* Don't blindly run over our data limit; do GC at least when the |
823 *next* GC would be within 20Mb of the limit or within a quarter of | 825 *next* GC would be within 20Mb of the limit or within a quarter of |
824 the limit, whichever is larger. If GCC does hit the data limit, | 826 the limit, whichever is larger. If GCC does hit the data limit, |
825 compilation will fail, so this tries to be conservative. */ | 827 compilation will fail, so this tries to be conservative. */ |
826 limit_kbytes = MAX (0, limit_kbytes - MAX (limit_kbytes / 4, 20 * 1024)); | 828 limit_kbytes = MAX (0, limit_kbytes - MAX (limit_kbytes / 4, 20 * 1024)); |
827 limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic()); | 829 limit_kbytes = (limit_kbytes * 100) / (110 + ggc_min_expand_heuristic ()); |
828 phys_kbytes = MIN (phys_kbytes, limit_kbytes); | 830 phys_kbytes = MIN (phys_kbytes, limit_kbytes); |
829 | 831 |
830 phys_kbytes = MAX (phys_kbytes, 4 * 1024); | 832 phys_kbytes = MAX (phys_kbytes, 4 * 1024); |
831 phys_kbytes = MIN (phys_kbytes, 128 * 1024); | 833 phys_kbytes = MIN (phys_kbytes, 128 * 1024); |
832 | 834 |
833 return phys_kbytes; | 835 return phys_kbytes; |
834 } | 836 } |
837 #endif | |
835 | 838 |
836 void | 839 void |
837 init_ggc_heuristics (void) | 840 init_ggc_heuristics (void) |
838 { | 841 { |
839 #if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT | 842 #if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT |
840 set_param_value ("ggc-min-expand", ggc_min_expand_heuristic()); | 843 set_default_param_value (GGC_MIN_EXPAND, ggc_min_expand_heuristic ()); |
841 set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic()); | 844 set_default_param_value (GGC_MIN_HEAPSIZE, ggc_min_heapsize_heuristic ()); |
842 #endif | 845 #endif |
843 } | 846 } |
844 | 847 |
845 #ifdef GATHER_STATISTICS | 848 #ifdef GATHER_STATISTICS |
846 | 849 |
978 void | 981 void |
979 ggc_free_overhead (void *ptr) | 982 ggc_free_overhead (void *ptr) |
980 { | 983 { |
981 PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), | 984 PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), |
982 NO_INSERT); | 985 NO_INSERT); |
983 struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot; | 986 struct ptr_hash_entry *p; |
987 /* The pointer might be not found if a PCH read happened between allocation | |
988 and ggc_free () call. FIXME: account memory properly in the presence of | |
989 PCH. */ | |
990 if (!slot) | |
991 return; | |
992 p = (struct ptr_hash_entry *) *slot; | |
984 p->loc->freed += p->size; | 993 p->loc->freed += p->size; |
985 htab_clear_slot (ptr_hash, slot); | 994 htab_clear_slot (ptr_hash, slot); |
986 free (p); | 995 free (p); |
987 } | 996 } |
988 | 997 |