Below adds docs at the top of each function about whether that function
calls pool compaction or dod. The dod functions and compaction functions
don't list the other one themselves, otherwise they'd be re-entrant. ;)
Also fixes a bug I found with GC_DEBUG. Namely, that during compaction,
when it allocs a new block, it passed along a null pool. That pool is
required in order to give the block the pool's minimum_block_size, which
otherwise would not be done.

This also affected the 'freeing' below such that it now skips the first
block (the block we just allocated).

This patch also eliminates GC_DEBUG for now, since it was sort of screwed
up. I still have to get my head around the new multiple arenas scheme, and
figure out how GC_DEBUG would interoperate with that.

Thoughts?
Mike Lambert

Index: resources.c
===================================================================
RCS file: /cvs/public/parrot/resources.c,v
retrieving revision 1.54
diff -u -r1.54 resources.c
--- resources.c 15 May 2002 01:13:52 -0000      1.54
+++ resources.c 19 May 2002 06:09:50 -0000
@@ -26,7 +26,9 @@
                              struct Memory_Pool *);


-/* Create a new tracked resource pool */
+/* Create a new tracked resource pool
+ * Can perform: pool compaction
+ */
 static struct Resource_Pool *
 new_resource_pool(struct Parrot_Interp *interpreter, size_t free_pool_size,
                   size_t unit_size, size_t units_per_alloc,
@@ -52,6 +54,7 @@
 /* Add entry to free pool
  * Requires that any object-specific processing (eg flag setting, statistics)
  * has already been done by the caller
+ * Can perform: pool compaction
  */
 static void
 add_to_free_pool(struct Parrot_Interp *interpreter,
@@ -68,9 +71,6 @@
                           &pool->free_pool_buffer,
                           (UINTVAL)(pool->free_pool_buffer.buflen * 1.2));
     }
-#ifdef GC_DEBUG
-    Parrot_go_collect(interpreter);
-#endif

     /* Okay, so there's space. Add the header on */
     temp_ptr = pool->free_pool_buffer.bufstart;
@@ -82,6 +82,7 @@
 /* Get an entity from the specified free pool
  * If the pool is empty, try a DOD sweep
  * If the pool is still empty, call the replenishment function
+ * Can perform: dod, pool compaction
  */
 static void *
 get_from_free_pool(struct Parrot_Interp *interpreter,
@@ -107,7 +108,9 @@
 }

 /* We have no more headers on the free header pool. Go allocate more
- * and put them on */
+ * and put them on
+ * Can perform: pool compaction
+ */
 static void
 alloc_more_pmc_headers(struct Parrot_Interp *interpreter,
                        struct Resource_Pool *pool)
@@ -143,6 +146,9 @@
     }
 }

+/*
+ * Can perform: dod, pool compaction
+ */
 PMC *
 new_pmc_header(struct Parrot_Interp *interpreter)
 {
@@ -160,6 +166,7 @@
     /* Get a PMC from the free pool */
     return_me = get_from_free_pool(interpreter,
                                    interpreter->arena_base->pmc_pool);
+
     /* Count that we've allocated it */
     interpreter->active_PMCs++;
     /* Mark it live */
@@ -170,6 +177,9 @@
     return return_me;
 }

+/*
+ * Can perform: nothing
+ */
 void
 free_pmc(PMC *pmc)
 {
@@ -179,7 +189,9 @@
 }

 /* We have no more headers on the free header pool. Go allocate more
- * and put them on */
+ * and put them on
+ * Can perform: pool compaction
+ */
 static void
 alloc_more_buffer_headers(struct Parrot_Interp *interpreter,
                           struct Resource_Pool *pool)
@@ -214,7 +226,9 @@
     }
 }

-/* Get a buffer out of our free pool */
+/* Get a buffer out of our free pool
+ * Can perform: dod, pool compaction
+ */
 Buffer *
 new_buffer_header(struct Parrot_Interp *interpreter)
 {
@@ -241,6 +255,9 @@
     return return_me;
 }

+/*
+ * Can perform: nothing
+ */
 void
 free_buffer(Buffer *thing)
 {
@@ -254,7 +271,9 @@
     }
 }

-/* Mark all the PMCs as not in use.  */
+/* Mark all the PMCs as not in use.
+ * Can perform: nothing
+ */
 static void
 mark_PMCs_unused(struct Parrot_Interp *interpreter)
 {
@@ -277,7 +296,9 @@
     }
 }

-/* Mark all the buffers as unused */
+/* Mark all the buffers as unused
+ * Can perform: nothing
+ */
 static void
 mark_buffers_unused(struct Parrot_Interp *interpreter,
                     struct Resource_Pool *pool)
@@ -300,6 +321,9 @@
     }
 }

+/*
+ * Can perform: nothing
+ */
 PMC *
 mark_used(PMC *used_pmc, PMC *current_end_of_list)
 {
@@ -325,14 +349,18 @@

 /* Tag a buffer header as alive. Used by the GC system when tracing
  * the root set, and used by the PMC GC handling routines to tag their
- * individual pieces if they have private ones */
+ * individual pieces if they have private ones
+ * Can perform: nothing
+ */
 INLINE void
 buffer_lives(Buffer *buffer)
 {
     buffer->flags |= BUFFER_live_FLAG;
 }

-/* Do a full trace run and mark all the PMCs as active if they are */
+/* Do a full trace run and mark all the PMCs as active if they are
+ * Can perform: nothing
+ */
 static void
 trace_active_PMCs(struct Parrot_Interp *interpreter)
 {
@@ -430,7 +458,9 @@
 }

 /* Scan any buffers in S registers and other non-PMC places and mark
- * them as active */
+ * them as active
+ * Can perform: nothing
+ */
 static void
 trace_active_buffers(struct Parrot_Interp *interpreter)
 {
@@ -476,7 +506,9 @@
     }
 }

-/* Free up any PMCs that aren't in use */
+/* Free up any PMCs that aren't in use
+ * Can perform: pool compaction
+ */
 static void
 free_unused_PMCs(struct Parrot_Interp *interpreter)
 {
@@ -502,7 +534,9 @@
     }
 }

-/* Put any free buffers that aren't on the free list on the free list */
+/* Put any free buffers that aren't on the free list on the free list
+ * Can perform: dod, pool compaction
+ */
 static void
 free_unused_buffers(struct Parrot_Interp *interpreter,
                     struct Resource_Pool *pool)
@@ -528,7 +562,9 @@
     }
 }

-/* See if we can find some unused headers */
+/* See if we can find some unused headers
+ * Can perform: pool compaction
+ */
 void
 Parrot_do_dod_run(struct Parrot_Interp *interpreter)
 {
@@ -566,7 +602,9 @@
     return;
 }

-/* Fetch a string header from the free header pool */
+/* Fetch a string header from the free header pool
+ * Can perform: dod, pool compaction
+ */
 STRING *
 new_string_header(struct Parrot_Interp *interpreter, UINTVAL flags)
 {
@@ -601,10 +639,13 @@
     return return_me;
 }

-/* Initialize the pools for the tracked resources */
+/* Initialize the pools for the tracked resources
+ * Can perform: pool compaction
+ */
 void
 Parrot_initialize_resource_pools(struct Parrot_Interp *interpreter)
 {
+
     /* Init the string header pool */
     interpreter->arena_base->string_header_pool =
         new_resource_pool(interpreter, 256, sizeof(STRING),
@@ -630,6 +671,9 @@
                           alloc_more_buffer_headers);
 }

+/*
+ * Can perform: nothing
+ */
 INLINE static UINTVAL
 sized_index(size_t unit_size)
 {
@@ -637,7 +681,9 @@
 }

 /* unit_size must be a multiple of sizeof(void*), for no particular reason
- * other than to shrink the size of the array of pools. */
+ * other than to shrink the size of the array of pools.
+ * Can perform: pool collection
+ */
 static struct Resource_Pool *
 new_sized_resource_pool(struct Parrot_Interp *interpreter,
                         size_t unit_size)
@@ -666,6 +712,9 @@
     /* FIXME! Sized buffer headers are currently not collected! */
 }

+/*
+ * Can perform: dod, pool compaction
+ */
 Buffer *
 new_tracked_header(struct Parrot_Interp *interpreter, size_t size)
 {
@@ -683,7 +732,9 @@
 }

 /* Figure out how much memory's been allocated total for buffered
- * things */
+ * things
+ * Can perform: nothing
+ */
 static UINTVAL
 calc_total_size(struct Parrot_Interp *interpreter, struct Memory_Pool *pool)
 {
@@ -695,7 +746,9 @@
     return size;
 }

-/* Compact the buffer pool */
+/* Compact the buffer pool
+ * Can perform: nothing
+ */
 static void
 compact_buffer_pool(struct Parrot_Interp *interpreter,
                     struct Memory_Pool *pool)
@@ -706,7 +759,7 @@
     UINTVAL cur_size;     /* How big our chunk is going to be */
     struct Buffer_Arena *cur_buffer_arena;
     struct Resource_Pool *header_pool;
-    Buffer *b;   /* temporary tidy-up for free pool collection */
+    Buffer *b;   /* temporary tidy-up for free pool compaction */
     INTVAL j;

     /* Bail if we're blocked */
@@ -722,7 +775,7 @@
      * use no more than this in our collection run */
     total_size = calc_total_size(interpreter, pool);
     /* Snag a block big enough for everything */
-    new_block = alloc_new_block(interpreter, total_size, NULL);
+    new_block = alloc_new_block(interpreter, total_size, pool);

     /* Start at the beginning */
     cur_spot = new_block->start;
@@ -781,16 +834,16 @@
         else header_pool = interpreter->arena_base->sized_header_pools[j];
         if (header_pool == NULL) continue;

-    for (cur_buffer_arena = header_pool->last_Arena;
-         NULL != cur_buffer_arena;
+        for (cur_buffer_arena = header_pool->last_Arena;
+             NULL != cur_buffer_arena;
              cur_buffer_arena = cur_buffer_arena->prev)
         {
-        Buffer *buffer_array = cur_buffer_arena->start_Buffer;
+            Buffer *buffer_array = cur_buffer_arena->start_Buffer;
             UINTVAL i;
-        for (i = 0; i < cur_buffer_arena->used; i++) {
+            for (i = 0; i < cur_buffer_arena->used; i++) {
                 Buffer *buffer = (Buffer*)((char*)cur_buffer_arena->start_Buffer + i 
* header_pool->unit_size);

-            /* Is the string live, and can we move it? */
+                /* Is the string live, and can we move it? */
                 if (buffer->flags & BUFFER_live_FLAG
                     && !(buffer->flags & BUFFER_immobile_FLAG)
                     && buffer->bufstart)
@@ -802,8 +855,8 @@
                     memcpy(cur_spot, buffer->bufstart, buffer->buflen);
                     buffer->bufstart = cur_spot;
                     cur_size = buffer->buflen;
-                cur_size = (cur_size + pool->align_1) & ~pool->align_1;
-                cur_spot += cur_size;
+                    cur_size = (cur_size + pool->align_1) & ~pool->align_1;
+                    cur_spot += cur_size;
                 } else if (buffer->flags & BUFFER_report_FLAG) {
                     if (buffer->bufstart != NULL)
                         fprintf(stderr, "  not copying buffer %p+%ld\n",
@@ -821,12 +874,13 @@

     interpreter->memory_collected += (new_block->top - new_block->start);

-    /* Now we're done. Put us as the only block on the free list and
-     * free the rest */
+    /* Now we're done. We're already on the pool's free list,
+     * so let us be the only one on the free list and free the rest */
     {
         struct Memory_Block *cur_block, *next_block;

-        cur_block = pool->top_block;
+        assert( new_block == pool->top_block );
+        cur_block = pool->top_block->prev;
         while (cur_block) {
             next_block = cur_block->prev;
             /* Note that we don't have it any more */
@@ -838,15 +892,15 @@
         }

         /* Set our new pool as the only pool */
-        pool->top_block = new_block;
-        new_block->next = NULL;
         new_block->prev = NULL;
     }
 }

 /* Compact the string pool
  * Ignore constants as these currently share the same header pool but use
- * different memory pools */
+ * different memory pools
+ * Can perform: nothing
+ */
 static void
 compact_string_pool(struct Parrot_Interp *interpreter,
                     struct Memory_Pool *pool)
@@ -871,7 +925,7 @@
        use no more than this in our collection run */
     total_size = calc_total_size(interpreter, pool);
     /* Snag a block big enough for everything */
-    new_block = alloc_new_block(interpreter, total_size, NULL);
+    new_block = alloc_new_block(interpreter, total_size, pool);

     /* Start at the beginning */
     cur_spot = new_block->start;
@@ -908,12 +962,13 @@

     interpreter->memory_collected += (new_block->top - new_block->start);

-    /* Now we're done. Put us as the only block on the free list and
-     * free the rest */
+    /* Now we're done. We're already on the pool's free list,
+     * so let us be the only one on the free list and free the rest */
     {
         struct Memory_Block *cur_block, *next_block;
-
-        cur_block = pool->top_block;
+
+        assert( new_block == pool->top_block );
+        cur_block = pool->top_block->prev;
         while (cur_block) {
             next_block = cur_block->prev;
             /* Note that we don't have it any more */
@@ -925,14 +980,14 @@
         }

         /* Set our new pool as the only pool */
-        pool->top_block = new_block;
-        new_block->next = NULL;
         new_block->prev = NULL;
     }
 }

 /* Go do a GC run. This only scans the string pools and compacts them,
- * it doesn't check for string liveness */
+ * it doesn't check for string liveness
+ * Can perform: pool compaction
+ */
 void
 Parrot_go_collect(struct Parrot_Interp *interpreter)
 {
@@ -973,7 +1028,9 @@
 }

 /* Allocate a new memory block. We allocate the larger of however much
- * was asked for or the default size, whichever's larger */
+ * was asked for or the default size, whichever's larger
+ * Can perform: nothing
+ */
 static void *
 alloc_new_block(struct Parrot_Interp *interpreter,
                        size_t size, struct Memory_Pool *pool)
@@ -1020,7 +1077,9 @@

 /* Takes an interpreter, a buffer pointer, and a new size. The buffer
  * pointer is in as a void * because we may take a STRING or
- * something, and C doesn't subclass */
+ * something, and C doesn't subclass
+ * Can perform: pool compaction
+ */
 void *
 Parrot_reallocate(struct Parrot_Interp *interpreter, void *from, size_t tosize)
 {
@@ -1051,7 +1110,9 @@
 }

 /* Takes an interpreter, a STRING pointer, and a new size.
- * The destination may be bigger, since we round up to the allocation quantum */
+ * The destination may be bigger, since we round up to the allocation quantum
+ * Can perform: pool compaction
+ */
 void *
 Parrot_reallocate_string(struct Parrot_Interp *interpreter, STRING *str,
                          size_t tosize)
@@ -1081,7 +1142,9 @@
     return mem;
 }

-/* Allocate exactly as much memory as they asked for */
+/* Allocate exactly as much memory as they asked for
+ * Can perform: pool compaction
+ */
 void *
 Parrot_allocate(struct Parrot_Interp *interpreter, void *buffer, size_t size)
 {
@@ -1095,7 +1158,9 @@
 }

 /* Allocate at least as much memory as they asked for. We round the
- * amount up to the allocation quantum */
+ * amount up to the allocation quantum
+ * Can perform: pool compaction
+ */
 void *
 Parrot_allocate_string(struct Parrot_Interp *interpreter, STRING *str,
                        size_t size)
@@ -1119,6 +1184,9 @@
     return str;
 }

+/*
+ * Can perform: pool compaction
+ */
 static void *
 mem_allocate(struct Parrot_Interp *interpreter, size_t *req_size,
              struct Memory_Pool *pool)
@@ -1129,9 +1197,6 @@
         void *mem = mem_sys_allocate(size);
         return mem;
     }
-#ifdef GC_DEBUG
-    Parrot_go_collect(interpreter);
-#endif

     /* Round up to requested alignment */
     size = (size + pool->align_1) & ~pool->align_1;
@@ -1143,7 +1208,7 @@
     }
     if (pool->top_block->free < size) {
         if (pool->compact) {
-          (*pool->compact)(interpreter, pool);
+            (*pool->compact)(interpreter, pool);
         }
         if (pool->top_block->free < size) {
             alloc_new_block(interpreter, size, pool);


Reply via email to