[pypy-svn] r50135 - pypy/dist/pypy/translator/c/src

arigo at codespeak.net arigo at codespeak.net
Thu Dec 27 13:12:37 CET 2007


Author: arigo
Date: Thu Dec 27 13:12:36 2007
New Revision: 50135

Modified:
   pypy/dist/pypy/translator/c/src/stack.h
Log:
LL_stack_too_big() accounts for up to 10% of the run-time of PyPy,
because it's called extremely often.  Split it in a fast path and
a slow path.  Gives a ~3% improvement.


Modified: pypy/dist/pypy/translator/c/src/stack.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/stack.h	(original)
+++ pypy/dist/pypy/translator/c/src/stack.h	Thu Dec 27 13:12:36 2007
@@ -9,7 +9,26 @@
 #endif
 
 void LL_stack_unwind(void);
-int LL_stack_too_big(void);
+int LL_stack_too_big_slowpath(void);
+
+extern volatile char *_LLstacktoobig_stack_base_pointer;
+extern long _LLstacktoobig_stack_min;
+extern long _LLstacktoobig_stack_max;
+
+static int LL_stack_too_big(void)
+{
+	/* The fast path of stack_too_big, called extremely often.
+	   Making it static makes an *inlinable* copy of this small
+	   function's implementation in each compilation unit. */
+	char local;
+	long diff = &local - _LLstacktoobig_stack_base_pointer;
+	/* common case: we are still in the same thread as last time
+	   we checked, and still in the allowed part of the stack */
+	return ((diff < _LLstacktoobig_stack_min ||
+		 diff > _LLstacktoobig_stack_max)
+		/* if not, call the slow path */
+		&& LL_stack_too_big_slowpath());
+}
 
 #ifndef PYPY_NOT_MAIN_FILE
 #include <stdio.h>
@@ -33,15 +52,16 @@
 		return &local - parent;
 }
 
-int LL_stack_too_big(void)
+volatile char *_LLstacktoobig_stack_base_pointer = NULL;
+long _LLstacktoobig_stack_min = 0;
+long _LLstacktoobig_stack_max = 0;
+RPyThreadStaticTLS _LLstacktoobig_stack_base_pointer_key;
+
+int LL_stack_too_big_slowpath(void)
 {
 	char local;
 	long diff;
 	char *baseptr;
-	static volatile char *stack_base_pointer = NULL;
-	static long stack_min = 0;
-	static long stack_max = 0;
-	static RPyThreadStaticTLS stack_base_pointer_key;
 	/* Check that the stack is less than MAX_STACK_SIZE bytes bigger
 	   than the value recorded in stack_base_pointer.  The base
 	   pointer is updated to the current value if it is still NULL
@@ -50,41 +70,37 @@
 	   try to minimize its overhead by keeping a local copy in
 	   stack_pointer_pointer. */
 
-	diff = &local - stack_base_pointer;
-	if (stack_min <= diff && diff <= stack_max) {
-		/* common case: we are still in the same thread as last time
-		   we checked, and still in the allowed part of the stack */
-		return 0;
-	}
-
-	if (stack_min == stack_max /* == 0 */) {
+	if (_LLstacktoobig_stack_min == _LLstacktoobig_stack_max /* == 0 */) {
 		/* not initialized */
 		/* XXX We assume that initialization is performed early,
 		   when there is still only one thread running.  This
 		   allows us to ignore race conditions here */
-		char *errmsg = RPyThreadStaticTLS_Create(&stack_base_pointer_key);
+		char *errmsg = RPyThreadStaticTLS_Create(
+			&_LLstacktoobig_stack_base_pointer_key);
 		if (errmsg) {
 			/* XXX should we exit the process? */
 			fprintf(stderr, "Internal PyPy error: %s\n", errmsg);
 			return 1;
 		}
 		if (_LL_stack_growing_direction(NULL) > 0)
-			stack_max = MAX_STACK_SIZE;
+			_LLstacktoobig_stack_max = MAX_STACK_SIZE;
 		else
-			stack_min = -MAX_STACK_SIZE;
+			_LLstacktoobig_stack_min = -MAX_STACK_SIZE;
 	}
 
-	baseptr = (char *) RPyThreadStaticTLS_Get(stack_base_pointer_key);
+	baseptr = (char *) RPyThreadStaticTLS_Get(
+			_LLstacktoobig_stack_base_pointer_key);
 	if (baseptr != NULL) {
 		diff = &local - baseptr;
-		if (stack_min <= diff && diff <= stack_max) {
+		if (_LLstacktoobig_stack_min <= diff &&
+		    diff <= _LLstacktoobig_stack_max) {
 			/* within bounds */
-			stack_base_pointer = baseptr;
+			_LLstacktoobig_stack_base_pointer = baseptr;
 			return 0;
 		}
 
-		if ((stack_min == 0 && diff < 0) ||
-		    (stack_max == 0 && diff > 0)) {
+		if ((_LLstacktoobig_stack_min == 0 && diff < 0) ||
+		    (_LLstacktoobig_stack_max == 0 && diff > 0)) {
 			/* we underflowed the stack, which means that
 			   the initial estimation of the stack base must
 			   be revised (see below) */
@@ -96,8 +112,8 @@
 
 	/* update the stack base pointer to the current value */
 	baseptr = &local;
-	RPyThreadStaticTLS_Set(stack_base_pointer_key, baseptr);
-	stack_base_pointer = baseptr;
+	RPyThreadStaticTLS_Set(_LLstacktoobig_stack_base_pointer_key, baseptr);
+	_LLstacktoobig_stack_base_pointer = baseptr;
 	return 0;
 }
 



More information about the Pypy-commit mailing list