aboutsummaryrefslogtreecommitdiff
path: root/gcc/vec.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2015-05-27 14:47:22 +0200
committerMartin Liska <marxin@gcc.gnu.org>2015-05-27 12:47:22 +0000
commit2d44c7dea7c8d2917eec28a5e08e8f405aad8c3e (patch)
tree4505b8171553fd7e780bb28532a4986cd72b6f4f /gcc/vec.c
parent151fbaac5c78c4e9b749fc9e916f78b0ba63b153 (diff)
downloadgcc-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.c278
1 files changed, 94 insertions, 184 deletions
diff --git a/gcc/vec.c b/gcc/vec.c
index 06b887b..d4a7a02 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -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);
}