GC backtrace: add limited support for distinguishing new and old objects
This commit is contained in:
parent
d9efa6cc9b
commit
21d925d1f0
|
@ -95,7 +95,8 @@ static void *print_out_pointer(const char *prefix, void *p,
|
||||||
|
|
||||||
static void print_traced_objects(int path_length_limit,
|
static void print_traced_objects(int path_length_limit,
|
||||||
GC_get_type_name_proc get_type_name,
|
GC_get_type_name_proc get_type_name,
|
||||||
GC_print_tagged_value_proc print_tagged_value)
|
GC_print_tagged_value_proc print_tagged_value,
|
||||||
|
GC_print_traced_filter_proc print_traced_filter)
|
||||||
{
|
{
|
||||||
int i, j, k, dp = 0, counter, each;
|
int i, j, k, dp = 0, counter, each;
|
||||||
# define DITTO_BUFFER_SIZE 16
|
# define DITTO_BUFFER_SIZE 16
|
||||||
|
@ -110,33 +111,35 @@ static void print_traced_objects(int path_length_limit,
|
||||||
int limit = path_length_limit;
|
int limit = path_length_limit;
|
||||||
int kind = 0;
|
int kind = 0;
|
||||||
p = found_objects[i];
|
p = found_objects[i];
|
||||||
p = print_out_pointer("==* ", p, get_type_name, print_tagged_value, &kind);
|
if (print_traced_filter(p)) {
|
||||||
|
p = print_out_pointer("==* ", p, get_type_name, print_tagged_value, &kind);
|
||||||
|
|
||||||
j = 0; counter = 0; each = 1;
|
j = 0; counter = 0; each = 1;
|
||||||
while (p && limit) {
|
while (p && limit) {
|
||||||
for (k = 0; k < DITTO_BUFFER_SIZE; k++) {
|
for (k = 0; k < DITTO_BUFFER_SIZE; k++) {
|
||||||
if (ditto[k] == p) {
|
if (ditto[k] == p) {
|
||||||
GCPRINT(GCOUTF, " <- %p: DITTO\n", p);
|
GCPRINT(GCOUTF, " <- %p: DITTO\n", p);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (p) {
|
|
||||||
if (j < DITTO_BUFFER_SIZE) {
|
|
||||||
/* Rememebr the 1st 2nd, 4th, 8th, etc. */
|
|
||||||
counter++;
|
|
||||||
if (counter == each) {
|
|
||||||
ditto[(j + dp) % DITTO_BUFFER_SIZE] = p;
|
|
||||||
j++;
|
|
||||||
each *= 2;
|
|
||||||
counter = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p = print_out_pointer(" <- ", p, get_type_name, print_tagged_value, &kind);
|
if (p) {
|
||||||
limit--;
|
if (j < DITTO_BUFFER_SIZE) {
|
||||||
|
/* Rememebr the 1st 2nd, 4th, 8th, etc. */
|
||||||
|
counter++;
|
||||||
|
if (counter == each) {
|
||||||
|
ditto[(j + dp) % DITTO_BUFFER_SIZE] = p;
|
||||||
|
j++;
|
||||||
|
each *= 2;
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = print_out_pointer(" <- ", p, get_type_name, print_tagged_value, &kind);
|
||||||
|
limit--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
dp = (j % DITTO_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
dp = (j % DITTO_BUFFER_SIZE);
|
|
||||||
}
|
}
|
||||||
GCPRINT(GCOUTF, "End Trace\n");
|
GCPRINT(GCOUTF, "End Trace\n");
|
||||||
--GC_instance->avoid_collection;
|
--GC_instance->avoid_collection;
|
||||||
|
|
|
@ -11,11 +11,13 @@ typedef void (*GC_for_each_struct_proc)(void *p);
|
||||||
typedef void (*GC_print_tagged_value_proc)(const char *prefix,
|
typedef void (*GC_print_tagged_value_proc)(const char *prefix,
|
||||||
void *v, uintptr_t diff, int max_w,
|
void *v, uintptr_t diff, int max_w,
|
||||||
const char *suffix);
|
const char *suffix);
|
||||||
|
typedef int (*GC_print_traced_filter_proc)(void *p);
|
||||||
|
|
||||||
GC2_EXTERN void GC_dump_with_traces(int flags,
|
GC2_EXTERN void GC_dump_with_traces(int flags,
|
||||||
GC_get_type_name_proc get_type_name,
|
GC_get_type_name_proc get_type_name,
|
||||||
GC_for_each_found_proc for_each_found,
|
GC_for_each_found_proc for_each_found,
|
||||||
short min_trace_for_tag, short max_trace_for_tag,
|
short min_trace_for_tag, short max_trace_for_tag,
|
||||||
|
GC_print_traced_filter_proc print_traced_filter,
|
||||||
GC_print_tagged_value_proc print_tagged_value,
|
GC_print_tagged_value_proc print_tagged_value,
|
||||||
int path_length_limit,
|
int path_length_limit,
|
||||||
GC_for_each_struct_proc for_each_struct);
|
GC_for_each_struct_proc for_each_struct);
|
||||||
|
|
|
@ -3690,7 +3690,7 @@ const char *trace_source_kind(int kind)
|
||||||
# define reset_object_traces() /* */
|
# define reset_object_traces() /* */
|
||||||
# define clear_object_traces() /* */
|
# define clear_object_traces() /* */
|
||||||
# define register_traced_object(p) /* */
|
# define register_traced_object(p) /* */
|
||||||
# define print_traced_objects(x, q, z) /* */
|
# define print_traced_objects(x, q, z, w) /* */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_DUMP_TAG 256
|
#define MAX_DUMP_TAG 256
|
||||||
|
@ -3699,6 +3699,7 @@ void GC_dump_with_traces(int flags,
|
||||||
GC_get_type_name_proc get_type_name,
|
GC_get_type_name_proc get_type_name,
|
||||||
GC_for_each_found_proc for_each_found,
|
GC_for_each_found_proc for_each_found,
|
||||||
short min_trace_for_tag, short max_trace_for_tag,
|
short min_trace_for_tag, short max_trace_for_tag,
|
||||||
|
GC_print_traced_filter_proc print_traced_filter,
|
||||||
GC_print_tagged_value_proc print_tagged_value,
|
GC_print_tagged_value_proc print_tagged_value,
|
||||||
int path_length_limit,
|
int path_length_limit,
|
||||||
GC_for_each_struct_proc for_each_struct)
|
GC_for_each_struct_proc for_each_struct)
|
||||||
|
@ -3876,7 +3877,7 @@ void GC_dump_with_traces(int flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & GC_DUMP_SHOW_TRACE) {
|
if (flags & GC_DUMP_SHOW_TRACE) {
|
||||||
print_traced_objects(path_length_limit, get_type_name, print_tagged_value);
|
print_traced_objects(path_length_limit, get_type_name, print_tagged_value, print_traced_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_object_traces();
|
clear_object_traces();
|
||||||
|
@ -3887,7 +3888,7 @@ void GC_dump_with_traces(int flags,
|
||||||
|
|
||||||
void GC_dump(void)
|
void GC_dump(void)
|
||||||
{
|
{
|
||||||
GC_dump_with_traces(0, NULL, NULL, 0, -1, NULL, 0, NULL);
|
GC_dump_with_traces(0, NULL, NULL, 0, -1, NULL, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MZ_GC_BACKTRACE
|
#ifdef MZ_GC_BACKTRACE
|
||||||
|
|
|
@ -2907,7 +2907,7 @@ print(Scheme_Object *obj, int notdisplay, int compact, Scheme_Hash_Table *ht,
|
||||||
notdisplay, 1, ht, mt, pp);
|
notdisplay, 1, ht, mt, pp);
|
||||||
} else if (pp->print_unreadable) {
|
} else if (pp->print_unreadable) {
|
||||||
Scheme_Stx *stx = (Scheme_Stx *)obj;
|
Scheme_Stx *stx = (Scheme_Stx *)obj;
|
||||||
if ((stx->srcloc->line >= 0) || (stx->srcloc->pos >= 0)) {
|
if (stx->srcloc && ((stx->srcloc->line >= 0) || (stx->srcloc->pos >= 0))) {
|
||||||
print_utf8_string(pp, "#<syntax:", 0, 9);
|
print_utf8_string(pp, "#<syntax:", 0, 9);
|
||||||
if (stx->srcloc->src && SCHEME_PATHP(stx->srcloc->src)) {
|
if (stx->srcloc->src && SCHEME_PATHP(stx->srcloc->src)) {
|
||||||
print_utf8_string(pp, SCHEME_BYTE_STR_VAL(stx->srcloc->src), 0, SCHEME_BYTE_STRLEN_VAL(stx->srcloc->src));
|
print_utf8_string(pp, SCHEME_BYTE_STR_VAL(stx->srcloc->src), 0, SCHEME_BYTE_STRLEN_VAL(stx->srcloc->src));
|
||||||
|
|
|
@ -1906,6 +1906,42 @@ static void cons_onto_list(void *p)
|
||||||
{
|
{
|
||||||
cons_accum_result = scheme_make_pair((Scheme_Object *)p, cons_accum_result);
|
cons_accum_result = scheme_make_pair((Scheme_Object *)p, cons_accum_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int print_all_traced(void *p) { return 1; }
|
||||||
|
|
||||||
|
static int traced_buffer_counter, traced_buffer_size;
|
||||||
|
static void **traced_buffer;
|
||||||
|
|
||||||
|
static int record_traced(void *p)
|
||||||
|
{
|
||||||
|
if (traced_buffer_counter == traced_buffer_size) {
|
||||||
|
void **b2;
|
||||||
|
int new_size = (traced_buffer_size
|
||||||
|
? (2 * traced_buffer_size)
|
||||||
|
: 512);
|
||||||
|
if (!traced_buffer) REGISTER_SO(traced_buffer);
|
||||||
|
b2 = scheme_malloc(sizeof(void*) * new_size);
|
||||||
|
memcpy(b2, traced_buffer, sizeof(void*)*traced_buffer_size);
|
||||||
|
traced_buffer = b2;
|
||||||
|
traced_buffer_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
traced_buffer[traced_buffer_counter++] = p;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int record_traced_and_print_new(void *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < traced_buffer_counter; i++) {
|
||||||
|
if (p == traced_buffer[i])
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return record_traced(p);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MZ_PRECISE_GC
|
#if MZ_PRECISE_GC
|
||||||
|
@ -2173,6 +2209,7 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
|
||||||
int trace_for_tag = 0;
|
int trace_for_tag = 0;
|
||||||
int dump_flags = 0;
|
int dump_flags = 0;
|
||||||
GC_for_each_found_proc for_each_found = NULL;
|
GC_for_each_found_proc for_each_found = NULL;
|
||||||
|
GC_print_traced_filter_proc maybe_print_traced_filter = NULL;
|
||||||
# else
|
# else
|
||||||
# define skip_summary 0
|
# define skip_summary 0
|
||||||
# define dump_flags 0
|
# define dump_flags 0
|
||||||
|
@ -2190,6 +2227,10 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MZ_PRECISE_GC) && MZ_PRECISE_GC_TRACE
|
||||||
|
maybe_print_traced_filter = print_all_traced;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Syntax-object debugging support: */
|
/* Syntax-object debugging support: */
|
||||||
if ((c == 1) && SCHEME_STXP(p[0])) {
|
if ((c == 1) && SCHEME_STXP(p[0])) {
|
||||||
|
@ -2490,6 +2531,10 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
|
||||||
if (tn && !strcmp(tn, s)) {
|
if (tn && !strcmp(tn, s)) {
|
||||||
trace_for_tag = i;
|
trace_for_tag = i;
|
||||||
dump_flags |= GC_DUMP_SHOW_TRACE;
|
dump_flags |= GC_DUMP_SHOW_TRACE;
|
||||||
|
if ((c > 1)
|
||||||
|
&& SCHEME_SYMBOLP(p[1])
|
||||||
|
&& !strcmp(SCHEME_SYM_VAL(p[1]), "new"))
|
||||||
|
maybe_print_traced_filter = record_traced_and_print_new;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2581,6 +2626,7 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
|
||||||
scheme_get_type_name_or_null,
|
scheme_get_type_name_or_null,
|
||||||
for_each_found,
|
for_each_found,
|
||||||
trace_for_tag, trace_for_tag,
|
trace_for_tag, trace_for_tag,
|
||||||
|
maybe_print_traced_filter,
|
||||||
print_tagged_value,
|
print_tagged_value,
|
||||||
path_length_limit,
|
path_length_limit,
|
||||||
for_each_struct);
|
for_each_struct);
|
||||||
|
@ -2670,8 +2716,9 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[])
|
||||||
scheme_console_printf(" (dump-memory-stats 'count sym) - return number of instances of type named by sym.\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");
|
scheme_console_printf(" Example: (dump-memory-stats 'count '<pair>)\n");
|
||||||
# if MZ_PRECISE_GC_TRACE
|
# if MZ_PRECISE_GC_TRACE
|
||||||
scheme_console_printf(" (dump-memory-stats sym) - prints paths to instances of type named by sym.\n");
|
scheme_console_printf(" (dump-memory-stats sym ['new]) - prints paths to instances of type named by sym.\n");
|
||||||
scheme_console_printf(" Example: (dump-memory-stats '<pair>)\n");
|
scheme_console_printf(" Example: (dump-memory-stats '<pair>)\n");
|
||||||
|
scheme_console_printf(" If 'new, all will be retrined, only new paths will be shown\n");
|
||||||
scheme_console_printf(" (dump-memory-stats 'struct) - show counts for specific structure types.\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 '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 with tag num.\n");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user