From: Petter Urkedal Date: Sun, 4 May 2008 16:12:52 +0000 (+0200) Subject: Fixed memory leak issue with unconditional marking. X-Git-Tag: gc7_3alpha2~320^2^2~8^2~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3582f8334edea1b95dbb117f7aff52b5332ad358;p=gc Fixed memory leak issue with unconditional marking. --- diff --git a/reclaim.c b/reclaim.c index c6a7f84c..b55860cc 100644 --- a/reclaim.c +++ b/reclaim.c @@ -42,6 +42,10 @@ STATIC unsigned GC_n_leaked = 0; GC_INNER GC_bool GC_have_errors = FALSE; +#if !defined(EAGER_SWEEP) && defined(MARK_UNCONDITIONALLY) +void GC_reclaim_unconditionally_marked(void); +#endif + GC_INLINE void GC_add_leaked(ptr_t leaked) { # ifndef SHORT_DBG_HDRS @@ -609,6 +613,11 @@ GC_INNER void GC_start_reclaim(GC_bool report_if_found) /* This is a very stupid thing to do. We make it possible anyway, */ /* so that you can convince yourself that it really is very stupid. */ GC_reclaim_all((GC_stop_func)0, FALSE); +# elif defined(MARK_UNCONDITIONALLY) + /* However, make sure to clear reclaimable objects of kinds with */ + /* unconditional marking enabled before we do any significant */ + /* marking work. */ + GC_reclaim_unconditionally_marked(); # endif # if defined(PARALLEL_MARK) GC_ASSERT(0 == GC_fl_builder_count); @@ -695,3 +704,33 @@ GC_INNER GC_bool GC_reclaim_all(GC_stop_func stop_func, GC_bool ignore_old) # endif return(TRUE); } + +#if !defined(EAGER_SWEEP) && defined(MARK_UNCONDITIONALLY) +/* Part of disclaim patch. This could be merged with the above, but I don't + * want to clobber the original source too much by changing the prototype and + * testing for defined(MARK_UNCONDITIONALLY). */ +void GC_reclaim_unconditionally_marked(void) +{ + word sz; + unsigned kind; + hdr * hhdr; + struct hblk * hbp; + struct obj_kind * ok; + struct hblk ** rlp; + struct hblk ** rlh; + for (kind = 0; kind < GC_n_kinds; kind++) { + ok = &(GC_obj_kinds[kind]); + if (!ok->ok_mark_unconditionally) continue; + rlp = ok->ok_reclaim_list; + if (rlp == 0) continue; + for (sz = 1; sz <= MAXOBJGRANULES; sz++) { + rlh = rlp + sz; + while ((hbp = *rlh) != 0) { + hhdr = HDR(hbp); + *rlh = hhdr->hb_next; + GC_reclaim_small_nonempty_block(hbp, FALSE, &GC_bytes_found); + } + } + } +} +#endif diff --git a/tests/disclaim_bench.c b/tests/disclaim_bench.c index af2375eb..1c90d839 100644 --- a/tests/disclaim_bench.c +++ b/tests/disclaim_bench.c @@ -1,11 +1,12 @@ #include "gc_disclaim.h" +#include "atomic_ops.h" #include #include #include #include #include -static int nf = 0; +static AO_t free_count = 0; typedef struct testobj_s *testobj_t; struct testobj_s { @@ -16,13 +17,13 @@ struct testobj_s { void testobj_finalize(void *obj, void *carg) { #define obj ((testobj_t)obj) - ++*(int *)carg; + AO_fetch_and_add1((AO_t *)carg); assert(obj->i++ == 109); #undef obj } static struct GC_finalizer_closure fclos = { testobj_finalize, - &nf + &free_count }; testobj_t testobj_new(int model) @@ -31,7 +32,7 @@ testobj_t testobj_new(int model) switch (model) { case 0: obj = GC_malloc(sizeof(struct testobj_s)); - GC_register_finalizer_no_order(obj, testobj_finalize, &nf, + GC_register_finalizer_no_order(obj, testobj_finalize, &free_count, NULL, NULL); break; case 1: @@ -43,14 +44,14 @@ testobj_t testobj_new(int model) default: abort(); } + assert(obj->i == 0 && obj->keep_link == NULL); obj->i = 109; - obj->keep_link = NULL; return obj; } #define ALLOC_CNT (4*1024*1024) -#define KEEP_CNT (32*1024) +#define KEEP_CNT ( 32*1024) int main(int argc, char **argv) { @@ -106,7 +107,7 @@ int main(int argc, char **argv) t /= CLOCKS_PER_SEC; if (model < 2) printf("%20s: %12.4lf %12lg %12lg\n", model_str[model], - nf/(double)ALLOC_CNT, t, t/nf); + free_count/(double)ALLOC_CNT, t, t/free_count); else printf("%20s: 0 %12lg N/A\n", model_str[model], t);