[svn:parrot] r41100 - trunk/src/gc

chromatic at svn.parrot.org chromatic at svn.parrot.org
Mon Sep 7 07:28:27 UTC 2009


Author: chromatic
Date: Mon Sep  7 07:28:24 2009
New Revision: 41100
URL: https://trac.parrot.org/parrot/changeset/41100

Log:
[GC] Fixed a memory leak in the GC by freeing attribute pools during final
destruction.

Modified:
   trunk/src/gc/api.c
   trunk/src/gc/mark_sweep.c

Modified: trunk/src/gc/api.c
==============================================================================
--- trunk/src/gc/api.c	Mon Sep  7 06:28:02 2009	(r41099)
+++ trunk/src/gc/api.c	Mon Sep  7 07:28:24 2009	(r41100)
@@ -260,13 +260,13 @@
 Parrot_gc_initialize(PARROT_INTERP, ARGIN(void *stacktop))
 {
     ASSERT_ARGS(Parrot_gc_initialize)
-    interp->arena_base = mem_allocate_zeroed_typed(Arenas);
-    interp->arena_base->sized_header_pools = NULL;
-    interp->arena_base->num_sized = 0;
-    interp->arena_base->attrib_pools = NULL;
-    interp->arena_base->num_attribs = 0;
 
-    interp->lo_var_ptr = stacktop;
+    interp->arena_base                     = mem_allocate_zeroed_typed(Arenas);
+    interp->arena_base->num_sized          = 0;
+    interp->arena_base->num_attribs        = 0;
+    interp->arena_base->attrib_pools       = NULL;
+    interp->arena_base->sized_header_pools = NULL;
+    interp->lo_var_ptr                     = stacktop;
 
 #if PARROT_GC_MS
     Parrot_gc_ms_init(interp);
@@ -1014,9 +1014,30 @@
     }
 
     mem_internal_free(interp->arena_base->sized_header_pools);
-    if (interp->arena_base->attrib_pools)
+
+    if (interp->arena_base->attrib_pools) {
+        unsigned int i;
+        for (i = 0; i < interp->arena_base->num_attribs; i++) {
+            PMC_Attribute_Pool  *pool  = interp->arena_base->attrib_pools[i];
+            PMC_Attribute_Arena *arena;
+
+            if (!pool)
+                continue;
+
+            arena = pool->top_arena;
+
+            while (arena) {
+                PMC_Attribute_Arena *next = arena->next;
+                mem_internal_free(arena);
+                arena = next;
+            }
+            mem_internal_free(pool);
+        }
+
         mem_internal_free(interp->arena_base->attrib_pools);
-    interp->arena_base->attrib_pools = NULL;
+    }
+
+    interp->arena_base->attrib_pools       = NULL;
     interp->arena_base->sized_header_pools = NULL;
 }
 

Modified: trunk/src/gc/mark_sweep.c
==============================================================================
--- trunk/src/gc/mark_sweep.c	Mon Sep  7 06:28:02 2009	(r41099)
+++ trunk/src/gc/mark_sweep.c	Mon Sep  7 07:28:24 2009	(r41100)
@@ -1148,37 +1148,46 @@
     pool->num_free_objects++;
 }
 
+
 static void
 Parrot_gc_allocate_new_attributes_arena(PARROT_INTERP, ARGMOD(PMC_Attribute_Pool *pool))
 {
     ASSERT_ARGS(Parrot_gc_allocate_new_attributes_arena)
-    const size_t num_items = pool->objects_per_alloc;
-    const size_t item_size = pool->attr_size;
-    const size_t total_size = sizeof (PMC_Attribute_Arena) + (item_size * num_items);
-    size_t i;
     PMC_Attribute_Free_List *list, *next, *first;
+
+    size_t       i;
+    const size_t num_items  = pool->objects_per_alloc;
+    const size_t item_size  = pool->attr_size;
+    const size_t total_size = sizeof (PMC_Attribute_Arena)
+                            + (item_size * num_items);
+
     PMC_Attribute_Arena * const new_arena = (PMC_Attribute_Arena *)mem_internal_allocate(
         total_size);
+
     new_arena->prev = NULL;
     new_arena->next = pool->top_arena;
     pool->top_arena = new_arena;
-    first = next = (PMC_Attribute_Free_List *)(new_arena + 1);
+    first           = next = (PMC_Attribute_Free_List *)(new_arena + 1);
+
 #if GC_USE_LAZY_ALLOCATOR
-    pool->newfree = first;
-    pool->newlast = (PMC_Attribute_Free_List*)((char*)first + (item_size * num_items));
+    pool->newfree   = first;
+    pool->newlast   = (PMC_Attribute_Free_List *)((char *)first + (item_size * num_items));
 #else
     for (i = 0; i < num_items; i++) {
-        list = next;
+        list       = next;
         list->next = (PMC_Attribute_Free_List *)((char *)list + item_size);
-        next = list->next;
+        next       = list->next;
     }
-    list->next = pool->free_list;
+
+    list->next      = pool->free_list;
     pool->free_list = first;
 #endif
+
     pool->num_free_objects += num_items;
     pool->total_objects    += num_items;
 }
 
+
 PARROT_CANNOT_RETURN_NULL
 PMC_Attribute_Pool *
 Parrot_gc_get_attribute_pool(PARROT_INTERP, size_t attrib_size)
@@ -1192,7 +1201,7 @@
                                       : attrib_size;
     const size_t               idx    = size - sizeof (void *);
 
-    if (pools == NULL) {
+    if (!pools) {
         const size_t total_length = idx + GC_ATTRIB_POOLS_HEADROOM;
         const size_t total_size   = (total_length + 1) * sizeof (void *);
         /* Allocate more then we strictly need, hoping that we can reduce the
@@ -1200,8 +1209,9 @@
         pools = (PMC_Attribute_Pool **)mem_internal_allocate(total_size);
         memset(pools, 0, total_size);
         arenas->attrib_pools = pools;
-        arenas->num_attribs = total_length;
+        arenas->num_attribs  = total_length;
     }
+
     if (arenas->num_attribs <= idx) {
         const size_t total_length = idx + GC_ATTRIB_POOLS_HEADROOM;
         const size_t total_size   = total_length * sizeof (void *);
@@ -1213,8 +1223,10 @@
         arenas->attrib_pools = pools;
         arenas->num_attribs = total_length;
     }
-    if (pools[idx] == NULL)
+
+    if (!pools[idx])
         pools[idx] = Parrot_gc_create_attrib_pool(interp, size);
+
     return pools[idx];
 }
 
@@ -1227,12 +1239,14 @@
         (GC_FIXED_SIZE_POOL_SIZE - sizeof (PMC_Attribute_Arena)) / attrib_size;
     const size_t num_objs = (num_objs_raw == 0)?(1):(num_objs_raw);
     PMC_Attribute_Pool * const newpool = mem_internal_allocate_typed(PMC_Attribute_Pool);
-    newpool->attr_size = attrib_size;
-    newpool->total_objects = 0;
+
+    newpool->attr_size         = attrib_size;
+    newpool->total_objects     = 0;
     newpool->objects_per_alloc = num_objs;
-    newpool->num_free_objects = 0;
-    newpool->free_list = NULL;
-    newpool->top_arena = NULL;
+    newpool->num_free_objects  = 0;
+    newpool->free_list         = NULL;
+    newpool->top_arena         = NULL;
+
     return newpool;
 }
 


More information about the parrot-commits mailing list