[m-rev.] for review: work around bug in reusing memory zones

Peter Wang wangp at students.csse.unimelb.edu.au
Fri Dec 1 13:17:33 AEDT 2006


Estimated hours taken: 2
Branches: main

The code that is supposed to reuse previously allocated memory zones when
allocating new zones is flawed/incomplete.  In stack segment grades it results
in memory zones being retained on the free list unnecessarily, then leaking
leak once the zone is "reused".

runtime/mercury_memory_zones.c:
	Add MR_dealloc_zone_memory() functions to free memory zones.

	Work around the problem above by freeing memory zones when they
	are not needed instead of putting them on the free list.


I didn't test all the variants of MR_dealloc_zone_memory.


Index: runtime/mercury_memory_zones.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory_zones.c,v
retrieving revision 1.29
diff -u -p -r1.29 mercury_memory_zones.c
--- runtime/mercury_memory_zones.c	1 Nov 2006 02:31:14 -0000	1.29
+++ runtime/mercury_memory_zones.c	1 Dec 2006 01:22:16 -0000
@@ -168,6 +168,12 @@ MR_realloc_zone_memory(void *old_base, s
     return ptr;
 }
 
+static void
+MR_dealloc_zone_memory(void *base, size_t size)
+{
+    VirtualFree(base, size, MEM_RELEASE);
+}
+
 #elif defined(MR_CONSERVATIVE_GC)
 
 static void *
@@ -187,6 +193,13 @@ MR_realloc_zone_memory(void *old_base, s
     return ptr;
 }
 
+static void
+MR_dealloc_zone_memory(void *base, size_t size)
+{
+    (void) size;
+    GC_free(base);
+}
+
 #elif defined(MR_HAVE_POSIX_MEMALIGN_XXX)
 
 static void *
@@ -219,6 +232,13 @@ MR_realloc_zone_memory(void *old_base, s
     return ptr;
 }
 
+static void
+MR_dealloc_zone_memory(void *base, size_t size)
+{
+    (void) size;
+    free(base);
+}
+
 #elif defined(MR_HAVE_MEMALIGN)
 
 static void *
@@ -243,6 +263,14 @@ MR_realloc_zone_memory(void *old_base, s
     return ptr;
 }
 
+static void
+MR_dealloc_zone_memory(void *base, size_t size)
+{
+    /* See above about calling free(base) here. */
+    (void) base;
+    (void) size;
+}
+
 #else
 
 static void *
@@ -258,6 +286,13 @@ MR_realloc_zone_memory(void *old_base, s
     return realloc(old_base, new_size);
 }
 
+static void
+MR_dealloc_zone_memory(void *base, size_t size)
+{
+    (void) size;
+    free(base);
+}
+
 #endif
 
 /*
@@ -383,6 +418,26 @@ MR_unget_zone(MR_MemoryZone *zone)
 {
     MR_MemoryZone   *prev;
     MR_MemoryZone   *tmp;
+    size_t          redsize;
+    int             res;
+
+    /*
+    ** XXX MR_construct_zone() does not yet reuse previously allocated memory
+    ** zones properly and simply leaks memory when it tries to do so.  As a
+    ** workaround, we never put memory zones on the free list and deallocate
+    ** them immediately here.
+    */
+
+    if (1) {
+        redsize = zone->MR_zone_redzone_size;
+        res = MR_protect_pages((char *) zone->MR_zone_redzone,
+            redsize + MR_unit, NORMAL_PROT);
+        assert(res == 0);
+
+        MR_dealloc_zone_memory(zone->MR_zone_bottom,
+            ((char *) zone->MR_zone_top) - ((char *) zone->MR_zone_bottom));
+        return;
+    }
 
     /*
     ** Find the zone on the used list, and unlink it from the list,
@@ -484,6 +539,9 @@ MR_construct_zone(const char *name, int 
     zone->MR_zone_handler = handler;
 #endif /* MR_CHECK_OVERFLOW_VIA_MPROTECT */
 
+    /*
+    ** XXX this causes a memory leak if `zone' was not newly allocated.
+    */
     zone->MR_zone_bottom = base;
 
 #ifdef  MR_PROTECTPAGE
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list