From 7f8f8c0b59abe660a5dc773693d56535498ffa19 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 21 Apr 2014 14:52:55 -0600 Subject: [PATCH] dump-memory-stats: add mode to return a tag count --- racket/src/racket/gc2/gc2_dump.h | 7 +- racket/src/racket/gc2/newgc.c | 130 ++++++++++++++++--------------- racket/src/racket/src/salloc.c | 99 +++++++++++++++++------ 3 files changed, 144 insertions(+), 92 deletions(-) diff --git a/racket/src/racket/gc2/gc2_dump.h b/racket/src/racket/gc2/gc2_dump.h index a6260055f8..95ef276d30 100644 --- a/racket/src/racket/gc2/gc2_dump.h +++ b/racket/src/racket/gc2/gc2_dump.h @@ -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); diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 936a906fb2..a94e063d49 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -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); diff --git a/racket/src/racket/src/salloc.c b/racket/src/racket/src/salloc.c index 853efa0c1d..53ff3768ed 100644 --- a/racket/src/racket/src/salloc.c +++ b/racket/src/racket/src/salloc.c @@ -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 ')\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 ')\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 ')\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();