Author: Nicolas Truessel <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit