/* Functions to support a pool of allocatable objects
- Copyright (C) 1997-2015 Free Software Foundation, Inc.
+ Copyright (C) 1997-2019 Free Software Foundation, Inc.
Contributed by Daniel Berlin <dan@cgsoftware.com>
This file is part of GCC.
extern void dump_alloc_pool_statistics (void);
+/* Flag indicates whether memory statistics are gathered any longer. */
+extern bool after_memory_report;
+
typedef unsigned long ALLOC_POOL_ID_TYPE;
/* Last used ID. */
{
char *location_string = loc->to_string ();
- fprintf (stderr, "%-32s%-48s %6li%10li:%5.1f%%%10li%10li:%5.1f%%%12li\n",
- m_pool_name, location_string, (long)m_instances,
- (long)m_allocated, get_percent (m_allocated, total.m_allocated),
- (long)m_peak, (long)m_times,
+ fprintf (stderr, "%-32s%-48s " PRsa(5) PRsa(9) ":%5.1f%%"
+ PRsa(9) PRsa(9) ":%5.1f%%%12" PRIu64 "\n",
+ m_pool_name, location_string,
+ SIZE_AMOUNT (m_instances),
+ SIZE_AMOUNT (m_allocated),
+ get_percent (m_allocated, total.m_allocated),
+ SIZE_AMOUNT (m_peak),
+ SIZE_AMOUNT (m_times),
get_percent (m_times, total.m_times),
- (long)m_element_size);
+ (uint64_t)m_element_size);
free (location_string);
}
{
fprintf (stderr, "%-32s%-48s %6s%11s%16s%17s%12s\n", "Pool name", name,
"Pools", "Leak", "Peak", "Times", "Elt size");
- print_dash_line ();
}
/* Dump footer. */
inline void
dump_footer ()
{
- print_dash_line ();
- fprintf (stderr, "%s%82li%10li\n", "Total", (long)m_instances,
- (long)m_allocated);
- print_dash_line ();
+ fprintf (stderr, "%s" PRsa(82) PRsa(10) "\n", "Total",
+ SIZE_AMOUNT (m_instances), SIZE_AMOUNT (m_allocated));
}
/* Element size. */
struct allocation_object
{
+#if CHECKING_P
/* The ID of alloc pool which the object was allocated from. */
ALLOC_POOL_ID_TYPE id;
+#endif
union
{
int64_t align_i;
} u;
+#if CHECKING_P
static inline allocation_object*
get_instance (void *data_ptr)
{
- offsetof (allocation_object,
u.data));
}
+#endif
static inline void*
get_data (void *instance_ptr)
const char *name, size_t size MEM_STAT_DECL):
m_name (name), m_id (0), m_elts_per_block (0), m_returned_free_list (NULL),
m_virgin_free_list (NULL), m_virgin_elts_remaining (0), m_elts_allocated (0),
- m_elts_free (0), m_blocks_allocated (0), m_block_list (NULL), m_size (size),
- m_initialized (false), m_location (ALLOC_POOL_ORIGIN, false PASS_MEM_STAT) {}
+ m_elts_free (0), m_blocks_allocated (0), m_block_list (NULL), m_elt_size (0),
+ m_size (size), m_initialized (false),
+ m_location (ALLOC_POOL_ORIGIN, false PASS_MEM_STAT) {}
/* Initialize a pool allocator. */
size_t size = m_size;
gcc_checking_assert (m_name);
+ gcc_checking_assert (m_size);
/* Make size large enough to store the list header. */
if (size < sizeof (allocation_pool_list*))
TBlockAllocator::release (block);
}
- if (GATHER_STATISTICS)
+ if (GATHER_STATISTICS && !after_memory_report)
{
pool_allocator_usage.release_instance_overhead
(this, (m_elts_allocated - m_elts_free) * m_elt_size);
/* Make the block. */
block = reinterpret_cast<char *> (TBlockAllocator::allocate ());
- block_header = (allocation_pool_list*) block;
+ block_header = new (block) allocation_pool_list;
block += align_eight (sizeof (allocation_pool_list));
/* Throw it on the block list. */
header->next = NULL;
/* Mark the element to be free. */
+#if CHECKING_P
((allocation_object*) block)->id = 0;
+#endif
VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (header,size));
m_returned_free_list = header;
m_virgin_free_list += m_elt_size;
m_elts_free--;
/* Set the ID for element. */
+#if CHECKING_P
allocation_object::get_instance (header)->id = m_id;
+#endif
VALGRIND_DISCARD (VALGRIND_MAKE_MEM_UNDEFINED (header, size));
return (void *)(header);
inline void
base_pool_allocator <TBlockAllocator>::remove (void *object)
{
+ int size = m_elt_size - offsetof (allocation_object, u.data);
+
if (flag_checking)
{
gcc_assert (m_initialized);
gcc_assert (object
- /* Check if we free more than we allocated, which is Bad (TM). */
- && m_elts_free < m_elts_allocated
- /* Check whether the PTR was allocated from POOL. */
- && m_id == allocation_object::get_instance (object)->id);
+ /* Check if we free more than we allocated. */
+ && m_elts_free < m_elts_allocated);
+#if CHECKING_P
+ /* Check whether the PTR was allocated from POOL. */
+ gcc_assert (m_id == allocation_object::get_instance (object)->id);
+#endif
- int size = m_elt_size - offsetof (allocation_object, u.data);
memset (object, 0xaf, size);
}
+#if CHECKING_P
/* Mark the element to be free. */
allocation_object::get_instance (object)->id = 0;
+#endif
- allocation_pool_list *header = (allocation_pool_list*) object;
+ allocation_pool_list *header = new (object) allocation_pool_list;
header->next = m_returned_free_list;
m_returned_free_list = header;
VALGRIND_DISCARD (VALGRIND_MAKE_MEM_NOACCESS (object, size));
m_allocator.release_if_empty ();
}
+
+ /* Allocate memory for instance of type T and call a default constructor. */
+
inline T *
allocate () ATTRIBUTE_MALLOC
{
- return ::new (m_allocator.allocate ()) T ();
+ return ::new (m_allocator.allocate ()) T;
+ }
+
+ /* Allocate memory for instance of type T and return void * that
+ could be used in situations where a default constructor is not provided
+ by the class T. */
+
+ inline void *
+ allocate_raw () ATTRIBUTE_MALLOC
+ {
+ return m_allocator.allocate ();
}
inline void
inline void *
operator new (size_t, object_allocator<T> &a)
{
- return a.allocate ();
+ return a.allocate_raw ();
}
/* Hashtable mapping alloc_pool names to descriptors. */