X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fggc-common.c;h=28c2b793f22d605d2a06349d8896cca5421b2b3f;hb=485e90919e0fb95cd148aa1dc43000aeb68abc2e;hp=17c1f50b608fc82d81f3a9e0eb028da3283b1a61;hpb=dfecde36dddd77b80db5b9848187ad3f982960ba;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 17c1f50b608..28c2b793f22 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -30,6 +30,9 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "hosthooks.h" #include "hosthooks-def.h" +#include "plugin.h" +#include "vec.h" +#include "timevar.h" #ifdef HAVE_SYS_RESOURCE_H # include @@ -39,7 +42,7 @@ along with GCC; see the file COPYING3. If not see # include # ifdef HAVE_MINCORE /* This is on Solaris. */ -# include +# include # endif #endif @@ -86,6 +89,63 @@ ggc_htab_delete (void **slot, void *info) return 1; } + +/* This extra vector of dynamically registered root_tab-s is used by + ggc_mark_roots and gives the ability to dynamically add new GGC root + tables, for instance from some plugins; this vector is on the heap + since it is used by GGC internally. */ +typedef const struct ggc_root_tab *const_ggc_root_tab_t; +DEF_VEC_P(const_ggc_root_tab_t); +DEF_VEC_ALLOC_P(const_ggc_root_tab_t, heap); +static VEC(const_ggc_root_tab_t, heap) *extra_root_vec; + +/* Dynamically register a new GGC root table RT. This is useful for + plugins. */ + +void +ggc_register_root_tab (const struct ggc_root_tab* rt) +{ + if (rt) + VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt); +} + +/* This extra vector of dynamically registered cache_tab-s is used by + ggc_mark_roots and gives the ability to dynamically add new GGC cache + tables, for instance from some plugins; this vector is on the heap + since it is used by GGC internally. */ +typedef const struct ggc_cache_tab *const_ggc_cache_tab_t; +DEF_VEC_P(const_ggc_cache_tab_t); +DEF_VEC_ALLOC_P(const_ggc_cache_tab_t, heap); +static VEC(const_ggc_cache_tab_t, heap) *extra_cache_vec; + +/* Dynamically register a new GGC cache table CT. This is useful for + plugins. */ + +void +ggc_register_cache_tab (const struct ggc_cache_tab* ct) +{ + if (ct) + VEC_safe_push (const_ggc_cache_tab_t, heap, extra_cache_vec, ct); +} + +/* Scan a hash table that has objects which are to be deleted if they are not + already marked. */ + +static void +ggc_scan_cache_tab (const_ggc_cache_tab_t ctp) +{ + const struct ggc_cache_tab *cti; + + for (cti = ctp; cti->base != NULL; cti++) + if (*cti->base) + { + ggc_set_mark (*cti->base); + htab_traverse_noresize (*cti->base, ggc_htab_delete, + CONST_CAST (void *, (const void *)cti)); + ggc_set_mark ((*cti->base)->entries); + } +} + /* Iterate through all registered roots and mark each element. */ void @@ -93,8 +153,9 @@ ggc_mark_roots (void) { const struct ggc_root_tab *const *rt; const struct ggc_root_tab *rti; + const_ggc_root_tab_t rtp; const struct ggc_cache_tab *const *ct; - const struct ggc_cache_tab *cti; + const_ggc_cache_tab_t ctp; size_t i; for (rt = gt_ggc_deletable_rtab; *rt; rt++) @@ -104,7 +165,14 @@ ggc_mark_roots (void) for (rt = gt_ggc_rtab; *rt; rt++) for (rti = *rt; rti->base != NULL; rti++) for (i = 0; i < rti->nelt; i++) - (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i)); + (*rti->cb) (*(void **)((char *)rti->base + rti->stride * i)); + + for (i = 0; VEC_iterate (const_ggc_root_tab_t, extra_root_vec, i, rtp); i++) + { + for (rti = rtp; rti->base != NULL; rti++) + for (i = 0; i < rti->nelt; i++) + (*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i)); + } if (ggc_protect_identifiers) ggc_mark_stringpool (); @@ -112,16 +180,16 @@ ggc_mark_roots (void) /* Now scan all hash tables that have objects which are to be deleted if they are not already marked. */ for (ct = gt_ggc_cache_rtab; *ct; ct++) - for (cti = *ct; cti->base != NULL; cti++) - if (*cti->base) - { - ggc_set_mark (*cti->base); - htab_traverse_noresize (*cti->base, ggc_htab_delete, (void *) cti); - ggc_set_mark ((*cti->base)->entries); - } + ggc_scan_cache_tab (*ct); + + for (i = 0; VEC_iterate (const_ggc_cache_tab_t, extra_cache_vec, i, ctp); i++) + ggc_scan_cache_tab (ctp); if (! ggc_protect_identifiers) ggc_purge_stringpool (); + + /* Some plugins may call ggc_set_mark from here. */ + invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL); } /* Allocate a block of memory, then clear it. */ @@ -264,12 +332,12 @@ gt_pch_note_object (void *obj, void *note_ptr_cookie, return 0; } - *slot = xcalloc (sizeof (struct ptr_data), 1); + *slot = XCNEW (struct ptr_data); (*slot)->obj = obj; (*slot)->note_ptr_fn = note_ptr_fn; (*slot)->note_ptr_cookie = note_ptr_cookie; if (note_ptr_fn == gt_pch_p_S) - (*slot)->size = strlen (obj) + 1; + (*slot)->size = strlen ((const char *)obj) + 1; else (*slot)->size = ggc_get_size (obj); (*slot)->type = type; @@ -287,7 +355,8 @@ gt_pch_note_reorder (void *obj, void *note_ptr_cookie, if (obj == NULL || obj == (void *) 1) return; - data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj)); + data = (struct ptr_data *) + htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj)); gcc_assert (data && data->note_ptr_cookie == note_ptr_cookie); data->reorder_fn = reorder_fn; @@ -370,7 +439,8 @@ relocate_ptrs (void *ptr_p, void *state_p) if (*ptr == NULL || *ptr == (void *)1) return; - result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr)); + result = (struct ptr_data *) + htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr)); gcc_assert (result); *ptr = result->new_addr; } @@ -398,8 +468,8 @@ write_pch_globals (const struct ggc_root_tab * const *tab, } else { - new_ptr = htab_find_with_hash (saving_htab, ptr, - POINTER_HASH (ptr)); + new_ptr = (struct ptr_data *) + htab_find_with_hash (saving_htab, ptr, POINTER_HASH (ptr)); if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f) != 1) fatal_error ("can't write PCH file: %m"); @@ -432,6 +502,7 @@ gt_pch_save (FILE *f) gt_pch_save_stringpool (); + timevar_push (TV_PCH_PTR_REALLOC); saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free); for (rt = gt_ggc_rtab; *rt; rt++) @@ -454,17 +525,22 @@ gt_pch_save (FILE *f) /* Try to arrange things so that no relocation is necessary, but don't try very hard. On most platforms, this will always work, - and on the rest it's a lot of work to do better. + and on the rest it's a lot of work to do better. (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and HOST_HOOKS_GT_PCH_USE_ADDRESS.) */ mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size, fileno (f)); - + ggc_pch_this_base (state.d, mmi.preferred_base); state.ptrs = XNEWVEC (struct ptr_data *, state.count); state.ptrs_i = 0; + htab_traverse (saving_htab, call_alloc, &state); + timevar_pop (TV_PCH_PTR_REALLOC); + + timevar_push (TV_PCH_PTR_SORT); qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data); + timevar_pop (TV_PCH_PTR_SORT); /* Write out all the scalar variables. */ for (rt = gt_pch_scalar_rtab; *rt; rt++) @@ -502,7 +578,7 @@ gt_pch_save (FILE *f) if (this_object_size < state.ptrs[i]->size) { this_object_size = state.ptrs[i]->size; - this_object = xrealloc (this_object, this_object_size); + this_object = XRESIZEVAR (char, this_object, this_object_size); } memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size); if (state.ptrs[i]->reorder_fn != NULL) @@ -635,13 +711,13 @@ mmap_gt_pch_get_address (size_t size, int fd) if (ret == (void *) MAP_FAILED) ret = NULL; else - munmap (ret, size); + munmap ((caddr_t) ret, size); return ret; } /* Default version of HOST_HOOKS_GT_PCH_USE_ADDRESS when mmap is present. - Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at + Map SIZE bytes of FD+OFFSET at BASE. Return 1 if we succeeded at mapping the data at BASE, -1 if we couldn't. This version assumes that the kernel honors the START operand of mmap @@ -659,7 +735,7 @@ mmap_gt_pch_use_address (void *base, size_t size, int fd, size_t offset) if (size == 0) return -1; - addr = mmap (base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, + addr = mmap ((caddr_t) base, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, offset); return addr == base ? 1 : -1; @@ -733,7 +809,7 @@ ggc_min_heapsize_heuristic (void) phys_kbytes /= 8; #if defined(HAVE_GETRLIMIT) && defined (RLIMIT_RSS) - /* Try not to overrun the RSS limit while doing garbage collection. + /* Try not to overrun the RSS limit while doing garbage collection. The RSS limit is only advisory, so no margin is subtracted. */ { struct rlimit rlim; @@ -788,7 +864,7 @@ static htab_t loc_hash; static hashval_t hash_descriptor (const void *p) { - const struct loc_descriptor *const d = p; + const struct loc_descriptor *const d = (const struct loc_descriptor *) p; return htab_hash_pointer (d->function) | d->line; } @@ -796,8 +872,8 @@ hash_descriptor (const void *p) static int eq_descriptor (const void *p1, const void *p2) { - const struct loc_descriptor *const d = p1; - const struct loc_descriptor *const d2 = p2; + const struct loc_descriptor *const d = (const struct loc_descriptor *) p1; + const struct loc_descriptor *const d2 = (const struct loc_descriptor *) p2; return (d->file == d2->file && d->line == d2->line && d->function == d2->function); @@ -816,7 +892,7 @@ struct ptr_hash_entry static hashval_t hash_ptr (const void *p) { - const struct ptr_hash_entry *const d = p; + const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p; return htab_hash_pointer (d->ptr); } @@ -824,7 +900,7 @@ hash_ptr (const void *p) static int eq_ptr (const void *p1, const void *p2) { - const struct ptr_hash_entry *const p = p1; + const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1; return (p->ptr == p2); } @@ -842,10 +918,10 @@ loc_descriptor (const char *name, int line, const char *function) if (!loc_hash) loc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL); - slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, 1); + slot = (struct loc_descriptor **) htab_find_slot (loc_hash, &loc, INSERT); if (*slot) return *slot; - *slot = xcalloc (sizeof (**slot), 1); + *slot = XCNEW (struct loc_descriptor); (*slot)->file = name; (*slot)->line = line; (*slot)->function = function; @@ -880,7 +956,7 @@ ggc_record_overhead (size_t allocated, size_t overhead, void *ptr, static int ggc_prune_ptr (void **slot, void *b ATTRIBUTE_UNUSED) { - struct ptr_hash_entry *p = *slot; + struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot; if (!ggc_marked_p (p->ptr)) { p->loc->collected += p->size; @@ -904,7 +980,7 @@ ggc_free_overhead (void *ptr) { PTR *slot = htab_find_slot_with_hash (ptr_hash, ptr, htab_hash_pointer (ptr), NO_INSERT); - struct ptr_hash_entry *p = *slot; + struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot; p->loc->freed += p->size; htab_clear_slot (ptr_hash, slot); free (p); @@ -914,8 +990,10 @@ ggc_free_overhead (void *ptr) static int final_cmp_statistic (const void *loc1, const void *loc2) { - struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1; - struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2; + const struct loc_descriptor *const l1 = + *(const struct loc_descriptor *const *) loc1; + const struct loc_descriptor *const l2 = + *(const struct loc_descriptor *const *) loc2; long diff; diff = ((long)(l1->allocated + l1->overhead - l1->freed) - (l2->allocated + l2->overhead - l2->freed)); @@ -926,8 +1004,10 @@ final_cmp_statistic (const void *loc1, const void *loc2) static int cmp_statistic (const void *loc1, const void *loc2) { - struct loc_descriptor *l1 = *(struct loc_descriptor **) loc1; - struct loc_descriptor *l2 = *(struct loc_descriptor **) loc2; + const struct loc_descriptor *const l1 = + *(const struct loc_descriptor *const *) loc1; + const struct loc_descriptor *const l2 = + *(const struct loc_descriptor *const *) loc2; long diff; diff = ((long)(l1->allocated + l1->overhead - l1->freed - l1->collected) - @@ -940,7 +1020,7 @@ cmp_statistic (const void *loc1, const void *loc2) } /* Collect array of the descriptors from hashtable. */ -struct loc_descriptor **loc_array; +static struct loc_descriptor **loc_array; static int add_statistics (void **slot, void *b) { @@ -964,7 +1044,7 @@ dump_ggc_loc_statistics (bool final ATTRIBUTE_UNUSED) ggc_force_collect = true; ggc_collect (); - loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements); + loc_array = XCNEWVEC (struct loc_descriptor *, loc_hash->n_elements); fprintf (stderr, "-------------------------------------------------------\n"); fprintf (stderr, "\n%-48s %10s %10s %10s %10s %10s\n", "source location", "Garbage", "Freed", "Leak", "Overhead", "Times");