/* Support for finding the count and size for each class (wrapper)
* in the heap .
*/
#include "heap-utils.h"
wrapper_stats_s wrapper_stats[STAT_SIZE];
static int wrapper_cursor;
static int wrapper_preassignments;
/*
extern void *KLpairGYdylanVdylanW;
extern void *KLsimple_object_vectorGYdylanVdylanW;
*/
static void preassign_wrapper (void* wrapper, int index)
{
wrapper_stats[wrapper_cursor].wrapper_address = wrapper;
wrapper_cursor++;
wrapper_preassignments++;
}
void clear_wrapper_stats (void)
{
int i;
wrapper_cursor = 0;
wrapper_preassignments = 0;
for (i = 0; i < STAT_SIZE; i++) {
wrapper_stats[i].wrapper_address = (void *)0;
wrapper_stats[i].usage_count = 0;
wrapper_stats[i].usage_size = 0;
}
/*
pre_assign_wrapper(&KLpairGYdylanVdylanW);
pre_assign_wrapper(&KLsimple_object_vectorGYdylanVdylanW);
*/
}
static int default_index_for_wrapper (void *wrapper)
{
int i;
for (i = wrapper_preassignments; i < wrapper_cursor; i++) {
if (wrapper_stats[i].wrapper_address == wrapper)
return(i);
}
if (wrapper_cursor < STAT_SIZE) {
int cursor = wrapper_cursor;
wrapper_stats[cursor].wrapper_address = wrapper;
wrapper_cursor++;
return(cursor);
}
report_error("Too many different classes encountered while walking the heap");
return(STAT_SIZE - 1);
}
static int index_for_wrapper (void *wrapper)
{
/*
if (wrapper == &KLpairGYdylanVdylanW)
return(0);
else if (wrapper == &KLsimple_object_vectorGYdylanVdylanW)
return(1);
else
*/
return default_index_for_wrapper(wrapper);
}
void add_stat_for_object (void *object, void* wrapper, int size)
{
int index = index_for_wrapper(wrapper);
wrapper_stats[index].usage_count += 1;
wrapper_stats[index].usage_size += size;
}
static void record_order_1_object (mps_addr_t object, mps_fmt_t format,
mps_pool_t pool, void *p1, size_t p2)
{
void *wrapper = *(void **)object;
if (wrapper && ((int)wrapper & 3) == 0) {
add_stat_for_object(object, wrapper, size_of_object(object, wrapper));
}
}
static int sort_criterion_for_index (int index)
{
return wrapper_stats[index].usage_size;
}
static int biggest_below_value (int value)
{
int i;
int largest_found = -1;
for (i = 0; i < wrapper_cursor; i++) {
int count = sort_criterion_for_index(i);
if ((count < value) && (count > largest_found)) {
largest_found = count;
}
}
return largest_found;
}
static void display_stat_line(char *message,
int count, int size, mps_lib_FILE *stream)
{
mps_lib_fputs_(message, class_name_size, stream);
display_padding_for_string(message, ' ', class_name_size, stream);
display_integer(count, stream);
mps_lib_fputc(' ', stream);
display_integer(size, stream);
mps_lib_fputc('\n', stream);
}
static void display_one_wrapper(int index, mps_lib_FILE *stream)
{
wrapper_stats_t stat = wrapper_stats + index;
char *class_name = class_name_from_wrapper(stat->wrapper_address);
display_stat_line(class_name, stat->usage_count, stat->usage_size, stream);
}
static void display_wrappers_of_size(int size, mps_lib_FILE *stream)
{
int i;
for (i = 0; i < wrapper_cursor; i++) {
int count = sort_criterion_for_index(i);
if (count == size) {
display_one_wrapper(i, stream);
}
}
}
static void display_totals(mps_lib_FILE *stream)
{
int i;
int tot_size = 0;
int tot_count = 0;
for (i = 0; i < wrapper_cursor; i++) {
tot_size += wrapper_stats[i].usage_size;
tot_count += wrapper_stats[i].usage_count;
}
display_stat_line("TOTAL:", tot_count, tot_size, stream);
}
#define very_big 0x7fffffff
void display_wrapper_stats (void)
{
int largest;
mps_lib_FILE *stream = mps_lib_get_stdout();
char *message = "Start of heap statistics";
mps_lib_fputc('\n', stream);
mps_lib_fputs(message, stream);
display_padding_for_string(message, ' ', class_name_size, stream);
mps_lib_fputs(" (count) (size)", stream);
mps_lib_fputs("\n\n", stream);
display_totals(stream);
mps_lib_fputc('\n', stream);
for (largest = biggest_below_value(very_big);
largest >= 0;
largest = biggest_below_value(largest)) {
display_wrappers_of_size(largest, stream);
}
mps_lib_fputs("End of heap statistics\n\n", stream);
}
void display_heap_stats_order_1 (void)
{
clear_wrapper_stats();
mps_arena_formatted_objects_walk(arena, &record_order_1_object, 0, 0);
display_wrapper_stats();
}
syntax highlighted by Code2HTML, v. 0.9.1