Author: Nicolas Truessel <ntrues...@njsm.de>
Branch: quad-color-gc
Changeset: r86982:79998830344e
Date: 2016-09-10 14:57 +0200
http://bitbucket.org/pypy/pypy/changeset/79998830344e/

Log:    Update qcgc codebase

diff --git a/rpython/translator/c/src/qcgc/allocator.c 
b/rpython/translator/c/src/qcgc/allocator.c
--- a/rpython/translator/c/src/qcgc/allocator.c
+++ b/rpython/translator/c/src/qcgc/allocator.c
@@ -23,6 +23,7 @@
 QCGC_STATIC cell_t *fit_allocator_large_first_fit(size_t index, size_t cells);
 
 QCGC_STATIC bool valid_block(cell_t *ptr, size_t cells);
+QCGC_STATIC void free_list_consistency_check(void);
 
 void qcgc_allocator_initialize(void) {
        qcgc_allocator_state.arenas =
@@ -77,8 +78,13 @@
        if (cells > 0) {
                assert((((object_t *)ptr)->flags & QCGC_PREBUILT_OBJECT) == 0);
                assert((cell_t *) qcgc_arena_addr(ptr) != ptr);
-               assert(qcgc_arena_get_blocktype(ptr) == BLOCK_FREE ||
-                               qcgc_arena_get_blocktype(ptr) == BLOCK_EXTENT);
+               assert(qcgc_arena_get_blocktype(ptr) == BLOCK_FREE);
+               if (qcgc_arena_addr(ptr) == qcgc_arena_addr(ptr + cells)) {
+                       assert(qcgc_arena_get_blocktype(ptr + cells) != 
BLOCK_EXTENT);
+               }
+               for (size_t i = 1; i < cells; i++) {
+                       assert(qcgc_arena_get_blocktype(ptr + i) == 
BLOCK_EXTENT);
+               }
        }
 #endif
        if (cells > 0) {
@@ -208,6 +214,9 @@
 }
 
 object_t *qcgc_fit_allocate(size_t bytes) {
+#if CHECKED
+       free_list_consistency_check();
+#endif
        size_t cells = bytes_to_cells(bytes);
        cell_t *mem;
 
@@ -223,7 +232,6 @@
                return NULL;
        }
 
-       qcgc_arena_mark_allocated(mem, cells);
        object_t *result = (object_t *) mem;
 
 #if QCGC_INIT_ZERO
@@ -250,6 +258,16 @@
        return result;
 }
 
+void qcgc_fit_allocator_empty_lists(void) {
+       for (size_t i = 0; i < QCGC_SMALL_FREE_LISTS; i++) {
+               qcgc_allocator_state.fit_state.small_free_list[i]->count = 0;
+       }
+
+       for (size_t i = 0; i < QCGC_LARGE_FREE_LISTS; i++) {
+               qcgc_allocator_state.fit_state.large_free_list[i]->count = 0;
+       }
+}
+
 QCGC_STATIC cell_t *fit_allocator_small_first_fit(size_t index, size_t cells) {
 #if CHECKED
        assert(small_index_to_cells(index) >= cells);
@@ -272,16 +290,11 @@
                        // Check whether block is still valid
                        if (valid_block(result, list_cell_size)) {
                                // The next call might invalidate free_list, 
reload!
+                               qcgc_arena_mark_allocated(result, cells);
                                qcgc_fit_allocator_add(result + cells, 
list_cell_size - cells);
-                               break;
-                       } else {
-                               result = NULL;
+                               return result;
                        }
                }
-
-               if (result != NULL) {
-                       return result;
-               }
        }
        return fit_allocator_large_first_fit(0, cells);
 }
@@ -332,6 +345,7 @@
                qcgc_allocator_state.fit_state.large_free_list[index] =
                        
qcgc_exp_free_list_remove_index(qcgc_allocator_state.fit_state.
                                        large_free_list[index], best_fit_index);
+               qcgc_arena_mark_allocated(result, cells);
                qcgc_fit_allocator_add(result + cells, best_fit_cells - cells);
        } else {
                // No best fit, go for first fit
@@ -344,7 +358,6 @@
 #if CHECKED
        assert(1u<<(index + QCGC_LARGE_FREE_LIST_FIRST_EXP) >= cells);
 #endif
-       cell_t *result = NULL;
        for ( ; index < QCGC_LARGE_FREE_LISTS; index++) {
                
while(qcgc_allocator_state.fit_state.large_free_list[index]->count
                                > 0) {
@@ -360,14 +373,11 @@
 
                        // Check whether block is still valid
                        if (valid_block(item.ptr, item.size)) {
+                               qcgc_arena_mark_allocated(item.ptr, cells);
                                qcgc_fit_allocator_add(item.ptr + cells, 
item.size - cells);
-                               result = item.ptr;
-                               break;
+                               return item.ptr;
                        }
                }
-               if (result != NULL) {
-                       return result;
-               }
        }
        return NULL;
 }
@@ -415,3 +425,31 @@
                                ((qcgc_arena_addr(ptr + cells)) == (arena_t *) 
(ptr + cells)) ||
                                qcgc_arena_get_blocktype(ptr + cells) != 
BLOCK_EXTENT));
 }
+
+QCGC_STATIC void free_list_consistency_check(void) {
+       for (size_t i = 0; i < QCGC_SMALL_FREE_LISTS; i++) {
+               linear_free_list_t *free_list =
+                       qcgc_allocator_state.fit_state.small_free_list[i];
+               for (size_t j = 0; j < free_list->count; j++) {
+                       cell_t *item = free_list->items[j];
+                       if  (qcgc_arena_get_blocktype(item) == BLOCK_FREE) {
+                               for (size_t s = 1; s < small_index_to_cells(i); 
s++) {
+                                       assert(qcgc_arena_get_blocktype(item + 
s) == BLOCK_EXTENT);
+                               }
+                       }
+               }
+       }
+
+       for (size_t i = 0; i < QCGC_LARGE_FREE_LISTS; i++) {
+               exp_free_list_t *free_list =
+                       qcgc_allocator_state.fit_state.large_free_list[i];
+               for (size_t j = 0; j < free_list->count; j++) {
+                       struct exp_free_list_item_s item = free_list->items[j];
+                       if  (qcgc_arena_get_blocktype(item.ptr) == BLOCK_FREE) {
+                               for (size_t s = 1; s < item.size; s++) {
+                                       
assert(qcgc_arena_get_blocktype(item.ptr + s) == BLOCK_EXTENT);
+                               }
+                       }
+               }
+       }
+}
diff --git a/rpython/translator/c/src/qcgc/allocator.h 
b/rpython/translator/c/src/qcgc/allocator.h
--- a/rpython/translator/c/src/qcgc/allocator.h
+++ b/rpython/translator/c/src/qcgc/allocator.h
@@ -89,6 +89,11 @@
  */
 object_t *qcgc_large_allocate(size_t bytes);
 
+/**
+ * Empty all free lists (used before sweep)
+ */
+void qcgc_fit_allocator_empty_lists(void);
+
 
 /**
  * Add memory to free lists
diff --git a/rpython/translator/c/src/qcgc/arena.c 
b/rpython/translator/c/src/qcgc/arena.c
--- a/rpython/translator/c/src/qcgc/arena.c
+++ b/rpython/translator/c/src/qcgc/arena.c
@@ -185,36 +185,20 @@
        assert(qcgc_arena_is_coalesced(arena));
        assert(qcgc_arena_addr(qcgc_allocator_state.bump_state.bump_ptr) == 
arena);
 #endif
-       // XXX: Maybe ignore free cell / largest block counting here?
-       size_t last_free_cell = 0;
+       // Ignore free cell / largest block counting here, as blocks are not
+       // registerd in free lists as well
        for (size_t cell = QCGC_ARENA_FIRST_CELL_INDEX;
                        cell < QCGC_ARENA_CELLS_COUNT;
                        cell++) {
                switch (get_blocktype(arena, cell)) {
-                       case BLOCK_FREE:
-                               last_free_cell = cell;
-                       case BLOCK_EXTENT: // Fall through
-                               break;
                        case BLOCK_BLACK:
                                set_blocktype(arena, cell, BLOCK_WHITE);
+                       case BLOCK_FREE: // Fall through
+                       case BLOCK_EXTENT: // Fall through
                        case BLOCK_WHITE: // Fall through
-                               if (last_free_cell != 0) {
-                                       qcgc_state.free_cells += cell - 
last_free_cell;
-                                       qcgc_state.largest_free_block = MAX(
-                                                       
qcgc_state.largest_free_block,
-                                                       cell - last_free_cell);
-                                       last_free_cell = 0;
-                               }
                                break;
                }
        }
-       if (last_free_cell != 0) {
-               qcgc_state.free_cells += QCGC_ARENA_CELLS_COUNT - 
last_free_cell;
-               qcgc_state.largest_free_block = MAX(
-                               qcgc_state.largest_free_block,
-                               QCGC_ARENA_CELLS_COUNT - last_free_cell);
-               last_free_cell = 0;
-       }
 #if CHECKED
        assert(qcgc_arena_is_coalesced(arena));
 #endif
@@ -232,7 +216,6 @@
        }
 
        size_t last_free_cell = 0;
-       bool register_free_block = false;
        bool free = true;
        for (size_t cell = QCGC_ARENA_FIRST_CELL_INDEX;
                        cell < QCGC_ARENA_CELLS_COUNT;
@@ -258,40 +241,34 @@
                                        last_free_cell = cell;
                                }
                                // ==> last_free_cell != 0
-                               register_free_block = true;
                                break;
                        case BLOCK_BLACK:
                                set_blocktype(arena, cell, BLOCK_WHITE);
                                if (last_free_cell != 0) {
-                                       if (register_free_block) {
-                                               
qcgc_fit_allocator_add(arena->cells + last_free_cell,
-                                                               cell - 
last_free_cell);
+                                       qcgc_fit_allocator_add(arena->cells + 
last_free_cell,
+                                                       cell - last_free_cell);
 #if DEBUG_ZERO_ON_SWEEP
-                                               memset(arena->cells + 
last_free_cell, 0,
-                                                               sizeof(cell_t) 
* (cell - last_free_cell));
+                                       memset(arena->cells + last_free_cell, 0,
+                                                       sizeof(cell_t) * (cell 
- last_free_cell));
 #endif
-                                       }
                                        qcgc_state.free_cells += cell - 
last_free_cell;
                                        qcgc_state.largest_free_block = MAX(
                                                        
qcgc_state.largest_free_block,
                                                        cell - last_free_cell);
                                        last_free_cell = 0;
                                }
-                               register_free_block = false;
                                free = false;
                                // ==> last_free_cell == 0
                                break;
                }
        }
        if (last_free_cell != 0 && !free) {
-               if (register_free_block) {
-                       qcgc_fit_allocator_add(arena->cells + last_free_cell,
-                                       QCGC_ARENA_CELLS_COUNT - 
last_free_cell);
+               qcgc_fit_allocator_add(arena->cells + last_free_cell,
+                               QCGC_ARENA_CELLS_COUNT - last_free_cell);
 #if DEBUG_ZERO_ON_SWEEP
-                       memset(arena->cells + last_free_cell, 0,
-                                       sizeof(cell_t) * 
(QCGC_ARENA_CELLS_COUNT - last_free_cell));
+               memset(arena->cells + last_free_cell, 0,
+                               sizeof(cell_t) * (QCGC_ARENA_CELLS_COUNT - 
last_free_cell));
 #endif
-               }
                qcgc_state.free_cells += QCGC_ARENA_CELLS_COUNT - 
last_free_cell;
                qcgc_state.largest_free_block = MAX(
                                qcgc_state.largest_free_block,
diff --git a/rpython/translator/c/src/qcgc/qcgc.c 
b/rpython/translator/c/src/qcgc/qcgc.c
--- a/rpython/translator/c/src/qcgc/qcgc.c
+++ b/rpython/translator/c/src/qcgc/qcgc.c
@@ -147,7 +147,8 @@
 
        if (size <= 1<<QCGC_LARGE_ALLOC_THRESHOLD_EXP) {
                // Use bump / fit allocator
-               if (qcgc_allocator_state.use_bump_allocator) {
+               //if (qcgc_allocator_state.use_bump_allocator) {
+               if (false) {
                        result = qcgc_bump_allocate(size);
                } else {
                        result = qcgc_fit_allocate(size);
@@ -368,6 +369,8 @@
        size_t i = 0;
        qcgc_state.free_cells = 0;
        qcgc_state.largest_free_block = 0;
+
+       qcgc_fit_allocator_empty_lists();
        while (i < qcgc_allocator_state.arenas->count) {
                arena_t *arena = qcgc_allocator_state.arenas->items[i];
                // The arena that contains the bump pointer is autmatically 
skipped
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to