diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-03-03 11:25:51 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-03-03 11:25:51 +0000 |
commit | 674b05f5734c0ce4249a6128d640beec4689956e (patch) | |
tree | 2b3885b2b287da398b70600d8381767cc76aa181 /gcc/ggc-common.c | |
parent | 0eaca434ca26e585c3d61781f006859981850551 (diff) | |
download | gcc-674b05f5734c0ce4249a6128d640beec4689956e.tar.gz |
* ggc-common.c (ggc_alloc_cleared_stat, ggc_realloc_stat):
Rename from ...; make statistics transparent.
(ggc_alloc_cleared, ggc_realloc_stat): ... these.
(loc_descriptor): New structure.
(hash_descriptor, eq_descriptor, loc_descriptor, cmp_statistics,
add_statistics):
New static function.
(ggc_record_overhead, dump_statistics): New global function.
* ggc-none.c (ggc_alloc_types_stat, ggc_alloc_stat, ggc_alloc_zone_stat,
ggc_alloc_cleared_stat, ggc_realloc_stat, ggc_alloc_typed_stat): Rename
from ...; accept locations
(ggc_alloc_types, ggc_alloc, ggc_alloc_zone, ggc_alloc_cleared,
ggc_realloc, ggc_alloc_typed): ... this one.
from ...; accept locations
* ggc-page.c (ggc_alloc_typed_stat, ggc_alloc_zone_stat,
ggc_alloc_stat): Rename from ... ; pass locations
* ggc-page.c (ggc_alloc_typed, ggc_alloc_zone, ggc_alloc):
... this one.
(ggc_alloc_stat): Record overehead.
* ggc.h (ggc_alloc_types, ggc_alloc, ggc_alloc_zone, ggc_alloc_cleared,
ggc_realloc, ggc_alloc_typed): Turn to macros
(ggc_alloc_types_stat, ggc_alloc_stat, ggc_alloc_zone_stat,
ggc_alloc_cleared_stat, ggc_realloc_stat, ggc_alloc_typed_stat): Declare.
(dump_ggc_loc_satistics, ggc_record_overehead): Declare.
* langhooks.h (lhd_make_node): Declare.
(LANG_HOOKS_MAKE_TYPE): Default to new function,
* langhooks.c (lhd_make_node): New.
* rtl.c (rtx_alloc_stat, swallow_copy_rtx_stat): Rename from ... ; pass
locations.
(rtx_alloc, swallow_copy_rtx): ... this one.
* rtl.h (rtx_alloc, swallow_copy_rtx): Turn to macros.
* rtl.c (rtx_alloc_stat, swallow_copy_rtx_stat): Declare.
* toplpev.c (finalize): Dump stats.
* tree.c (make_node_stat, copy_node_stat, make_tree_vec_stat,
build_tree_list_stat, tree_cons_stat, build?_stat, build_decl_stat):
Rename from ... ; pass locators.
(make_node, copy_node, make_tree_vec, build_tree_list, tree_cons,
build?, build_decl): Declare.
* tree.h (make_node_stat, copy_node_stat, make_tree_vec_stat,
build_tree_list_stat, tree_cons_stat, build?_stat, build_decl_stat):
Declare.
(make_node, copy_node, make_tree_vec, build_tree_list, tree_cons,
build?, build_decl): New macros.
* Makefile.in (RTL_H, TREE_H): Add statistics.h dependency.
* statistics.h: New file.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@78826 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ggc-common.c')
-rw-r--r-- | gcc/ggc-common.c | 147 |
1 files changed, 142 insertions, 5 deletions
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c index 3d096b9e133..70a0d084c81 100644 --- a/gcc/ggc-common.c +++ b/gcc/ggc-common.c @@ -129,22 +129,22 @@ ggc_mark_roots (void) /* Allocate a block of memory, then clear it. */ void * -ggc_alloc_cleared (size_t size) +ggc_alloc_cleared_stat (size_t size MEM_STAT_DECL) { - void *buf = ggc_alloc (size); + void *buf = ggc_alloc_stat (size PASS_MEM_STAT); memset (buf, 0, size); return buf; } /* Resize a block of memory, possibly re-allocating it. */ void * -ggc_realloc (void *x, size_t size) +ggc_realloc_stat (void *x, size_t size MEM_STAT_DECL) { void *r; size_t old_size; if (x == NULL) - return ggc_alloc (size); + return ggc_alloc_stat (size PASS_MEM_STAT); old_size = ggc_get_size (x); @@ -166,7 +166,7 @@ ggc_realloc (void *x, size_t size) return x; } - r = ggc_alloc (size); + r = ggc_alloc_stat (size PASS_MEM_STAT); /* Since ggc_get_size returns the size of the pool, not the size of the individually allocated object, we'd access parts of the old object @@ -761,3 +761,140 @@ init_ggc_heuristics (void) set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic()); #endif } + +#ifdef GATHER_STATISTICS + +/* Datastructure used to store per-call-site statistics. */ +struct loc_descriptor +{ + const char *file; + int line; + const char *function; + int times; + size_t allocated; + size_t overhead; +}; + +/* Hashtable used for statistics. */ +static htab_t loc_hash; + +/* Hash table helpers functions. */ +static hashval_t +hash_descriptor (const void *p) +{ + const struct loc_descriptor *d = p; + + return htab_hash_pointer (d->function) | d->line; +} + +static int +eq_descriptor (const void *p1, const void *p2) +{ + const struct loc_descriptor *d = p1; + const struct loc_descriptor *d2 = p2; + + return (d->file == d2->file && d->line == d2->line + && d->function == d2->function); +} + +/* Return descriptor for given call site, create new one if needed. */ +static struct loc_descriptor * +loc_descriptor (const char *name, int line, const char *function) +{ + struct loc_descriptor loc; + struct loc_descriptor **slot; + + loc.file = name; + loc.line = line; + loc.function = 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); + if (*slot) + return *slot; + *slot = xcalloc (sizeof (**slot), 1); + (*slot)->file = name; + (*slot)->line = line; + (*slot)->function = function; + return *slot; +} + +/* Record ALLOCATED and OVERHEAD bytes to descritor NAME:LINE (FUNCTION). */ +void ggc_record_overhead (size_t allocated, size_t overhead, + const char *name, int line, const char *function) +{ + struct loc_descriptor *loc = loc_descriptor (name, line, function); + + loc->times++; + loc->allocated+=allocated; + loc->overhead+=overhead; +} + +/* Helper for qsort; sort descriptors by amount of memory consumed. */ +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; + return (l1->allocated + l1->overhead) - (l2->allocated + l2->overhead); +} + +/* Collect array of the descriptors from hashtable. */ +struct loc_descriptor **loc_array; +static int +add_statistics (void **slot, void *b) +{ + int *n = (int *)b; + loc_array[*n] = (struct loc_descriptor *) *slot; + (*n)++; + return 1; +} + +/* Dump per-site memory statistics. */ +#endif +void dump_ggc_loc_statistics (void) +{ +#ifdef GATHER_STATISTICS + int nentries = 0; + char s[4096]; + size_t count, size, overhead; + int i; + + loc_array = xcalloc (sizeof (*loc_array), loc_hash->n_elements); + fprintf (stderr, "-------------------------------------------------------\n"); + fprintf (stderr, "\n%-60s %10s %10s %10s\n", + "source location", "Times", "Allocated", "Overhead"); + fprintf (stderr, "-------------------------------------------------------\n"); + count = 0; + size = 0; + overhead = 0; + htab_traverse (loc_hash, add_statistics, &nentries); + qsort (loc_array, nentries, sizeof (*loc_array), cmp_statistic); + for (i = 0; i < nentries; i++) + { + struct loc_descriptor *d = loc_array[i]; + size += d->allocated; + count += d->times; + overhead += d->overhead; + } + for (i = 0; i < nentries; i++) + { + struct loc_descriptor *d = loc_array[i]; + if (d->allocated) + { + const char *s1 = d->file; + const char *s2; + while ((s2 = strstr (s1, "gcc/"))) + s1 = s2 + 4; + sprintf (s, "%s:%i (%s)", s1, d->line, d->function); + fprintf (stderr, "%-60s %10i %10li %10li:%.3f%%\n", s, + d->times, (long)d->allocated, (long)d->overhead, + (d->allocated + d->overhead) *100.0 / (size + overhead)); + } + } + fprintf (stderr, "%-60s %10ld %10ld %10ld\n", + "Total", (long)count, (long)size, (long)overhead); + fprintf (stderr, "-------------------------------------------------------\n"); +#endif +} |