Allocpool statistics
Jan Hubicka
jh@suse.cz
Wed Jan 21 23:17:00 GMT 2004
Hi,
this patch adds statistics for allocpools. It is mostly cut&past from
varrays except that it removes code to strdup xstrdup used to save copy
of allocpool name.
THis confuse my hashtable and I think it can safely go as we always pass
the static strings anyway.
Honza
* alloc-poo.c: Include hashtab.h
(alloc_pool_descriptor): New structure
(alloc_pool_hash): New global variable.
(hash_descriptor, eq_descriptor, alloc_pool_descriptor): New.
(create_alloc_pool): Update statistics.
(free_alloc_pool): Likewise.
(pool_alloc): Likewise.
(output_info): New structure
(print_statistics, dump_alloc_pool_statistics): New function.
* alloc-pool.h (alloc_pool_def): Turn name to be constant.
(dump_alloc_pool_statistics): Declare.
* toplev.c (finalize): Dump statistics.
Index: alloc-pool.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alloc-pool.c,v
retrieving revision 1.9
diff -c -3 -p -r1.9 alloc-pool.c
*** alloc-pool.c 21 Dec 2003 14:08:32 -0000 1.9
--- alloc-pool.c 21 Jan 2004 22:42:39 -0000
*************** Software Foundation, 59 Temple Place - S
*** 23,28 ****
--- 23,29 ----
#include "config.h"
#include "system.h"
#include "alloc-pool.h"
+ #include "hashtab.h"
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic
*************** typedef struct allocation_object_def
*** 73,78 ****
--- 74,129 ----
static ALLOC_POOL_ID_TYPE last_id;
#endif
+ #ifdef GATHER_STATISTICS
+
+ /* Store infromation about each particular alloc_pool. */
+ struct alloc_pool_descriptor
+ {
+ const char *name;
+ int allocated;
+ int created;
+ int peak;
+ int current;
+ };
+
+ /* Hashtable mapping alloc_pool names to descriptors. */
+ static htab_t alloc_pool_hash;
+
+ /* Hashtable helpers. */
+ static hashval_t
+ hash_descriptor (const void *p)
+ {
+ const struct alloc_pool_descriptor *d = p;
+ return htab_hash_pointer (d->name);
+ }
+ static int
+ eq_descriptor (const void *p1, const void *p2)
+ {
+ const struct alloc_pool_descriptor *d = p1;
+ return d->name == p2;
+ }
+
+ /* For given name, return descriptor, create new if needed. */
+ static struct alloc_pool_descriptor *
+ alloc_pool_descriptor (const char *name)
+ {
+ struct alloc_pool_descriptor **slot;
+
+ if (!alloc_pool_hash)
+ alloc_pool_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+
+ slot = (struct alloc_pool_descriptor **)
+ htab_find_slot_with_hash (alloc_pool_hash, name,
+ htab_hash_pointer (name),
+ 1);
+ if (*slot)
+ return *slot;
+ *slot = xcalloc (sizeof (**slot), 1);
+ (*slot)->name = name;
+ return *slot;
+ }
+ #endif
+
/* Create a pool of things of size SIZE, with NUM in each block we
allocate. */
*************** create_alloc_pool (const char *name, siz
*** 81,86 ****
--- 132,140 ----
{
alloc_pool pool;
size_t pool_size, header_size;
+ #ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc;
+ #endif
if (!name)
abort ();
*************** create_alloc_pool (const char *name, siz
*** 108,114 ****
pool = xmalloc (pool_size);
/* Now init the various pieces of our pool structure. */
! pool->name = xstrdup (name);
pool->elt_size = size;
pool->elts_per_block = num;
--- 162,172 ----
pool = xmalloc (pool_size);
/* Now init the various pieces of our pool structure. */
! pool->name = /*xstrdup (name)*/name;
! #ifdef GATHER_STATISTICS
! desc = alloc_pool_descriptor (name);
! desc->created++;
! #endif
pool->elt_size = size;
pool->elts_per_block = num;
*************** void
*** 140,145 ****
--- 198,206 ----
free_alloc_pool (alloc_pool pool)
{
alloc_pool_list block, next_block;
+ #ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+ #endif
#ifdef ENABLE_CHECKING
if (!pool)
*************** free_alloc_pool (alloc_pool pool)
*** 151,159 ****
{
next_block = block->next;
free (block);
}
! /* Lastly, free the pool and the name. */
! free (pool->name);
free (pool);
}
--- 212,222 ----
{
next_block = block->next;
free (block);
+ #ifdef GATHER_STATISTICS
+ desc->current -= pool->block_size;
+ #endif
}
! /* Lastly, free the pool. */
free (pool);
}
*************** pool_alloc (alloc_pool pool)
*** 163,168 ****
--- 226,236 ----
{
alloc_pool_list header;
char *block;
+ #ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+
+ desc->allocated+=pool->elt_size;
+ #endif
#ifdef ENABLE_CHECKING
if (!pool)
*************** pool_alloc (alloc_pool pool)
*** 179,184 ****
--- 247,257 ----
block = xmalloc (pool->block_size);
block_header = (alloc_pool_list) block;
block += align_eight (sizeof (struct alloc_pool_list_def));
+ #ifdef GATHER_STATISTICS
+ desc->current += pool->block_size;
+ if (desc->peak < desc->current)
+ desc->peak = desc->current;
+ #endif
/* Throw it on the block list. */
block_header->next = pool->block_list;
*************** pool_free (alloc_pool pool, void *ptr)
*** 241,244 ****
--- 315,364 ----
header->next = pool->free_list;
pool->free_list = header;
pool->elts_free++;
+ }
+ /* Output per-alloc_pool statistics. */
+ #ifdef GATHER_STATISTICS
+
+ /* Used to accumulate statistics about alloc_pool sizes. */
+ struct output_info
+ {
+ int count;
+ int size;
+ };
+
+ /* Called via htab_traverse. Output alloc_pool descriptor pointed out by SLOT
+ and update statistics. */
+ static int
+ print_statistics (void **slot, void *b)
+ {
+ struct alloc_pool_descriptor *d = (struct alloc_pool_descriptor *) *slot;
+ struct output_info *i = (struct output_info *) b;
+
+ if (d->allocated)
+ {
+ fprintf (stderr, "%-21s %6d %10d %10d %10d\n", d->name,
+ d->created, d->allocated, d->peak, d->current);
+ i->size += d->allocated;
+ i->count += d->created;
+ }
+ return 1;
+ }
+ #endif
+
+ /* Output per-alloc_pool memory usage statistics. */
+ void dump_alloc_pool_statistics (void)
+ {
+ #ifdef GATHER_STATISTICS
+ struct output_info info;
+
+ fprintf (stderr, "\nAlloc-pool Kind Pools Allocated Peak Leak\n");
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ info.count = 0;
+ info.size = 0;
+ htab_traverse (alloc_pool_hash, print_statistics, &info);
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n",
+ "Total", info.count, info.size);
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ #endif
}
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1229
diff -c -3 -p -r1.1229 Makefile.in
*** Makefile.in 20 Jan 2004 20:36:18 -0000 1.1229
--- Makefile.in 21 Jan 2004 22:42:53 -0000
*************** unroll.o : unroll.c $(CONFIG_H) $(SYSTEM
*** 1677,1683 ****
function.h $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H) \
cfgloop.h
! alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h
flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) function.h except.h $(EXPR_H) $(GGC_H) $(TM_P_H)
--- 1677,1683 ----
function.h $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H) \
cfgloop.h
! alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) function.h except.h $(EXPR_H) $(GGC_H) $(TM_P_H)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.865
diff -c -3 -p -r1.865 toplev.c
*** toplev.c 17 Jan 2004 12:28:57 -0000 1.865
--- toplev.c 21 Jan 2004 22:48:42 -0000
*************** finalize (void)
*** 4583,4588 ****
--- 4585,4591 ----
stringpool_statistics ();
dump_tree_statistics ();
dump_rtx_statistics ();
+ dump_alloc_pool_statistics ();
}
/* Free up memory for the benefit of leak detectors. */
Index: alloc-pool.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alloc-pool.h,v
retrieving revision 1.3
diff -c -3 -p -r1.3 alloc-pool.h
*** alloc-pool.h 15 Jun 2003 13:43:30 -0000 1.3
--- alloc-pool.h 21 Jan 2004 22:48:42 -0000
*************** typedef struct alloc_pool_list_def
*** 32,38 ****
typedef struct alloc_pool_def
{
! char *name;
#ifdef ENABLE_CHECKING
ALLOC_POOL_ID_TYPE id;
#endif
--- 32,38 ----
typedef struct alloc_pool_def
{
! const char *name;
#ifdef ENABLE_CHECKING
ALLOC_POOL_ID_TYPE id;
#endif
*************** extern alloc_pool create_alloc_pool (con
*** 51,54 ****
--- 51,55 ----
extern void free_alloc_pool (alloc_pool);
extern void *pool_alloc (alloc_pool);
extern void pool_free (alloc_pool, void *);
+ extern void dump_alloc_pool_statistics (void);
#endif
More information about the Gcc-patches
mailing list