[pypy-commit] pypy quad-color-gc: Update qcgc

ntruessel pypy.commits at gmail.com
Tue Sep 20 16:52:33 EDT 2016


Author: Nicolas Truessel <ntruessel at njsm.de>
Branch: quad-color-gc
Changeset: r87261:d78ddf89fd0b
Date: 2016-09-20 22:51 +0200
http://bitbucket.org/pypy/pypy/changeset/d78ddf89fd0b/

Log:	Update qcgc

diff --git a/rpython/translator/c/src/qcgc/config.h b/rpython/translator/c/src/qcgc/config.h
--- a/rpython/translator/c/src/qcgc/config.h
+++ b/rpython/translator/c/src/qcgc/config.h
@@ -11,7 +11,8 @@
 #define EVENT_LOG 1							// Enable event log
 #define LOGFILE "./qcgc_events.log"			// Default logfile
 #define LOG_ALLOCATION 0					// Enable allocation log
-#define LOG_DUMP_FREELIST_STATS 1			// Dump freelist stats
+#define LOG_DUMP_FREELIST_STATS 0			// Dump freelist stats
+#define LOG_ALLOCATOR_SWITCH 0				// Log allocator switches
 
 #define QCGC_SHADOWSTACK_SIZE 163840		// Total shadowstack size
 #define QCGC_ARENA_BAG_INIT_SIZE 16			// Initial size of the arena bag
@@ -19,7 +20,7 @@
 #define QCGC_LARGE_ALLOC_THRESHOLD_EXP 14	// Less than QCGC_ARENA_SIZE_EXP
 #define QCGC_MARK_LIST_SEGMENT_SIZE 64		// TODO: Tune for performance
 #define QCGC_GRAY_STACK_INIT_SIZE 128		// TODO: Tune for performance
-#define QCGC_INC_MARK_MIN 64				// TODO: Tune for performance
+#define QCGC_INC_MARK_MIN 1024				// TODO: Tune for performance
 
 /**
  * Fit allocator
@@ -31,8 +32,8 @@
 /**
  * Auto Mark/Collect
  */
-#define QCGC_INCMARK_THRESHOLD (1<<(QCGC_ARENA_SIZE_EXP-4))
-#define QCGC_INCMARK_TO_SWEEP 5
+#define QCGC_INCMARK_THRESHOLD (1<<(QCGC_ARENA_SIZE_EXP-5))
+#define QCGC_INCMARK_TO_SWEEP 10
 
 /**
  * DO NOT MODIFY BELOW HERE
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
@@ -88,6 +88,9 @@
 object_t *_qcgc_allocate_slowpath(size_t size) {
 	bool use_fit_allocator = _qcgc_bump_allocator.ptr == NULL;
 	size_t cells = bytes_to_cells(size);
+#if LOG_ALLOCATOR_SWITCH
+	bool old_use_fit_allocator = use_fit_allocator;
+#endif
 
 	if (UNLIKELY(qcgc_state.cells_since_incmark >
 				qcgc_state.incmark_threshold)) {
@@ -103,7 +106,7 @@
 
 	object_t *result = NULL;
 	if (!use_fit_allocator) {
-		qcgc_bump_allocator_renew_block(false);
+		qcgc_bump_allocator_renew_block(size, false);
 
 		qcgc_state.cells_since_incmark += _qcgc_bump_allocator.end -
 			_qcgc_bump_allocator.ptr;
@@ -124,16 +127,47 @@
 #endif
 
 			result->flags = QCGC_GRAY_FLAG;
+#if LOG_ALLOCATOR_SWITCH
+			if ((_qcgc_bump_allocator.ptr == NULL) != old_use_fit_allocator) {
+				// Allocator switched
+				struct log_info_s {
+					size_t allocations;
+					bool fit_allocator;
+				};
+				struct log_info_s log_info = {
+					qcgc_allocations,
+					_qcgc_bump_allocator.ptr == NULL,
+				};
+				qcgc_event_logger_log(EVENT_ALLOCATOR_SWITCH, sizeof(struct log_info_s),
+						(uint8_t *) &log_info);
+			}
+#endif
 			return result;
 		}
 	}
 
 	// Fit allocate
+	result = qcgc_fit_allocate(size);
 	if (result != NULL) {
 		qcgc_state.cells_since_incmark += bytes_to_cells(size);
+#if LOG_ALLOCATOR_SWITCH
+		if ((_qcgc_bump_allocator.ptr == NULL) != old_use_fit_allocator) {
+			// Allocator switched
+			struct log_info_s {
+				size_t allocations;
+				bool fit_allocator;
+			};
+			struct log_info_s log_info = {
+				qcgc_allocations,
+				_qcgc_bump_allocator.ptr == NULL,
+			};
+			qcgc_event_logger_log(EVENT_ALLOCATOR_SWITCH, sizeof(struct log_info_s),
+					(uint8_t *) &log_info);
+		}
+#endif
 		return result;
 	}
-	qcgc_bump_allocator_renew_block(true);
+	qcgc_bump_allocator_renew_block(size, true);
 	qcgc_state.cells_since_incmark +=
 		_qcgc_bump_allocator.end - _qcgc_bump_allocator.ptr;
 
@@ -150,6 +184,21 @@
 #endif
 
 	result->flags = QCGC_GRAY_FLAG;
+#if LOG_ALLOCATOR_SWITCH
+	if ((_qcgc_bump_allocator.ptr == NULL) != old_use_fit_allocator) {
+		// Allocator switched
+		struct log_info_s {
+			size_t allocations;
+			bool fit_allocator;
+		};
+		struct log_info_s log_info = {
+			qcgc_allocations,
+			_qcgc_bump_allocator.ptr == NULL,
+		};
+		qcgc_event_logger_log(EVENT_ALLOCATOR_SWITCH, sizeof(struct log_info_s),
+				(uint8_t *) &log_info);
+	}
+#endif
 	return result;
 }
 
diff --git a/rpython/translator/c/src/qcgc/qcgc.h b/rpython/translator/c/src/qcgc/qcgc.h
--- a/rpython/translator/c/src/qcgc/qcgc.h
+++ b/rpython/translator/c/src/qcgc/qcgc.h
@@ -59,6 +59,10 @@
 	object_t *items[];
 } object_stack_t;
 
+#if LOG_ALLOCATOR_SWITCH
+size_t qcgc_allocations = 0;
+#endif
+
 /**
  * Arena
  */
@@ -200,6 +204,10 @@
 #endif
 	size_t cells = bytes_to_cells(size);
 
+#if LOG_ALLOCATOR_SWITCH
+	qcgc_allocations++;
+#endif
+
 #if LOG_ALLOCATION
 	qcgc_event_logger_log(EVENT_ALLOCATE, sizeof(size_t),
 			(uint8_t *) &cells);
@@ -281,6 +289,6 @@
  * @param	object	The object to trace
  * @param	visit	The function to be called on the referenced objects
  */
-extern void qcgc_trace_cb(object_t *object, void (*visit)(object_t *object));
+void qcgc_trace_cb(object_t *object, void (*visit)(object_t *object));
 
 #endif
diff --git a/rpython/translator/c/src/qcgc/src/allocator.c b/rpython/translator/c/src/qcgc/src/allocator.c
--- a/rpython/translator/c/src/qcgc/src/allocator.c
+++ b/rpython/translator/c/src/qcgc/src/allocator.c
@@ -33,7 +33,7 @@
 
 	_qcgc_bump_allocator.ptr = NULL;
 	_qcgc_bump_allocator.end = NULL;
-	qcgc_bump_allocator_renew_block(true);
+	qcgc_bump_allocator_renew_block(0,true);
 }
 
 void qcgc_allocator_destroy(void) {
@@ -65,7 +65,7 @@
  * Bump Allocator                                                              *
  ******************************************************************************/
 
-void qcgc_bump_allocator_renew_block(bool force_arena) {
+void qcgc_bump_allocator_renew_block(size_t size, bool force_arena) {
 #if CHECKED
 	if (_qcgc_bump_allocator.end > _qcgc_bump_allocator.ptr) {
 		for (cell_t *it = _qcgc_bump_allocator.ptr + 1;
@@ -79,19 +79,25 @@
 	qcgc_reset_bump_ptr();
 
 	// Always use a huge block if there is one
-	exp_free_list_t *free_list = qcgc_allocator_state.fit_state.
-		large_free_list[QCGC_LARGE_FREE_LISTS - 1];
+	assert(3 < QCGC_LARGE_FREE_LISTS);
+	size_t cells = bytes_to_cells(size);
+	size_t i = is_small(cells) ? 3 : MAX(3, large_index(cells) + 1);
+	for (; i < QCGC_LARGE_FREE_LISTS; i++) {
+		exp_free_list_t *free_list = qcgc_allocator_state.fit_state.
+			large_free_list[i];
+		if (free_list->count > 0) {
+			// Assign block to bump allocator
+			bump_allocator_assign(free_list->items[0].ptr,
+					free_list->items[0].size);
+			free_list = qcgc_exp_free_list_remove_index(free_list, 0);
 
-	if (free_list->count > 0) {
-		// Assign huge block to bump allocator
-		bump_allocator_assign(free_list->items[0].ptr,
-				free_list->items[0].size);
-		free_list = qcgc_exp_free_list_remove_index(free_list, 0);
-		qcgc_allocator_state.fit_state.
-			large_free_list[QCGC_LARGE_FREE_LISTS - 1] = free_list;
-		qcgc_state.free_cells -=
-			_qcgc_bump_allocator.end - _qcgc_bump_allocator.ptr;
-	} else {
+			qcgc_allocator_state.fit_state.large_free_list[i] = free_list;
+			qcgc_state.free_cells -=
+				_qcgc_bump_allocator.end - _qcgc_bump_allocator.ptr;
+		}
+	}
+
+	if (_qcgc_bump_allocator.ptr == NULL) {
 		if (qcgc_allocator_state.free_arenas->count > 0) {
 			// Reuse arena
 			arena_t *arena = qcgc_allocator_state.free_arenas->items[0];
diff --git a/rpython/translator/c/src/qcgc/src/allocator.h b/rpython/translator/c/src/qcgc/src/allocator.h
--- a/rpython/translator/c/src/qcgc/src/allocator.h
+++ b/rpython/translator/c/src/qcgc/src/allocator.h
@@ -100,6 +100,7 @@
 /**
  * Find a new block for the bump allocator
  *
+ * @param	size		Minimal size
  * @param	force_arena	Force generation of new arena if no block is found
  */
-void qcgc_bump_allocator_renew_block(bool force_arena);
+void qcgc_bump_allocator_renew_block(size_t size, bool force_arena);
diff --git a/rpython/translator/c/src/qcgc/src/collector.c b/rpython/translator/c/src/qcgc/src/collector.c
--- a/rpython/translator/c/src/qcgc/src/collector.c
+++ b/rpython/translator/c/src/qcgc/src/collector.c
@@ -155,7 +155,7 @@
 	qcgc_trace_cb(object, &qcgc_push_object);
 }
 
-QCGC_STATIC void qcgc_push_object(object_t *object) {
+QCGC_STATIC QCGC_INLINE void qcgc_push_object(object_t *object) {
 #if CHECKED
 	assert(qcgc_state.phase == GC_MARK);
 #endif
diff --git a/rpython/translator/c/src/qcgc/src/event_logger.c b/rpython/translator/c/src/qcgc/src/event_logger.c
--- a/rpython/translator/c/src/qcgc/src/event_logger.c
+++ b/rpython/translator/c/src/qcgc/src/event_logger.c
@@ -14,7 +14,8 @@
 void qcgc_event_logger_initialize(void) {
 #if EVENT_LOG
 	event_logger_state.logfile = fopen(LOGFILE, "w");
-	qcgc_event_logger_log(EVENT_LOG_START, 0, NULL);
+	size_t arena_cells = 1<<QCGC_ARENA_SIZE_EXP;
+	qcgc_event_logger_log(EVENT_LOG_START, sizeof(size_t), (uint8_t *)&arena_cells);
 
 	if (event_logger_state.logfile == NULL)  {
 		fprintf(stderr, "%s\n", "Failed to create logfile.");
diff --git a/rpython/translator/c/src/qcgc/src/event_logger.h b/rpython/translator/c/src/qcgc/src/event_logger.h
--- a/rpython/translator/c/src/qcgc/src/event_logger.h
+++ b/rpython/translator/c/src/qcgc/src/event_logger.h
@@ -23,6 +23,8 @@
 	EVENT_MARK_DONE,
 
 	EVENT_FREELIST_DUMP,
+
+	EVENT_ALLOCATOR_SWITCH,
 };
 
 /**


More information about the pypy-commit mailing list