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

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Sat Aug 15 00:47:56 UTC 2009


Author: whiteknight
Date: Sat Aug 15 00:47:55 2009
New Revision: 40552
URL: https://trac.parrot.org/parrot/changeset/40552

Log:
[gc] add in a completely lazy GC allocator. Disabled by default, can be enabled by setting GC_USE_LAZY_ALLOCATOR in src/gc/gc_private.h to 1.

Modified:
   trunk/src/gc/alloc_resources.c
   trunk/src/gc/gc_ms.c
   trunk/src/gc/gc_private.h
   trunk/src/gc/mark_sweep.c

Modified: trunk/src/gc/alloc_resources.c
==============================================================================
--- trunk/src/gc/alloc_resources.c	Sat Aug 15 00:36:23 2009	(r40551)
+++ trunk/src/gc/alloc_resources.c	Sat Aug 15 00:47:55 2009	(r40552)
@@ -402,8 +402,9 @@
                 cur_buffer_arena = cur_buffer_arena->prev) {
             Buffer *b = (Buffer *)ARENA_to_PObj(cur_buffer_arena->start_objects);
             UINTVAL i;
+            const size_t objects_end = cur_buffer_arena->used;
 
-            for (i = cur_buffer_arena->used; i; --i) {
+            for (i = objects_end; i; --i) {
                 INTVAL *ref_count = NULL;
 
                 /* ! (on_free_list | constant | external | sysmem) */

Modified: trunk/src/gc/gc_ms.c
==============================================================================
--- trunk/src/gc/gc_ms.c	Sat Aug 15 00:36:23 2009	(r40551)
+++ trunk/src/gc/gc_ms.c	Sat Aug 15 00:47:55 2009	(r40552)
@@ -429,6 +429,25 @@
     PObj *ptr;
     PObj *free_list = (PObj *)pool->free_list;
 
+#if GC_USE_LAZY_ALLOCATOR
+    if (!free_list && !pool->newfree) {
+        (*pool->more_objects)(interp, pool);
+        free_list = (PObj *)pool->free_list;
+    }
+    if (!free_list) {
+        Small_Object_Arena * const arena = pool->last_Arena;
+        ptr = (PObj *)pool->newfree;
+        pool->newfree = (void *)((char *)pool->newfree + pool->object_size);
+        arena->used++;
+        if(pool->newfree >= pool->newlast)
+            pool->newfree = NULL;
+        PARROT_ASSERT(ptr < pool->newlast);
+    }
+    else {
+        ptr = free_list;
+        pool->free_list = ((GC_MS_PObj_Wrapper*)ptr)->next_ptr;
+    }
+#else
     /* if we don't have any objects */
     if (!free_list) {
         (*pool->more_objects)(interp, pool);
@@ -437,6 +456,7 @@
 
     ptr             = free_list;
     pool->free_list = ((GC_MS_PObj_Wrapper*)ptr)->next_ptr;
+#endif
 
     PObj_flags_SETTO(ptr, 0);
 
@@ -568,15 +588,35 @@
     PMC_EXT *ptr;
     PMC_EXT *free_list = (PMC_EXT *)pool->free_list;
 
+#if GC_USE_LAZY_ALLOCATOR
+    if (!free_list && !pool->newfree) {
+        (*pool->more_objects)(interp, pool);
+        free_list = (PObj *)pool->free_list;
+    }
+    if (!free_list) {
+        Small_Object_Arena * const arena = pool->last_Arena;
+        ptr = (PMC_EXT *)pool->newfree;
+        pool->newfree = (void *)((char *)pool->newfree + pool->object_size);
+        if(pool->newfree >= pool->newlast)
+            pool->newfree = NULL;
+        arena->used++;
+        PARROT_ASSERT(ptr < pool->newlast);
+    }
+    else {
+        ptr = free_list;
+        pool->free_list = ptr->_next_for_GC;
+        ptr->_next_for_GC = NULL;
+    }
+#else
     /* if we don't have any objects */
     if (!free_list) {
         (*pool->more_objects)(interp, pool);
         free_list = (PMC_EXT *)pool->free_list;
     }
-
     ptr               = free_list;
     pool->free_list   = ptr->_next_for_GC;
     ptr->_next_for_GC = NULL;
+#endif
 
     --pool->num_free_objects;
 

Modified: trunk/src/gc/gc_private.h
==============================================================================
--- trunk/src/gc/gc_private.h	Sat Aug 15 00:36:23 2009	(r40551)
+++ trunk/src/gc/gc_private.h	Sat Aug 15 00:47:55 2009	(r40552)
@@ -124,7 +124,7 @@
 
 #endif /* PARROT_GC_GMS */
 
-#define GC_USE_LAZY_ALLOCATOR 1
+#define GC_USE_LAZY_ALLOCATOR 0
 
 typedef struct PMC_Attribute_Pool {
     size_t attr_size;
@@ -165,6 +165,10 @@
     size_t start_arena_memory;
     size_t end_arena_memory;
     PARROT_OBSERVER const char *name;
+#if GC_USE_LAZY_ALLOCATOR
+    void *newfree;
+    void *newlast;
+#endif
 #if PARROT_GC_GMS
     struct _gc_gms_hdr marker;          /* limit of list */
     struct _gc_gms_hdr *black;          /* alive */

Modified: trunk/src/gc/mark_sweep.c
==============================================================================
--- trunk/src/gc/mark_sweep.c	Sat Aug 15 00:36:23 2009	(r40551)
+++ trunk/src/gc/mark_sweep.c	Sat Aug 15 00:47:55 2009	(r40552)
@@ -303,11 +303,12 @@
 
     /* Run through all the buffer header pools and mark */
     for (cur_arena = pool->last_Arena; cur_arena; cur_arena = cur_arena->prev) {
+        const size_t objects_end = cur_arena->used;
         Buffer *b = (Buffer *)cur_arena->start_objects;
         UINTVAL i;
 
         /* loop only while there are objects in the arena */
-        for (i = cur_arena->total_objects; i; i--) {
+        for (i = objects_end; i; i--) {
 
             if (PObj_on_free_list_TEST(b))
                 ; /* if it's on free list, do nothing */
@@ -614,16 +615,24 @@
     const UINTVAL num_objects = pool->objects_per_alloc;
 
     pool->total_objects += num_objects;
-    arena->used          = num_objects;
-
-    /* Move all the new objects into the free list */
     object = (void *)arena->start_objects;
-
+#if GC_USE_LAZY_ALLOCATOR
+    /* Don't move anything onto the free list. Set the pointers and do it
+       lazily when we allocate. */
+    {
+        const size_t total_size = num_objects * pool->object_size;
+        pool->newfree = arena->start_objects;
+        pool->newlast = (void*)((char*)object + total_size);
+        arena->used = 0;
+    }
+#else
+    /* Move all the new objects into the free list */
+    arena->used          = num_objects;
     for (i = 0; i < num_objects; i++) {
         pool->add_free_object(interp, pool, object);
         object = (void *)((char *)object + pool->object_size);
     }
-
+#endif
     pool->num_free_objects += num_objects;
 }
 
@@ -868,6 +877,10 @@
     pool->mem_pool          = NULL;
     pool->object_size       = object_size;
     pool->objects_per_alloc = objects_per_alloc;
+#if GC_USE_LAZY_ALLOCATOR
+    pool->newfree           = NULL;
+    pool->newlast           = NULL;
+#endif
 
     return pool;
 }


More information about the parrot-commits mailing list