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