[pypy-commit] pypy quad-color-gc: Update qcgc codebase (performance optimizations)

ntruessel pypy.commits at gmail.com
Mon Sep 12 06:26:23 EDT 2016


Author: Nicolas Truessel <ntruessel at njsm.de>
Branch: quad-color-gc
Changeset: r87033:332c546faefd
Date: 2016-09-12 12:25 +0200
http://bitbucket.org/pypy/pypy/changeset/332c546faefd/

Log:	Update qcgc codebase (performance optimizations)

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
@@ -276,24 +276,16 @@
 	for ( ; index < QCGC_SMALL_FREE_LISTS; index++) {
 		size_t list_cell_size = small_index_to_cells(index);
 
-		while (qcgc_allocator_state.fit_state.small_free_list[index]->count
-				> 0) {
+		if (qcgc_allocator_state.fit_state.small_free_list[index]->count > 0) {
 			result = qcgc_allocator_state.fit_state.small_free_list[index]->
-				items[qcgc_allocator_state.fit_state.small_free_list[index]
-				->count - 1];
+				items[0];
 			qcgc_allocator_state.fit_state.small_free_list[index] =
 				qcgc_linear_free_list_remove_index(
 						qcgc_allocator_state.fit_state.small_free_list[index],
-						qcgc_allocator_state.fit_state.small_free_list[index]->
-						count - 1);
-
-			// 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);
-				return result;
-			}
+						0);
+			qcgc_arena_mark_allocated(result, cells);
+			qcgc_fit_allocator_add(result + cells, list_cell_size - cells);
+			return result;
 		}
 	}
 	return fit_allocator_large_first_fit(0, cells);
@@ -309,30 +301,18 @@
 
 	cell_t *result = NULL;
 	size_t best_fit_cells = SIZE_MAX;
-	size_t i = 0;
-	while (i < qcgc_allocator_state.fit_state.large_free_list[index]->count) {
-		if (valid_block(qcgc_allocator_state.fit_state.large_free_list[index] ->
-					items[i].ptr,
-					qcgc_allocator_state.fit_state.large_free_list[index]->
-					items[i].size)) {
-			if (qcgc_allocator_state.fit_state.large_free_list[index]->
-					items[i].size >= cells &&
-					qcgc_allocator_state.fit_state.large_free_list[index]->
-					items[i].size < best_fit_cells) {
-				result = qcgc_allocator_state.fit_state.large_free_list[index]->
-					items[i].ptr;
-				best_fit_cells = qcgc_allocator_state.fit_state.
-					large_free_list[index]->items[i].size;
-				best_fit_index = i;
-			}
-			i++;
-		} else {
-			qcgc_allocator_state.fit_state.large_free_list[index] =
-				qcgc_exp_free_list_remove_index(qcgc_allocator_state.fit_state.
-						large_free_list[index], i);
-			// NO i++ !
+	size_t count = qcgc_allocator_state.fit_state.large_free_list[index]->count;
+	for (size_t i = 0; i < count; i++) {
+		if (qcgc_allocator_state.fit_state.large_free_list[index]->
+				items[i].size >= cells &&
+				qcgc_allocator_state.fit_state.large_free_list[index]->
+				items[i].size < best_fit_cells) {
+			result = qcgc_allocator_state.fit_state.large_free_list[index]->
+				items[i].ptr;
+			best_fit_cells = qcgc_allocator_state.fit_state.
+				large_free_list[index]->items[i].size;
+			best_fit_index = i;
 		}
-
 		if (best_fit_cells == cells) {
 			break;
 		}
@@ -359,24 +339,17 @@
 	assert(1u<<(index + QCGC_LARGE_FREE_LIST_FIRST_EXP) >= cells);
 #endif
 	for ( ; index < QCGC_LARGE_FREE_LISTS; index++) {
-		while(qcgc_allocator_state.fit_state.large_free_list[index]->count
-				> 0) {
+		if (qcgc_allocator_state.fit_state.large_free_list[index]->count > 0) {
 			struct exp_free_list_item_s item =
-				qcgc_allocator_state.fit_state.large_free_list[index]->items[
-				qcgc_allocator_state.fit_state.large_free_list[index]->count - 1
-				];
+				qcgc_allocator_state.fit_state.large_free_list[index]->items[0];
 			qcgc_allocator_state.fit_state.large_free_list[index] =
 				qcgc_exp_free_list_remove_index(
 						qcgc_allocator_state.fit_state.large_free_list[index],
-						qcgc_allocator_state.fit_state.large_free_list[index]->
-						count - 1);
+						0);
 
-			// 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);
-				return item.ptr;
-			}
+			qcgc_arena_mark_allocated(item.ptr, cells);
+			qcgc_fit_allocator_add(item.ptr + cells, item.size - cells);
+			return item.ptr;
 		}
 	}
 	return NULL;
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
@@ -69,11 +69,6 @@
  * Shadow stack
  */
 void qcgc_shadowstack_push(object_t *object) {
-	if (qcgc_state.phase != GC_PAUSE) {
-		qcgc_state.phase = GC_MARK;
-		qcgc_push_object(object);
-	}
-
 	*qcgc_state.shadow_stack = object;
 	qcgc_state.shadow_stack++;
 }
@@ -153,8 +148,7 @@
 
 	if (size <= 1<<QCGC_LARGE_ALLOC_THRESHOLD_EXP) {
 		// Use bump / fit allocator
-		//if (qcgc_allocator_state.use_bump_allocator) {
-		if (false) {
+		if (qcgc_allocator_state.use_bump_allocator) {
 			result = qcgc_bump_allocate(size);
 		} else {
 			result = qcgc_fit_allocate(size);
@@ -209,10 +203,6 @@
 }
 
 void qcgc_mark(bool incremental) {
-	if (qcgc_state.phase == GC_COLLECT) {
-		return;	// Fast exit when there is nothing to mark
-	}
-
 	{
 		struct log_info_s {
 			bool incremental;
@@ -226,16 +216,6 @@
 	qcgc_state.bytes_since_incmark = 0;
 
 	if (qcgc_state.phase == GC_PAUSE) {
-		qcgc_state.phase = GC_MARK;
-
-		// If we do this for the first time, push all roots.
-		// All further changes to the roots (new additions) will be added
-		// by qcgc_shadowstack_push
-		for (object_t **it = qcgc_state.shadow_stack_base;
-			it < qcgc_state.shadow_stack;
-			it++) {
-			qcgc_push_object(*it);
-		}
 
 		// If we do this for the first time, push all prebuilt objects.
 		// All further changes to prebuilt objects will go to the gp_gray_stack
@@ -248,6 +228,15 @@
 		}
 	}
 
+	qcgc_state.phase = GC_MARK;
+
+	// Always push all roots to make shadowstack pushes faster
+	for (object_t **it = qcgc_state.shadow_stack_base;
+		it < qcgc_state.shadow_stack;
+		it++) {
+		qcgc_push_object(*it);
+	}
+
 	while (qcgc_state.gray_stack_size > 0) {
 		// General purpose gray stack (prebuilt objects and huge blocks)
 		size_t to_process = (incremental ?


More information about the pypy-commit mailing list