[svn:parrot] r45833 - branches/compact_pool_revamp/src/gc

bacek at svn.parrot.org bacek at svn.parrot.org
Tue Apr 20 21:34:55 UTC 2010


Author: bacek
Date: Tue Apr 20 21:34:54 2010
New Revision: 45833
URL: https://trac.parrot.org/parrot/changeset/45833

Log:
Handcraft std::lower_bound for finding blocks. bsearch couldn't find them

Modified:
   branches/compact_pool_revamp/src/gc/alloc_resources.c
   branches/compact_pool_revamp/src/gc/mark_sweep.c

Modified: branches/compact_pool_revamp/src/gc/alloc_resources.c
==============================================================================
--- branches/compact_pool_revamp/src/gc/alloc_resources.c	Tue Apr 20 21:30:07 2010	(r45832)
+++ branches/compact_pool_revamp/src/gc/alloc_resources.c	Tue Apr 20 21:34:54 2010	(r45833)
@@ -65,6 +65,12 @@
 static void check_var_size_obj_pool(ARGIN(const Variable_Size_Pool *pool))
         __attribute__nonnull__(1);
 
+static int compare_memory_blocks(
+    ARGIN(const void * lv),
+    ARGIN(const void * rv))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2);
+
 static void debug_print_buf(PARROT_INTERP, ARGIN(const Buffer *b))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2);
@@ -166,6 +172,9 @@
        PARROT_ASSERT_ARG(mem_pools))
 #define ASSERT_ARGS_check_var_size_obj_pool __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(pool))
+#define ASSERT_ARGS_compare_memory_blocks __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(lv) \
+    , PARROT_ASSERT_ARG(rv))
 #define ASSERT_ARGS_debug_print_buf __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
        PARROT_ASSERT_ARG(interp) \
     , PARROT_ASSERT_ARG(b))
@@ -483,12 +492,12 @@
 
     /* Allocate storage for skip list */
     skip_blocks = (Memory_Block**)Parrot_gc_allocate_fixed_size_storage(interp,
-                        sizeof (Memory_Block**) * total_blocks);
+                        sizeof (Memory_Block*) * total_blocks);
 
     /* Snag a block big enough for everything */
     total_size = pad_pool_size(pool, skip_blocks, &skip_blocks_count);
 
-    //fprintf(stderr, "%d %d\n", total_blocks, skip_blocks_count);
+    fprintf(stderr, "%d %d\n", total_blocks, skip_blocks_count);
 
     alloc_new_block(mem_pools, total_size, pool, "inside compact");
 
@@ -516,22 +525,36 @@
 
             for (i = objects_end; i; --i) {
                 UINTVAL  k;
-                INTVAL   skip = 0;
+                INTVAL   skip = !PObj_is_movable_TESTALL(b);
 
                 /* Check that buffer isn't in skip list */
-                if (PObj_is_movable_TESTALL(b)) {
-                    char *bufstart = (char*)Buffer_bufstart(b);
-                    for (k = 0; k < skip_blocks_count; ++k) {
-                        if ((bufstart >= skip_blocks[k]->start)
-                            && (bufstart < skip_blocks[k]->top)) {
-                            /* Skip buffer. */
-                            skip = 1;
-                            break;
+                if (skip_blocks_count && Buffer_buflen(b) && !skip) {
+                    char         *buf_start = (char*)Buffer_bufstart(b);
+
+                    /* Poor man std::lower_bound */
+                    size_t       low = 0, high = skip_blocks_count;
+                    Memory_Block *block = skip_blocks[0], *middle;
+
+                    while (low < high) {
+                        /* It's unlikely to have integer overflow here */
+                        size_t mid = (high + low)/2;
+                        middle = skip_blocks[mid];
+
+                        if (middle->start < buf_start) {
+                            block = middle;
+                            low   = mid + 1;
                         }
+                        else
+                            high  = mid;
                     }
+
+                    /* And check that is real one */
+                    if (block && (block->start <= buf_start) && (buf_start < block->top))
+                        skip = 1;
                 }
 
-                if (!skip)
+
+                if (!skip && PObj_is_movable_TESTALL(b))
                     cur_spot = move_one_buffer(interp, b, cur_spot);
 
                 b = (Buffer *)((char *)b + object_size);
@@ -554,13 +577,33 @@
 
     if (total_blocks)
         Parrot_gc_free_fixed_size_storage(interp,
-                sizeof (Memory_Block**) * total_blocks, skip_blocks);
+                sizeof (Memory_Block*) * total_blocks, skip_blocks);
 
     --mem_pools->gc_sweep_block_level;
 }
 
 /*
 
+=item C<static int compare_memory_blocks(const void * lv, const void * rv)>
+
+Compare Memory_Block by C<start> element. Used for sorting and binary
+search
+
+=cut
+
+*/
+
+static int
+compare_memory_blocks(ARGIN(const void * lv), ARGIN(const void * rv))
+{
+    ASSERT_ARGS(compare_memory_blocks)
+    const Memory_Block ** l = (const Memory_Pools **)lv;
+    const Memory_Block ** r = (const Memory_Pools **)rv;
+    return (*l)->start > (*r)->start;
+}
+
+/*
+
 =item C<static UINTVAL pad_pool_size(const Variable_Size_Pool *pool,
 Memory_Block **skip_blocks, size_t *skip_blocks_count)>
 
@@ -600,8 +643,7 @@
     size_t skip_pos    = 0;
 
     while (cur_block) {
-        if ((cur_block->size * 0.2 > cur_block->freed)
-            && (cur_block->free < cur_block->size * 0.2)) {
+        if (cur_block->freed < cur_block->size * 0.2) {
             /* Don't reclaim almost filled blocks */
             /* TODO Keep blocks ordered by block->start to use binary search */
             skip_blocks[skip_pos++] = cur_block;
@@ -627,6 +669,9 @@
 
     *skip_blocks_count = skip_pos;
 
+    /* Sort skip_blocks to use binary search */
+    qsort(skip_blocks, skip_pos, sizeof(Memory_Block*), compare_memory_blocks);
+
     return total_size;
 }
 

Modified: branches/compact_pool_revamp/src/gc/mark_sweep.c
==============================================================================
--- branches/compact_pool_revamp/src/gc/mark_sweep.c	Tue Apr 20 21:30:07 2010	(r45832)
+++ branches/compact_pool_revamp/src/gc/mark_sweep.c	Tue Apr 20 21:34:54 2010	(r45833)
@@ -740,17 +740,18 @@
         }
 
         /* Find our block */
-        while (block) {
-            if (block->start <= (char*)Buffer_bufstart(b)
-                && (char*)Buffer_bufstart(b) < block->top) {
-                /* ... and update usage */
-                block->freed += aligned_string_size(Buffer_buflen(b));
-                break;
-            }
+        if (Buffer_buflen(b) && PObj_is_movable_TESTALL(b)) {
+            while (block) {
+                if (block->start <= (char*)Buffer_bufstart(b)
+                    && (char*)Buffer_bufstart(b) < block->top) {
+                    /* ... and update usage */
+                    block->freed += aligned_string_size(Buffer_buflen(b));
+                    break;
+                }
 
-            block = block->prev;
+                block = block->prev;
+            }
         }
-
     }
 
     Buffer_buflen(b) = 0;


More information about the parrot-commits mailing list