]> granicus.if.org Git - gc/commitdiff
Fixed memory leak issue with unconditional marking.
authorPetter Urkedal <urkedal@nbi.dk>
Sun, 4 May 2008 16:12:52 +0000 (18:12 +0200)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 30 Sep 2011 13:34:46 +0000 (17:34 +0400)
reclaim.c
tests/disclaim_bench.c

index f4be205d55d4be5915c8f3b91c8fb80ee8ef7529..da25f8b3b93e8761cfd26e2d54f437c8c398e456 100644 (file)
--- 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
index af2375eb89609331be0d40fa25d381a2f3e5153f..1c90d839060fd4d0f5e61f5d7dbe74e333693362 100644 (file)
@@ -1,11 +1,12 @@
 #include "gc_disclaim.h"
+#include "atomic_ops.h"
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
 
-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);