X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=boehm-gc%2Freclaim.c;h=864c0cad8afa40c5cf61cb1b47fff170036316dd;hb=745dbd8cb5d93fe40be03434c93184c2cd30365b;hp=846215edb4f87370ae33b3e939bd5358535c6ef7;hpb=0cc01484c3f8c9ec4fec760501aec318bc199adf;p=pf3gnuchains%2Fgcc-fork.git diff --git a/boehm-gc/reclaim.c b/boehm-gc/reclaim.c index 846215edb4f..864c0cad8af 100644 --- a/boehm-gc/reclaim.c +++ b/boehm-gc/reclaim.c @@ -27,23 +27,61 @@ signed_word GC_mem_found = 0; /* nonzero. */ #endif /* PARALLEL_MARK */ -static void report_leak(p, sz) -ptr_t p; -word sz; +/* We defer printing of leaked objects until we're done with the GC */ +/* cycle, since the routine for printing objects needs to run outside */ +/* the collector, e.g. without the allocation lock. */ +#define MAX_LEAKED 40 +ptr_t GC_leaked[MAX_LEAKED]; +unsigned GC_n_leaked = 0; + +GC_bool GC_have_errors = FALSE; + +void GC_add_leaked(leaked) +ptr_t leaked; { - if (HDR(p) -> hb_obj_kind == PTRFREE) { - GC_err_printf0("Leaked atomic object at "); - } else { - GC_err_printf0("Leaked composite object at "); + if (GC_n_leaked < MAX_LEAKED) { + GC_have_errors = TRUE; + GC_leaked[GC_n_leaked++] = leaked; + /* Make sure it's not reclaimed this cycle */ + GC_set_mark_bit(leaked); } - GC_print_heap_obj(p); - GC_err_printf0("\n"); } +static GC_bool printing_errors = FALSE; +/* Print all objects on the list after printing any smashed objs. */ +/* Clear both lists. */ +void GC_print_all_errors () +{ + unsigned i; + + LOCK(); + if (printing_errors) { + UNLOCK(); + return; + } + printing_errors = TRUE; + UNLOCK(); + if (GC_debugging_started) GC_print_all_smashed(); + for (i = 0; i < GC_n_leaked; ++i) { + ptr_t p = GC_leaked[i]; + if (HDR(p) -> hb_obj_kind == PTRFREE) { + GC_err_printf0("Leaked atomic object at "); + } else { + GC_err_printf0("Leaked composite object at "); + } + GC_print_heap_obj(p); + GC_err_printf0("\n"); + GC_free(p); + GC_leaked[i] = 0; + } + GC_n_leaked = 0; + printing_errors = FALSE; +} + + # define FOUND_FREE(hblk, word_no) \ { \ - report_leak((ptr_t)hblk + WORDS_TO_BYTES(word_no), \ - HDR(hblk) -> hb_sz); \ + GC_add_leaked((ptr_t)hblk + WORDS_TO_BYTES(word_no)); \ } /* @@ -850,7 +888,7 @@ void GC_print_block_list() { struct Print_stats pstats; - GC_printf0("(kind(0=ptrfree,1=normal,2=unc.,3=stubborn):size_in_bytes, #_marks_set)\n"); + GC_printf1("(kind(0=ptrfree,1=normal,2=unc.,%lu=stubborn):size_in_bytes, #_marks_set)\n", STUBBORN); pstats.number_of_blocks = 0; pstats.total_bytes = 0; GC_apply_to_all_blocks(GC_print_block_descr, (word)&pstats); @@ -862,6 +900,25 @@ void GC_print_block_list() #endif /* NO_DEBUGGING */ /* + * Clear all obj_link pointers in the list of free objects *flp. + * Clear *flp. + * This must be done before dropping a list of free gcj-style objects, + * since may otherwise end up with dangling "descriptor" pointers. + * It may help for other pointer-containing objects. + */ +void GC_clear_fl_links(flp) +ptr_t *flp; +{ + ptr_t next = *flp; + + while (0 != next) { + *flp = 0; + flp = &(obj_link(next)); + next = *flp; + } +} + +/* * Perform GC_reclaim_block on the entire heap, after first clearing * small object free lists (if we are not just looking for leaks). */ @@ -875,17 +932,24 @@ int report_if_found; /* Abort if a GC_reclaimable object is found */ # endif /* Clear reclaim- and free-lists */ for (kind = 0; kind < GC_n_kinds; kind++) { - register ptr_t *fop; - register ptr_t *lim; - register struct hblk ** rlp; - register struct hblk ** rlim; - register struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list; + ptr_t *fop; + ptr_t *lim; + struct hblk ** rlp; + struct hblk ** rlim; + struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list; + GC_bool should_clobber = (GC_obj_kinds[kind].ok_descriptor != 0); if (rlist == 0) continue; /* This kind not used. */ if (!report_if_found) { lim = &(GC_obj_kinds[kind].ok_freelist[MAXOBJSZ+1]); for( fop = GC_obj_kinds[kind].ok_freelist; fop < lim; fop++ ) { - *fop = 0; + if (*fop != 0) { + if (should_clobber) { + GC_clear_fl_links(fop); + } else { + *fop = 0; + } + } } } /* otherwise free list objects are marked, */ /* and its safe to leave them */