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

bacek at svn.parrot.org bacek at svn.parrot.org
Thu Sep 16 08:43:03 UTC 2010


Author: bacek
Date: Thu Sep 16 08:43:03 2010
New Revision: 49045
URL: https://trac.parrot.org/parrot/changeset/49045

Log:
Merge branch 'string_gc'

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

Modified: trunk/src/gc/alloc_resources.c
==============================================================================
--- trunk/src/gc/alloc_resources.c	Thu Sep 16 08:37:09 2010	(r49044)
+++ trunk/src/gc/alloc_resources.c	Thu Sep 16 08:43:03 2010	(r49045)
@@ -34,6 +34,11 @@
 
 typedef void (*compact_f) (Interp *, Memory_Pools * const, Variable_Size_Pool *);
 
+typedef struct string_callback_data {
+    Memory_Block *new_block;     /* A pointer to our working block */
+    char         *cur_spot;      /* Where we're currently copying to */
+} string_callback_data;
+
 /* HEADERIZER HFILE: src/gc/gc_private.h */
 
 /* HEADERIZER BEGIN: static */
@@ -93,6 +98,13 @@
 static int is_block_almost_full(ARGIN(const Memory_Block *block))
         __attribute__nonnull__(1);
 
+static void move_buffer_callback(PARROT_INTERP,
+    ARGIN(Buffer *b),
+    ARGIN(void *data))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static char * move_one_buffer(PARROT_INTERP,
@@ -175,6 +187,10 @@
 #define ASSERT_ARGS_free_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
 #define ASSERT_ARGS_is_block_almost_full __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(block))
+#define ASSERT_ARGS_move_buffer_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp) \
+    , PARROT_ASSERT_ARG(b) \
+    , PARROT_ASSERT_ARG(data))
 #define ASSERT_ARGS_move_one_buffer __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(pool) \
@@ -439,11 +455,12 @@
     INTVAL        j;
     UINTVAL       total_size;
 
-    Memory_Block *new_block;     /* A pointer to our working block */
-    char         *cur_spot;      /* Where we're currently copying to */
-
     Fixed_Size_Arena *cur_buffer_arena;
 
+    /* Contains new_block and cur_spot */
+    string_callback_data cb_data;
+
+
     /* Bail if we're blocked */
     if (mem_pools->gc_sweep_block_level)
         return;
@@ -466,57 +483,53 @@
 
     alloc_new_block(mem_pools, total_size, pool, "inside compact");
 
-    new_block = pool->top_block;
+    cb_data.new_block = pool->top_block;
 
     /* Start at the beginning */
-    cur_spot  = new_block->start;
+    cb_data.cur_spot  = cb_data.new_block->start;
 
     /* Run through all the Buffer header pools and copy */
-    for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
-        Fixed_Size_Pool * const header_pool = mem_pools->sized_header_pools[j];
-        UINTVAL       object_size;
-
-        if (!header_pool)
-            continue;
+    interp->gc_sys->iterate_live_strings(interp, move_buffer_callback, &cb_data);
 
-        object_size = header_pool->object_size;
+    /* Okay, we're done with the copy. Set the bits in the pool struct */
+    /* First, where we allocate next */
+    cb_data.new_block->top = cb_data.cur_spot;
 
-        for (cur_buffer_arena = header_pool->last_Arena;
-                cur_buffer_arena;
-                cur_buffer_arena = cur_buffer_arena->prev) {
-            Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
-            UINTVAL i;
-            const size_t objects_end = cur_buffer_arena->used;
+    PARROT_ASSERT(cb_data.new_block->size
+                  >=
+                  (size_t)cb_data.new_block->top - (size_t)cb_data.new_block->start);
 
-            for (i = objects_end; i; --i) {
+    /* How much is free. That's the total size minus the amount we used */
+    cb_data.new_block->free     = cb_data.new_block->size
+                                  - (cb_data.cur_spot - cb_data.new_block->start);
+    mem_pools->memory_collected += (cb_data.cur_spot - cb_data.new_block->start);
+    mem_pools->memory_used      += (cb_data.cur_spot - cb_data.new_block->start);
 
-                if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
-                    Memory_Block *old_block = Buffer_pool(b);
+    free_old_mem_blocks(mem_pools, pool, cb_data.new_block, total_size);
 
-                    if (!is_block_almost_full(old_block))
-                        cur_spot = move_one_buffer(interp, new_block, b, cur_spot);
-                }
+    --mem_pools->gc_sweep_block_level;
+}
 
-                b = (Buffer *)((char *)b + object_size);
-            }
-        }
-    }
+/*
+=item C<static void move_buffer_callback(PARROT_INTERP, Buffer *b, void *data)>
 
-    /* Okay, we're done with the copy. Set the bits in the pool struct */
-    /* First, where we allocate next */
-    new_block->top = cur_spot;
+Callback for live STRING/Buffer for compating.
 
-    PARROT_ASSERT(new_block->size >= (size_t)new_block->top -
-            (size_t)new_block->start);
+=cut
+*/
+static void
+move_buffer_callback(PARROT_INTERP, ARGIN(Buffer *b), ARGIN(void *data))
+{
+    ASSERT_ARGS(move_buffer_callback)
+    string_callback_data *cb = (string_callback_data*)data;
 
-    /* How much is free. That's the total size minus the amount we used */
-    new_block->free = new_block->size - (cur_spot - new_block->start);
-    mem_pools->memory_collected +=      (cur_spot - new_block->start);
-    mem_pools->memory_used      +=      (cur_spot - new_block->start);
+    if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
+        Memory_Block *old_block = Buffer_pool(b);
 
-    free_old_mem_blocks(mem_pools, pool, new_block, total_size);
+        if (!is_block_almost_full(old_block))
+            cb->cur_spot = move_one_buffer(interp, cb->new_block, b, cb->cur_spot);
+    }
 
-    --mem_pools->gc_sweep_block_level;
 }
 
 /*

Modified: trunk/src/gc/gc_ms.c
==============================================================================
--- trunk/src/gc/gc_ms.c	Thu Sep 16 08:37:09 2010	(r49044)
+++ trunk/src/gc/gc_ms.c	Thu Sep 16 08:43:03 2010	(r49045)
@@ -162,6 +162,11 @@
 static unsigned int gc_ms_is_blocked_GC_sweep(PARROT_INTERP)
         __attribute__nonnull__(1);
 
+static void gc_ms_iterate_live_strings(PARROT_INTERP,
+    string_iterator_callback callback,
+    ARGIN_NULLOK(void *data))
+        __attribute__nonnull__(1);
+
 static void gc_ms_mark_and_sweep(PARROT_INTERP, UINTVAL flags)
         __attribute__nonnull__(1);
 
@@ -327,6 +332,8 @@
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms_is_blocked_GC_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
+#define ASSERT_ARGS_gc_ms_iterate_live_strings __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms_mark_and_sweep __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp))
 #define ASSERT_ARGS_gc_ms_mark_special __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
@@ -456,6 +463,8 @@
 
     interp->gc_sys->get_gc_info      = gc_ms_get_gc_info;
 
+    interp->gc_sys->iterate_live_strings = gc_ms_iterate_live_strings;
+
     initialize_var_size_pools(interp, interp->mem_pools);
     initialize_fixed_size_pools(interp, interp->mem_pools);
     Parrot_gc_initialize_fixed_size_pools(interp, interp->mem_pools,
@@ -1878,6 +1887,52 @@
 }
 
 /*
+=item C<static void gc_ms_iterate_live_strings(PARROT_INTERP,
+string_iterator_callback callback, void *data)>
+
+Iterate over live string invoking callback for each of them. Used during
+compacting of string pool.
+
+=cut
+*/
+static void
+gc_ms_iterate_live_strings(PARROT_INTERP,
+        string_iterator_callback callback,
+        ARGIN_NULLOK(void *data))
+{
+    ASSERT_ARGS(gc_ms_iterate_live_strings)
+
+    Memory_Pools * const mem_pools = interp->mem_pools;
+    INTVAL j;
+
+    /* Run through all the Buffer header pools and invoke callback */
+    for (j = (INTVAL)mem_pools->num_sized - 1; j >= 0; --j) {
+        Fixed_Size_Pool  * const header_pool = mem_pools->sized_header_pools[j];
+        Fixed_Size_Arena       * cur_buffer_arena;
+        UINTVAL       object_size;
+
+        if (!header_pool)
+            continue;
+
+        object_size = header_pool->object_size;
+
+        for (cur_buffer_arena = header_pool->last_Arena;
+                cur_buffer_arena;
+                cur_buffer_arena = cur_buffer_arena->prev) {
+            Buffer *b = (Buffer *) cur_buffer_arena->start_objects;
+            UINTVAL i;
+            const size_t objects_end = cur_buffer_arena->used;
+
+            for (i = objects_end; i; --i) {
+                callback(interp, b, data);
+                b = (Buffer *)((char *)b + object_size);
+            }
+        }
+    }
+}
+
+
+/*
 
 =back
 

Modified: trunk/src/gc/gc_private.h
==============================================================================
--- trunk/src/gc/gc_private.h	Thu Sep 16 08:37:09 2010	(r49044)
+++ trunk/src/gc/gc_private.h	Thu Sep 16 08:43:03 2010	(r49045)
@@ -91,6 +91,9 @@
     GC_NEVER_SKIP       /* unused */
 } gc_skip_type_enum;
 
+/* Callback for live string. Use Buffer for now... */
+typedef void (*string_iterator_callback)(PARROT_INTERP, Buffer *str, void *data);
+
 typedef struct GC_Subsystem {
     /* Which GC subsystem are we using? See PARROT_GC_DEFAULT_TYPE in
      * include/parrot/settings.h for possible values */
@@ -148,6 +151,9 @@
     /* Return by value to simplify memory management */
     size_t (*get_gc_info)(PARROT_INTERP, Interpinfo_enum);
 
+    /* Iterate over _live_ strings. Used for string pool compacting */
+    void (*iterate_live_strings)(PARROT_INTERP, string_iterator_callback callback, void *data);
+
     /*Function hooks that GC systems can CHOOSE to provide if they need them
      *These will be called via the GC API functions Parrot_gc_func_name
      *e.g. read barrier && write barrier hooks can go here later ...*/


More information about the parrot-commits mailing list