void register_object_overhead (T *usage, size_t size, const void *ptr);
/* Release PTR pointer of SIZE bytes. If REMOVE_FROM_MAP is set to true,
- remove the instance from reverse map. */
- void release_instance_overhead (void *ptr, size_t size,
- bool remove_from_map = false);
+ remove the instance from reverse map. Return memory usage that belongs
+ to this memory description. */
+ T * release_instance_overhead (void *ptr, size_t size,
+ bool remove_from_map = false);
/* Release intance object identified by PTR pointer. */
void release_object_overhead (void *ptr);
/* Release PTR pointer of SIZE bytes. */
template <class T>
-inline void
+inline T *
mem_alloc_description<T>::release_instance_overhead (void *ptr, size_t size,
bool remove_from_map)
{
if (!slot)
{
/* Due to PCH, it can really happen. */
- return;
+ return NULL;
}
- mem_usage_pair<T> usage_pair = *slot;
- usage_pair.usage->release_overhead (size);
+ T *usage = (*slot).usage;
+ usage->release_overhead (size);
if (remove_from_map)
m_reverse_map->remove (ptr);
+
+ return usage;
}
/* Release intance object identified by PTR pointer. */
struct vec_usage: public mem_usage
{
/* Default constructor. */
- vec_usage (): m_items (0), m_items_peak (0) {}
+ vec_usage (): m_items (0), m_items_peak (0), m_element_size (0) {}
/* Constructor. */
vec_usage (size_t allocated, size_t times, size_t peak,
- size_t items, size_t items_peak)
+ size_t items, size_t items_peak, size_t element_size)
: mem_usage (allocated, times, peak),
- m_items (items), m_items_peak (items_peak) {}
+ m_items (items), m_items_peak (items_peak),
+ m_element_size (element_size) {}
/* Sum the usage with SECOND usage. */
vec_usage
m_times + second.m_times,
m_peak + second.m_peak,
m_items + second.m_items,
- m_items_peak + second.m_items_peak);
+ m_items_peak + second.m_items_peak, 0);
}
/* Dump usage coupled to LOC location, where TOTAL is sum of all rows. */
s[48] = '\0';
- fprintf (stderr, "%-48s %10li:%4.1f%%%10li%10li:%4.1f%%%11li%11li\n", s,
+ fprintf (stderr, "%-48s %10li%11li:%4.1f%%%10li%10li:%4.1f%%%11li%11li\n", s,
+ (long)m_element_size,
(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);
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");
+ fprintf (stderr, "%-48s %10s%11s%16s%10s%17s%11s\n", name, "sizeof(T)",
+ "Leak", "Peak", "Times", "Leak items", "Peak items");
print_dash_line ();
}
size_t m_items;
/* Peak value of number of allocated items. */
size_t m_items_peak;
+ /* Size of element of the vector. */
+ size_t m_element_size;
};
/* Vector memory description. */
/* Account the overhead. */
void
-vec_prefix::register_overhead (void *ptr, size_t size, size_t elements
- MEM_STAT_DECL)
+vec_prefix::register_overhead (void *ptr, size_t elements,
+ size_t element_size MEM_STAT_DECL)
{
vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN, false
FINAL_PASS_MEM_STAT);
- vec_usage *usage = vec_mem_desc.register_instance_overhead (size, ptr);
+ vec_usage *usage
+ = vec_mem_desc.register_instance_overhead (elements * element_size, ptr);
+ usage->m_element_size = element_size;
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 *ptr, size_t size, bool in_dtor
- MEM_STAT_DECL)
+vec_prefix::release_overhead (void *ptr, size_t size, size_t elements,
+ bool in_dtor MEM_STAT_DECL)
{
if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN,
false FINAL_PASS_MEM_STAT);
- vec_mem_desc.release_instance_overhead (ptr, size, in_dtor);
+ vec_usage *usage = vec_mem_desc.release_instance_overhead (ptr, size,
+ in_dtor);
+ usage->m_items -= elements;
}
/* Calculate the number of slots to reserve a vector, making sure that
/* Memory allocation support routines in vec.c. */
void register_overhead (void *, size_t, size_t CXX_MEM_STAT_INFO);
- void release_overhead (void *, size_t, bool CXX_MEM_STAT_INFO);
+ void release_overhead (void *, size_t, size_t, bool CXX_MEM_STAT_INFO);
static unsigned calculate_allocation (vec_prefix *, unsigned, bool);
static unsigned calculate_allocation_1 (unsigned, unsigned);
va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
MEM_STAT_DECL)
{
+ size_t elt_size = sizeof (T);
unsigned alloc
= vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
gcc_checking_assert (alloc);
if (GATHER_STATISTICS && v)
- v->m_vecpfx.release_overhead (v, v->allocated (), false);
+ v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
+ v->allocated (), false);
size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc);
unsigned nelem = v ? v->length () : 0;
v->embedded_init (alloc, nelem);
if (GATHER_STATISTICS)
- v->m_vecpfx.register_overhead (v, alloc, nelem PASS_MEM_STAT);
+ v->m_vecpfx.register_overhead (v, alloc, elt_size PASS_MEM_STAT);
}
void
va_heap::release (vec<T, va_heap, vl_embed> *&v)
{
+ size_t elt_size = sizeof (T);
if (v == NULL)
return;
if (GATHER_STATISTICS)
- v->m_vecpfx.release_overhead (v, v->allocated (), true);
+ v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
+ v->allocated (), true);
::free (v);
v = NULL;
}