dump-memory-stats: add mode to return a tag count

This commit is contained in:
Matthew Flatt 2014-04-21 14:52:55 -06:00
parent 0985bcda66
commit 7f8f8c0b59
3 changed files with 144 additions and 92 deletions

View File

@ -27,9 +27,10 @@ GC2_EXTERN void GC_dump_variable_stack(void **var_stack,
GC_get_type_name_proc get_type_name,
GC_print_tagged_value_proc print_tagged_value);
# define GC_DUMP_SHOW_DETAILS 0x1
# define GC_DUMP_SHOW_TRACE 0x2
# define GC_DUMP_SHOW_FINALS 0x4
# define GC_DUMP_SHOW_DETAILS 0x1
# define GC_DUMP_SHOW_TRACE 0x2
# define GC_DUMP_SHOW_FINALS 0x4
# define GC_DUMP_SUPPRESS_SUMMARY 0x8
GC2_EXTERN int GC_is_tagged(void *p);
GC2_EXTERN int GC_is_tagged_start(void *p);

View File

@ -3718,74 +3718,76 @@ void GC_dump_with_traces(int flags,
for (ib = gc->immobile_boxes; ib; ib = ib->next)
num_immobiles++;
GCPRINT(GCOUTF, "Begin Racket3m\n");
for (i = 0; i < MAX_DUMP_TAG; i++) {
if (counts[i]) {
char *tn, buf[256];
if (get_type_name)
tn = get_type_name((Type_Tag)i);
else
tn = NULL;
if (!tn) {
sprintf(buf, "unknown,%d", i);
tn = buf;
}
GCPRINT(GCOUTF, " %20.20s: %10" PRIdPTR " %10" PRIdPTR "\n",
tn, counts[i], gcWORDS_TO_BYTES(sizes[i]));
}
}
GCPRINT(GCOUTF, "End Racket3m\n");
GCWARN((GCOUTF, "Generation 0: %" PRIdPTR " of %" PRIdPTR " bytes used\n",
(uintptr_t) gen0_size_in_use(gc), gc->gen0.max_size));
for(i = 0; i < PAGE_TYPES; i++) {
uintptr_t total_use = 0, count = 0;
for(page = gc->gen1_pages[i]; page; page = page->next) {
total_use += page->size;
count++;
}
GCWARN((GCOUTF, "Generation 1 [%s]: %" PRIdPTR " bytes used in %" PRIdPTR " pages\n",
type_name[i], total_use, count));
}
GCWARN((GCOUTF, "Generation 1 [medium]:"));
for (i = 0; i < NUM_MED_PAGE_SIZES; i++) {
if (gc->med_pages[i]) {
intptr_t count = 0, page_count = 0;
for (page = gc->med_pages[i]; page; page = page->next) {
void **start = PPTR(NUM(page->addr) + PREFIX_SIZE);
void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->size);
page_count++;
while(start <= end) {
objhead *info = (objhead *)start;
if (!info->dead) {
count += info->size;
}
start += info->size;
if (!(flags & GC_DUMP_SUPPRESS_SUMMARY)) {
GCPRINT(GCOUTF, "Begin Racket3m\n");
for (i = 0; i < MAX_DUMP_TAG; i++) {
if (counts[i]) {
char *tn, buf[256];
if (get_type_name)
tn = get_type_name((Type_Tag)i);
else
tn = NULL;
if (!tn) {
sprintf(buf, "unknown,%d", i);
tn = buf;
}
GCPRINT(GCOUTF, " %20.20s: %10" PRIdPTR " %10" PRIdPTR "\n",
tn, counts[i], gcWORDS_TO_BYTES(sizes[i]));
}
GCWARN((GCOUTF, " %" PRIdPTR " [%" PRIdPTR "/%" PRIdPTR "]",
count, page_count, gc->med_pages[i]->size));
}
GCPRINT(GCOUTF, "End Racket3m\n");
GCWARN((GCOUTF, "Generation 0: %" PRIdPTR " of %" PRIdPTR " bytes used\n",
(uintptr_t) gen0_size_in_use(gc), gc->gen0.max_size));
for(i = 0; i < PAGE_TYPES; i++) {
uintptr_t total_use = 0, count = 0;
for(page = gc->gen1_pages[i]; page; page = page->next) {
total_use += page->size;
count++;
}
GCWARN((GCOUTF, "Generation 1 [%s]: %" PRIdPTR " bytes used in %" PRIdPTR " pages\n",
type_name[i], total_use, count));
}
GCWARN((GCOUTF, "Generation 1 [medium]:"));
for (i = 0; i < NUM_MED_PAGE_SIZES; i++) {
if (gc->med_pages[i]) {
intptr_t count = 0, page_count = 0;
for (page = gc->med_pages[i]; page; page = page->next) {
void **start = PPTR(NUM(page->addr) + PREFIX_SIZE);
void **end = PPTR(NUM(page->addr) + APAGE_SIZE - page->size);
page_count++;
while(start <= end) {
objhead *info = (objhead *)start;
if (!info->dead) {
count += info->size;
}
start += info->size;
}
}
GCWARN((GCOUTF, " %" PRIdPTR " [%" PRIdPTR "/%" PRIdPTR "]",
count, page_count, gc->med_pages[i]->size));
}
}
GCWARN((GCOUTF, "\n"));
GCWARN((GCOUTF,"\n"));
GCWARN((GCOUTF,"Current memory use: %" PRIdPTR "\n", GC_get_memory_use(NULL)));
GCWARN((GCOUTF,"Peak memory use after a collection: %" PRIdPTR "\n", gc->peak_memory_use));
GCWARN((GCOUTF,"Allocated (+reserved) page sizes: %" PRIdPTR " (+%" PRIdPTR ")\n",
gc->used_pages * APAGE_SIZE,
mmu_memory_allocated(gc->mmu) - (gc->used_pages * APAGE_SIZE)));
GCWARN((GCOUTF,"# of major collections: %" PRIdPTR "\n", gc->num_major_collects));
GCWARN((GCOUTF,"# of minor collections: %" PRIdPTR "\n", gc->num_minor_collects));
GCWARN((GCOUTF,"# of installed finalizers: %i\n", gc->num_fnls));
GCWARN((GCOUTF,"# of traced ephemerons: %i\n", gc->num_last_seen_ephemerons));
GCWARN((GCOUTF,"# of immobile boxes: %i\n", num_immobiles));
}
GCWARN((GCOUTF, "\n"));
GCWARN((GCOUTF,"\n"));
GCWARN((GCOUTF,"Current memory use: %" PRIdPTR "\n", GC_get_memory_use(NULL)));
GCWARN((GCOUTF,"Peak memory use after a collection: %" PRIdPTR "\n", gc->peak_memory_use));
GCWARN((GCOUTF,"Allocated (+reserved) page sizes: %" PRIdPTR " (+%" PRIdPTR ")\n",
gc->used_pages * APAGE_SIZE,
mmu_memory_allocated(gc->mmu) - (gc->used_pages * APAGE_SIZE)));
GCWARN((GCOUTF,"# of major collections: %" PRIdPTR "\n", gc->num_major_collects));
GCWARN((GCOUTF,"# of minor collections: %" PRIdPTR "\n", gc->num_minor_collects));
GCWARN((GCOUTF,"# of installed finalizers: %i\n", gc->num_fnls));
GCWARN((GCOUTF,"# of traced ephemerons: %i\n", gc->num_last_seen_ephemerons));
GCWARN((GCOUTF,"# of immobile boxes: %i\n", num_immobiles));
if (flags & GC_DUMP_SHOW_TRACE) {
print_traced_objects(path_length_limit, get_type_name, print_tagged_value);

View File

@ -1903,6 +1903,14 @@ static void cons_onto_list(void *p)
}
#endif
#if MZ_PRECISE_GC
static int found_counter = 0;
static void increment_found_counter(void *p)
{
found_counter++;
}
#endif
#if MZ_PRECISE_GC_TRACE
static void count_struct_instance(void *p) {
Scheme_Structure *s = (Scheme_Structure *)p;
@ -2155,18 +2163,23 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
void *initial_trace_root = NULL;
int (*inital_root_skip)(void *, size_t) = NULL;
#endif
#if MZ_PRECISE_GC_TRACE
#ifdef MZ_PRECISE_GC
int skip_summary = 0;
int trace_for_tag = 0;
int flags = 0;
int path_length_limit = 10000;
GC_for_each_found_proc for_each_found = NULL;
# else
# define skip_summary 0
# define flags 0
# define trace_for_tag 0
# define for_each_found NULL
#endif
#if MZ_PRECISE_GC_TRACE
int path_length_limit = 10000;
GC_for_each_struct_proc for_each_struct = NULL;
#else
# ifndef USE_TAGGED_ALLOCATION
# define flags 0
# define trace_for_tag 0
# define path_length_limit 10000
# define for_each_found NULL
# define for_each_struct NULL
# define print_tagged_value NULL
# endif
@ -2431,6 +2444,29 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
#else
# ifdef MZ_PRECISE_GC
if (c && SCHEME_SYMBOLP(p[0])) {
if (!strcmp("count", SCHEME_SYM_VAL(p[0]))
&& (c == 2)
&& SCHEME_SYMBOLP(p[1])) {
int i, maxpos;
maxpos = scheme_num_types();
for (i = 0; i < maxpos; i++) {
void *tn;
tn = scheme_get_type_name_or_null(i);
if (tn && !strcmp(tn, SCHEME_SYM_VAL(p[1]))) {
found_counter = 0;
for_each_found = increment_found_counter;
trace_for_tag = i;
flags |= GC_DUMP_SUPPRESS_SUMMARY;
skip_summary = 1;
break;
}
}
}
}
# endif
# if MZ_PRECISE_GC_TRACE
cons_accum_result = scheme_void;
if (c && SCHEME_SYMBOLP(p[0])) {
@ -2530,11 +2566,11 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
cons_accum_result = scheme_null;
flags -= (flags & GC_DUMP_SHOW_TRACE);
}
scheme_console_printf("Begin Dump\n");
#else
scheme_console_printf("Begin Dump\n");
#endif
if (!skip_summary)
scheme_console_printf("Begin Dump\n");
# ifdef MZ_PRECISE_GC
GC_dump_with_traces(flags,
scheme_get_type_name_or_null,
@ -2623,27 +2659,40 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
}
#endif
if (!skip_summary) {
#ifdef MZ_PRECISE_GC
scheme_console_printf("Begin Help\n");
scheme_console_printf(" (dump-memory-stats 'count sym) - return number of instances of type named by sym.\n");
scheme_console_printf(" Example: (dump-memory-stats 'count '<pair>)\n");
# if MZ_PRECISE_GC_TRACE
scheme_console_printf("Begin Help\n");
scheme_console_printf(" (dump-memory-stats sym) - prints paths to instances of type named by sym.\n");
scheme_console_printf(" Example: (dump-memory-stats '<pair>)\n");
scheme_console_printf(" (dump-memory-stats 'struct) - show counts for specific structure types.\n");
scheme_console_printf(" (dump-memory-stats 'fnl) - prints not-yet-finalized objects.\n");
scheme_console_printf(" (dump-memory-stats num) - prints paths to objects with tag num.\n");
scheme_console_printf(" (dump-memory-stats -num) - prints paths to objects of size num.\n");
scheme_console_printf(" (dump-memory-stats sym/num len) - limits path to size len.\n");
scheme_console_printf(" (dump-memory-stats sym/num 'cons) - builds list instead of showing paths.\n");
scheme_console_printf(" (dump-memory-stats 'peek num v) - returns value if num is address of object, v otherwise.\n");
scheme_console_printf(" (dump-memory-stats 'next v) - next tagged object after v, #f if none; start with #f.\n");
scheme_console_printf(" (dump-memory-stats 'addr v) - returns the address of v.\n");
scheme_console_printf(" (dump-memory-stats thread) - shows information about the thread.\n");
scheme_console_printf("End Help\n");
scheme_console_printf(" (dump-memory-stats sym) - prints paths to instances of type named by sym.\n");
scheme_console_printf(" Example: (dump-memory-stats '<pair>)\n");
scheme_console_printf(" (dump-memory-stats 'struct) - show counts for specific structure types.\n");
scheme_console_printf(" (dump-memory-stats 'fnl) - prints not-yet-finalized objects.\n");
scheme_console_printf(" (dump-memory-stats num) - prints paths to objects with tag num.\n");
scheme_console_printf(" (dump-memory-stats -num) - prints paths to objects of size num.\n");
scheme_console_printf(" (dump-memory-stats sym/num len) - limits path to size len.\n");
scheme_console_printf(" (dump-memory-stats sym/num 'cons) - builds list instead of showing paths.\n");
scheme_console_printf(" (dump-memory-stats 'peek num v) - returns value if num is address of object, v otherwise.\n");
scheme_console_printf(" (dump-memory-stats 'next v) - next tagged object after v, #f if none; start with #f.\n");
scheme_console_printf(" (dump-memory-stats 'addr v) - returns the address of v.\n");
scheme_console_printf(" (dump-memory-stats thread) - shows information about the thread.\n");
# endif
scheme_console_printf("End Help\n");
#endif
result = cons_accum_result;
scheme_console_printf("End Dump\n");
}
#ifdef MZ_PRECISE_GC
if (for_each_found == increment_found_counter)
result = scheme_make_integer(found_counter);
# if MZ_PRECISE_GC_TRACE
else
result = cons_accum_result;
cons_accum_result = scheme_void;
# endif
scheme_console_printf("End Dump\n");
#endif
scheme_end_atomic();