diff options
author | Martin Liska <mliska@suse.cz> | 2015-05-27 14:47:22 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2015-05-27 12:47:22 +0000 |
commit | 2d44c7dea7c8d2917eec28a5e08e8f405aad8c3e (patch) | |
tree | 4505b8171553fd7e780bb28532a4986cd72b6f4f /gcc/vec.c | |
parent | 151fbaac5c78c4e9b749fc9e916f78b0ba63b153 (diff) | |
download | gcc-2d44c7dea7c8d2917eec28a5e08e8f405aad8c3e.zip gcc-2d44c7dea7c8d2917eec28a5e08e8f405aad8c3e.tar.gz gcc-2d44c7dea7c8d2917eec28a5e08e8f405aad8c3e.tar.bz2 |
New memory allocation statistics infrastructure.
* Makefile.in: Add additional dependencies related to memory report
enhancement.
* alloc-pool.c (allocate_pool_descriptor): Use new ctor.
* bitmap.c (struct bitmap_descriptor_d): Remove.
(struct loc): Likewise.
(struct bitmap_desc_hasher): Likewise.
(bitmap_desc_hasher::hash): Likewise.
(bitmap_desc_hasher::equal): Likewise.
(get_bitmap_descriptor): Likewise.
(bitmap_register): User new memory descriptor API.
(register_overhead): Likewise.
(bitmap_find_bit): Register nsearches and search_iter statistics.
(struct bitmap_output_info): Remove.
(print_statistics): Likewise.
(dump_bitmap_statistics): Use new memory descriptor.
* bitmap.h (struct bitmap_usage): New class.
* genmatch.c: Extend header file inclusion.
* genpreds.c: Likewise.
* ggc-common.c (struct ggc_usage): New class.
(struct ggc_loc_desc_hasher): Remove.
(ggc_loc_desc_hasher::hash): Likewise.
(ggc_loc_desc_hasher::equal): Likewise.
(struct ggc_ptr_hash_entry): Likewise.
(struct ptr_hash_hasher): Likewise.
(ptr_hash_hasher::hash): Likewise.
(ptr_hash_hasher::equal): Likewise.
(make_loc_descriptor): Likewise.
(ggc_prune_ptr): Likewise.
(dump_ggc_loc_statistics): Use new memory descriptor.
(ggc_record_overhead): Likewise.
(ggc_free_overhead): Likewise.
(final_cmp_statistic): Remove.
(cmp_statistic): Likewise.
(ggc_add_statistics): Liekwise.
(ggc_prune_overhead_list): Likewise.
* hash-map-traits.h: New file.
* hash-map.h (struct default_hashmap_traits): Move the traits to a
separate header file.
* hash-set.h: Pass memory statistics info to ctor.
* hash-table.c (void dump_hash_table_loc_statistics): New function.
* hash-table.h (hash_table::hash_table): Add new ctor arguments.
(hash_table::~hash_table): Register memory release operation.
(hash_table::alloc_entries): Handle memory allocation operation.
(hash_table::expand): Likewise.
* inchash.c (iterative_hash_hashval_t): Move implementation to header
file.
(iterative_hash_host_wide_int): Likewise.
* inchash.h (class hash): Likewise.
* mem-stats-traits.h: New file.
* mem-stats.h: New file.
(mem_location): Add new class.
(mem_usage): Likewise.
(mem_alloc_description): Likewise.
* sese.c: Add new header file inclusision.
* toplev.c (dump_memory_report): Add report for hash_table, hash_map
and hash_set.
* tree-sra.c: Add new header file inclusision.
* vec.c (struct vec_descriptor): Remove.
(hash_descriptor): Likewise.
(struct vec_usage): Likewise.
(struct ptr_hash_entry): Likewise.
(hash_ptr): Likewise.
(eq_ptr): Likewise.
(vec_prefix::register_overhead): Use new memory descriptor API.
(vec_prefix::release_overhead): Likewise.
(add_statistics): Remove.
(dump_vec_loc_statistics): Use new memory descriptor API.
* vec.h (struct vec_prefix): Likewise.
(va_heap::reserve): Likewise.
(va_heap::release): Likewise.
* emit-rtl.c (gen_raw_REG): Fix passing MEM_STAT.
From-SVN: r223748
Diffstat (limited to 'gcc/vec.c')
-rw-r--r-- | gcc/vec.c | 278 |
1 files changed, 94 insertions, 184 deletions
@@ -33,6 +33,9 @@ along with GCC; see the file COPYING3. If not see #include "vec.h" #include "diagnostic-core.h" #include "hashtab.h" +#include "mem-stats.h" +#include "hash-map.h" +#include "mem-stats.h" /* vNULL is an empty type with a template cast operation that returns a zero-initialized vec<T, A, L> instance. Use this when you want @@ -44,129 +47,110 @@ along with GCC; see the file COPYING3. If not see they cannot have ctors/dtors. */ vnull vNULL; - -/* Store information about each particular vector. */ -struct vec_descriptor -{ - const char *function; - const char *file; - int line; - size_t allocated; - size_t times; - size_t peak; -}; - - -/* Hashtable mapping vec addresses to descriptors. */ -static htab_t vec_desc_hash; - -/* Hashtable helpers. */ -static hashval_t -hash_descriptor (const void *p) -{ - const struct vec_descriptor *const d = - (const struct vec_descriptor *) p; - return htab_hash_pointer (d->file) + d->line; -} -static int -eq_descriptor (const void *p1, const void *p2) +/* Vector memory usage. */ +struct vec_usage: public mem_usage { - const struct vec_descriptor *const d = (const struct vec_descriptor *) p1; - const struct vec_descriptor *const l = (const struct vec_descriptor *) p2; - return d->file == l->file && d->function == l->function && d->line == l->line; -} - -/* Hashtable converting address of allocated field to loc descriptor. */ -static htab_t ptr_hash; -struct ptr_hash_entry -{ - void *ptr; - struct vec_descriptor *loc; - size_t allocated; + /* Default constructor. */ + vec_usage (): m_items (0), m_items_peak (0) {} + + /* Constructor. */ + vec_usage (size_t allocated, size_t times, size_t peak, + size_t items, size_t items_peak) + : mem_usage (allocated, times, peak), + m_items (items), m_items_peak (items_peak) {} + + /* Comparison operator. */ + inline bool operator< (const vec_usage &second) const + { + return (m_allocated == second.m_allocated ? + (m_peak == second.m_peak ? m_times < second.m_times + : m_peak < second.m_peak) : m_allocated < second.m_allocated); + } + + /* Sum the usage with SECOND usage. */ + vec_usage operator+ (const vec_usage &second) + { + return vec_usage (m_allocated + second.m_allocated, + m_times + second.m_times, + m_peak + second.m_peak, + m_items + second.m_items, + m_items_peak + second.m_items_peak); + } + + /* Dump usage coupled to LOC location, where TOTAL is sum of all rows. */ + inline void dump (mem_location *loc, mem_usage &total) const + { + char s[4096]; + sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (), + loc->m_line, loc->m_function); + + s[48] = '\0'; + + fprintf (stderr, "%-48s %10li:%4.1f%%%10li%10li:%4.1f%%%11li%11li\n", s, + (long)m_allocated, m_allocated * 100.0 / total.m_allocated, + (long)m_peak, (long)m_times, m_times * 100.0 / total.m_times, + (long)m_items, (long)m_items_peak); + } + + /* Dump footer. */ + inline void dump_footer () + { + print_dash_line (); + fprintf (stderr, "%s%55li%25li%17li\n", "Total", (long)m_allocated, + (long)m_times, (long)m_items); + print_dash_line (); + } + + /* Dump header with NAME. */ + static inline void dump_header (const char *name) + { + fprintf (stderr, "%-48s %11s%15s%10s%17s%11s\n", name, "Leak", "Peak", + "Times", "Leak items", "Peak items"); + print_dash_line (); + } + + /* Compare wrapper used by qsort method. */ + static int compare (const void *first, const void *second) + { + typedef std::pair<mem_location *, vec_usage *> mem_pair_t; + + const mem_pair_t f = *(const mem_pair_t *)first; + const mem_pair_t s = *(const mem_pair_t *)second; + + return (*f.second) < (*s.second); + } + + /* Current number of items allocated. */ + size_t m_items; + /* Peak value of number of allocated items. */ + size_t m_items_peak; }; -/* Hash table helpers functions. */ -static hashval_t -hash_ptr (const void *p) -{ - const struct ptr_hash_entry *const d = (const struct ptr_hash_entry *) p; - - return htab_hash_pointer (d->ptr); -} - -static int -eq_ptr (const void *p1, const void *p2) -{ - const struct ptr_hash_entry *const p = (const struct ptr_hash_entry *) p1; - - return (p->ptr == p2); -} - -/* Return descriptor for given call site, create new one if needed. */ -static struct vec_descriptor * -vec_descriptor (const char *name, int line, const char *function) -{ - struct vec_descriptor loc; - struct vec_descriptor **slot; - - loc.file = name; - loc.line = line; - loc.function = function; - if (!vec_desc_hash) - vec_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL); - - slot = (struct vec_descriptor **) htab_find_slot (vec_desc_hash, &loc, - INSERT); - if (*slot) - return *slot; - *slot = XCNEW (struct vec_descriptor); - (*slot)->file = name; - (*slot)->line = line; - (*slot)->function = function; - (*slot)->allocated = 0; - (*slot)->peak = 0; - return *slot; -} +/* Vector memory description. */ +static mem_alloc_description <vec_usage> vec_mem_desc; /* Account the overhead. */ void -vec_prefix::register_overhead (size_t size, const char *name, int line, - const char *function) +vec_prefix::register_overhead (void *ptr, size_t size, size_t elements + MEM_STAT_DECL) { - struct vec_descriptor *loc = vec_descriptor (name, line, function); - struct ptr_hash_entry *p = XNEW (struct ptr_hash_entry); - PTR *slot; - - p->ptr = this; - p->loc = loc; - p->allocated = size; - if (!ptr_hash) - ptr_hash = htab_create (10, hash_ptr, eq_ptr, NULL); - slot = htab_find_slot_with_hash (ptr_hash, this, htab_hash_pointer (this), - INSERT); - gcc_assert (!*slot); - *slot = p; - - loc->allocated += size; - if (loc->peak < loc->allocated) - loc->peak += loc->allocated; - loc->times++; + vec_mem_desc.register_descriptor (ptr, VEC, false FINAL_PASS_MEM_STAT); + vec_usage *usage = vec_mem_desc.register_instance_overhead (size, ptr); + usage->m_items += elements; + if (usage->m_items_peak < usage->m_items) + usage->m_items_peak = usage->m_items; } - /* Notice that the memory allocated for the vector has been freed. */ void -vec_prefix::release_overhead (void) +vec_prefix::release_overhead (void *ptr, size_t size, bool in_dtor + MEM_STAT_DECL) { - PTR *slot = htab_find_slot_with_hash (ptr_hash, this, - htab_hash_pointer (this), - NO_INSERT); - struct ptr_hash_entry *p = (struct ptr_hash_entry *) *slot; - p->loc->allocated -= p->allocated; - htab_clear_slot (ptr_hash, slot); - ::free (p); + if (!vec_mem_desc.contains_descriptor_for_instance (ptr)) + vec_mem_desc.register_descriptor (ptr, VEC, false FINAL_PASS_MEM_STAT); + vec_mem_desc.release_instance_overhead (ptr, size, in_dtor); } @@ -195,84 +179,10 @@ vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired) return alloc; } - -/* Helper for qsort; sort descriptors by amount of memory consumed. */ - -static int -cmp_statistic (const void *loc1, const void *loc2) -{ - const struct vec_descriptor *const l1 = - *(const struct vec_descriptor *const *) loc1; - const struct vec_descriptor *const l2 = - *(const struct vec_descriptor *const *) loc2; - long diff; - diff = l1->allocated - l2->allocated; - if (!diff) - diff = l1->peak - l2->peak; - if (!diff) - diff = l1->times - l2->times; - return diff > 0 ? 1 : diff < 0 ? -1 : 0; -} - - -/* Collect array of the descriptors from hashtable. */ - -static struct vec_descriptor **loc_array; -static int -add_statistics (void **slot, void *b) -{ - int *n = (int *)b; - loc_array[*n] = (struct vec_descriptor *) *slot; - (*n)++; - return 1; -} - /* Dump per-site memory statistics. */ void dump_vec_loc_statistics (void) { - int nentries = 0; - char s[4096]; - size_t allocated = 0; - size_t times = 0; - int i; - - if (! GATHER_STATISTICS) - return; - - loc_array = XCNEWVEC (struct vec_descriptor *, vec_desc_hash->n_elements); - fprintf (stderr, "Heap vectors:\n"); - fprintf (stderr, "\n%-48s %10s %10s %10s\n", - "source location", "Leak", "Peak", "Times"); - fprintf (stderr, "-------------------------------------------------------\n"); - htab_traverse (vec_desc_hash, add_statistics, &nentries); - qsort (loc_array, nentries, sizeof (*loc_array), cmp_statistic); - for (i = 0; i < nentries; i++) - { - struct vec_descriptor *d = loc_array[i]; - allocated += d->allocated; - times += d->times; - } - for (i = 0; i < nentries; i++) - { - struct vec_descriptor *d = loc_array[i]; - 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); - s[48] = 0; - fprintf (stderr, "%-48s %10li:%4.1f%% %10li %10li:%4.1f%% \n", s, - (long)d->allocated, - (d->allocated) * 100.0 / allocated, - (long)d->peak, - (long)d->times, - (d->times) * 100.0 / times); - } - fprintf (stderr, "%-48s %10ld %10ld\n", - "Total", (long)allocated, (long)times); - fprintf (stderr, "\n%-48s %10s %10s %10s\n", - "source location", "Leak", "Peak", "Times"); - fprintf (stderr, "-------------------------------------------------------\n"); + vec_mem_desc.dump (VEC); } |