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

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Thu Oct 22 00:59:26 UTC 2009


Author: whiteknight
Date: Thu Oct 22 00:59:24 2009
New Revision: 42004
URL: https://trac.parrot.org/parrot/changeset/42004

Log:
[gc] a few modest improvements to the fixed-size allocator. Reduce the number of unnecessary redundant checks that we were doing on each allocation by doing better initialization

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

Modified: trunk/src/gc/api.c
==============================================================================
--- trunk/src/gc/api.c	Thu Oct 22 00:27:00 2009	(r42003)
+++ trunk/src/gc/api.c	Thu Oct 22 00:59:24 2009	(r42004)
@@ -336,6 +336,7 @@
 
     initialize_var_size_pools(interp);
     initialize_fixed_size_pools(interp);
+    Parrot_gc_initialize_fixed_size_pools(interp, GC_NUM_INITIAL_FIXED_SIZE_POOLS);
 }
 
 /*

Modified: trunk/src/gc/gc_private.h
==============================================================================
--- trunk/src/gc/gc_private.h	Thu Oct 22 00:27:00 2009	(r42003)
+++ trunk/src/gc/gc_private.h	Thu Oct 22 00:59:24 2009	(r42004)
@@ -52,6 +52,7 @@
 
 #define CONSTANT_PMC_HEADERS_PER_ALLOC 4096 / sizeof (PMC)
 #define GET_SIZED_POOL_IDX(x) ((x) / sizeof (void *))
+#define GC_NUM_INITIAL_FIXED_SIZE_POOLS 128
 
 
 /* these values are used for the attribute allocator */
@@ -346,6 +347,10 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(* pool);
 
+void Parrot_gc_initialize_fixed_size_pools(PARROT_INTERP,
+    size_t init_num_pools)
+        __attribute__nonnull__(1);
+
 void Parrot_gc_run_init(PARROT_INTERP)
         __attribute__nonnull__(1);
 
@@ -393,6 +398,9 @@
      __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_Parrot_gc_initialize_fixed_size_pools \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_gc_run_init __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_Parrot_gc_sweep_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\

Modified: trunk/src/gc/mark_sweep.c
==============================================================================
--- trunk/src/gc/mark_sweep.c	Thu Oct 22 00:27:00 2009	(r42003)
+++ trunk/src/gc/mark_sweep.c	Thu Oct 22 00:59:24 2009	(r42004)
@@ -82,7 +82,7 @@
 
 PARROT_CANNOT_RETURN_NULL
 static PMC_Attribute_Pool * Parrot_gc_create_attrib_pool(PARROT_INTERP,
-    size_t attrib_size)
+    size_t attrib_idx)
         __attribute__nonnull__(1);
 
 #define ASSERT_ARGS_free_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -972,7 +972,7 @@
 allocate. If the pool does not exist, create it.
 
 =item C<static PMC_Attribute_Pool * Parrot_gc_create_attrib_pool(PARROT_INTERP,
-size_t attrib_size)>
+size_t attrib_idx)>
 
 Create a new pool for fixed-sized data items with the given C<attrib_size>.
 
@@ -988,22 +988,14 @@
 {
     ASSERT_ARGS(Parrot_gc_get_attributes_from_pool)
     PMC_Attribute_Free_List *item;
-    if (pool->top_arena == NULL
 
 #if GC_USE_LAZY_ALLOCATOR
-     || (pool->newfree == NULL && pool->free_list == NULL))
-#else
-
-     || pool->free_list == NULL)
-#endif
+    if (pool->newfree == NULL && pool->free_list == NULL)
         Parrot_gc_allocate_new_attributes_arena(interp, pool);
-
-
-#if GC_USE_LAZY_ALLOCATOR
     if (pool->newfree) {
         item          = pool->newfree;
         pool->newfree = (PMC_Attribute_Free_List *)
-                            ((char *)(pool->newfree) + pool->attr_size);
+                        ((char *)(pool->newfree) + pool->attr_size);
         if (pool->newfree >= pool->newlast)
             pool->newfree = NULL;
     }
@@ -1012,7 +1004,8 @@
         pool->free_list = item->next;
     }
 #else
-
+    if (pool->free_list == NULL)
+        Parrot_gc_allocate_new_attributes_arena(interp, pool);
     item            = pool->free_list;
     pool->free_list = item->next;
 #endif
@@ -1042,8 +1035,8 @@
     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);
+    const size_t item_space = item_size * num_items;
+    const size_t total_size = sizeof (PMC_Attribute_Arena) + item_space;
 
     PMC_Attribute_Arena * const new_arena = (PMC_Attribute_Arena *)mem_internal_allocate(
         total_size);
@@ -1051,26 +1044,40 @@
     new_arena->prev = NULL;
     new_arena->next = pool->top_arena;
     pool->top_arena = new_arena;
-    first           = next = (PMC_Attribute_Free_List *)(new_arena + 1);
+    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   = next;
+    pool->newlast   = (PMC_Attribute_Free_List *)((char *)next + item_space);
 #else
+    pool->free_list = next;
     for (i = 0; i < num_items; i++) {
-        list       = next;
-        list->next = (PMC_Attribute_Free_List *)((char *)list + item_size);
-        next       = list->next;
+        list        = next;
+        list->next  = (PMC_Attribute_Free_List *)((char *)list + item_size);
+        next        = list->next;
     }
-
     list->next      = pool->free_list;
-    pool->free_list = first;
 #endif
 
     pool->num_free_objects += num_items;
     pool->total_objects    += num_items;
 }
 
+void
+Parrot_gc_initialize_fixed_size_pools(PARROT_INTERP, size_t init_num_pools)
+{
+    ASSERT_ARGS(Parrot_gc_initialize_fixed_size_pools)
+    Memory_Pools       * const mem_pools = interp->mem_pools;
+    PMC_Attribute_Pool **pools;
+    const size_t total_size = (init_num_pools + 1) * sizeof (void *);
+
+    pools = (PMC_Attribute_Pool **)mem_internal_allocate(total_size);
+    memset(pools, 0, total_size);
+
+    mem_pools->attrib_pools = pools;
+    mem_pools->num_attribs = init_num_pools;
+}
+
 
 PARROT_CANNOT_RETURN_NULL
 PMC_Attribute_Pool *
@@ -1078,24 +1085,11 @@
 {
     ASSERT_ARGS(Parrot_gc_get_attribute_pool)
 
-    Memory_Pools             * const mem_pools = interp->mem_pools;
-    PMC_Attribute_Pool       **pools  = mem_pools->attrib_pools;
-    const size_t               size   = (attrib_size < sizeof (void *))
-                                      ? sizeof (void *)
-                                      : attrib_size;
-    const size_t               idx    = size - sizeof (void *);
-
-    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
-           number of resizes. 8 is just an arbitrary number */
-        pools = (PMC_Attribute_Pool **)mem_internal_allocate(total_size);
-        memset(pools, 0, total_size);
-
-        mem_pools->attrib_pools = pools;
-        mem_pools->num_attribs = total_length;
-    }
+    Memory_Pools       * const mem_pools = interp->mem_pools;
+    PMC_Attribute_Pool **pools = mem_pools->attrib_pools;
+    const size_t         idx   = (attrib_size < sizeof (void *))
+                               ? 0
+                               : attrib_size - sizeof(void *);
 
     if (mem_pools->num_attribs <= idx) {
         const size_t total_length = idx + GC_ATTRIB_POOLS_HEADROOM;
@@ -1109,17 +1103,22 @@
         mem_pools->num_attribs = total_length;
     }
 
-    if (!pools[idx])
-        pools[idx] = Parrot_gc_create_attrib_pool(interp, size);
+    if (!pools[idx]) {
+        PMC_Attribute_Pool * const pool = Parrot_gc_create_attrib_pool(interp, idx);
+        /* Create the first arena now, so we don't have to check for it later */
+        Parrot_gc_allocate_new_attributes_arena(interp, pool);
+        pools[idx] = pool;
+    }
 
     return pools[idx];
 }
 
 PARROT_CANNOT_RETURN_NULL
 static PMC_Attribute_Pool *
-Parrot_gc_create_attrib_pool(PARROT_INTERP, size_t attrib_size)
+Parrot_gc_create_attrib_pool(PARROT_INTERP, size_t attrib_idx)
 {
     ASSERT_ARGS(Parrot_gc_create_attrib_pool)
+    const size_t attrib_size = attrib_idx + sizeof(void *);
     const size_t num_objs_raw =
         (GC_FIXED_SIZE_POOL_SIZE - sizeof (PMC_Attribute_Arena)) / attrib_size;
     const size_t num_objs = (num_objs_raw == 0)?(1):(num_objs_raw);


More information about the parrot-commits mailing list