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