]> granicus.if.org Git - python/commitdiff
Massive performance improvement for C extension and builtin tracing code
authorNicholas Bastin <nick.bastin@gmail.com>
Fri, 25 Jun 2004 23:31:06 +0000 (23:31 +0000)
committerNicholas Bastin <nick.bastin@gmail.com>
Fri, 25 Jun 2004 23:31:06 +0000 (23:31 +0000)
Lib/test/output/test_profile
Python/ceval.c
configure
configure.in
pyconfig.h.in

index b46bb6ab739cdf09d46893c02b23a84144b63041..baa25091e9f89a66703e468187c058e0b770f4bf 100644 (file)
@@ -4,9 +4,9 @@ test_profile
    Ordered by: standard name
 
    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
-       12    0.000    0.000    0.012    0.001 :0(hasattr)
-        8    0.000    0.000    0.000    0.000 :0(range)
-        1    0.000    0.000    0.000    0.000 :0(setprofile)
+       12    0.000    0.000    0.012    0.001 :0(<built-in function hasattr>)
+        8    0.000    0.000    0.000    0.000 :0(<built-in function range>)
+        1    0.000    0.000    0.000    0.000 :0(<built-in function setprofile>)
         1    0.000    0.000    1.000    1.000 <string>:1(?)
         0    0.000             0.000          profile:0(profiler)
         1    0.000    0.000    1.000    1.000 profile:0(testfunc())
index 6f6fef65b3f9f8fd6a3aae132ec64cfcf896959d..b320f61681ce1a1213e5d89d7d38eb2387bbdc67 100644 (file)
@@ -3438,47 +3438,33 @@ err_args(PyObject *func, int flags, int nargs)
                             nargs);
 }
 
-#ifdef WITH_C_PROF
-#define BEGIN_C_TRACE \
-if (tstate->use_tracing) { \
+#define C_TRACE(call) \
+if (tstate->use_tracing && tstate->c_profilefunc) { \
+       if (call_trace(tstate->c_profilefunc, \
+               tstate->c_profileobj, \
+               tstate->frame, PyTrace_C_CALL, \
+               func)) \
+               { return NULL; } \
+       call; \
        if (tstate->c_profilefunc != NULL) { \
-               PyObject *func_name = \
-                       PyString_FromString (((PyCFunctionObject *) \
-                                               func)->m_ml->ml_name); \
-               are_tracing = 1; \
-               if (call_trace(tstate->c_profilefunc, \
-                       tstate->c_profileobj, \
-                       tstate->frame, PyTrace_C_CALL, \
-                       func_name)) \
-                       { return NULL; } \
-               Py_DECREF (func_name); \
+               if (x == NULL) { \
+                       if (call_trace (tstate->c_profilefunc, \
+                               tstate->c_profileobj, \
+                               tstate->frame, PyTrace_C_EXCEPTION, \
+                               func)) \
+                               { return NULL; } \
+               } else { \
+                       if (call_trace(tstate->c_profilefunc, \
+                               tstate->c_profileobj, \
+                               tstate->frame, PyTrace_C_RETURN, \
+                               func)) \
+                               { return NULL; } \
                } \
+       } \
+} else { \
+       call; \
        }
 
-#define END_C_TRACE \
-       if (tstate->use_tracing && are_tracing) { \
-               if (tstate->c_profilefunc != NULL) { \
-                       if (x == NULL) { \
-                               if (call_trace (tstate->c_profilefunc, \
-                                       tstate->c_profileobj, \
-                                       tstate->frame, PyTrace_C_EXCEPTION, \
-                                       NULL)) \
-                                       { return NULL; } \
-                       } else { \
-                               if (call_trace(tstate->c_profilefunc, \
-                                       tstate->c_profileobj, \
-                                       tstate->frame, PyTrace_C_RETURN, \
-                                       NULL))  \
-                                       { return NULL; } \
-                       } \
-               } \
-       }
-#else
-#define BEGIN_C_TRACE
-#define END_C_TRACE
-#endif
-
-
 static PyObject *
 call_function(PyObject ***pp_stack, int oparg
 #ifdef WITH_TSC
@@ -3493,30 +3479,22 @@ call_function(PyObject ***pp_stack, int oparg
        PyObject *func = *pfunc;
        PyObject *x, *w;
 
-#ifdef WITH_C_PROF
-       int     are_tracing = 0;
-       PyThreadState *tstate = PyThreadState_GET();
-#endif
-
        /* Always dispatch PyCFunction first, because these are
           presumed to be the most frequent callable object.
        */
        if (PyCFunction_Check(func) && nk == 0) {
                int flags = PyCFunction_GET_FLAGS(func);
                PCALL(PCALL_CFUNCTION);
+               PyThreadState *tstate = PyThreadState_GET();
                if (flags & (METH_NOARGS | METH_O)) {
                        PyCFunction meth = PyCFunction_GET_FUNCTION(func);
                        PyObject *self = PyCFunction_GET_SELF(func);
                        if (flags & METH_NOARGS && na == 0) {
-                               BEGIN_C_TRACE
-                               x = (*meth)(self, NULL);
-                               END_C_TRACE
+                               C_TRACE(x=(*meth)(self,NULL));
                        }
                        else if (flags & METH_O && na == 1) {
                                PyObject *arg = EXT_POP(*pp_stack);
-                               BEGIN_C_TRACE
-                               x = (*meth)(self, arg);
-                               END_C_TRACE
+                               C_TRACE(x=(*meth)(self,arg));
                                Py_DECREF(arg);
                        }
                        else {
@@ -3527,15 +3505,13 @@ call_function(PyObject ***pp_stack, int oparg
                else {
                        PyObject *callargs;
                        callargs = load_args(pp_stack, na);
-                       BEGIN_C_TRACE
 #ifdef WITH_TSC
                        rdtscll(*pintr0);
 #endif
-                       x = PyCFunction_Call(func, callargs, NULL);
+                       C_TRACE(x=PyCFunction_Call(func,callargs,NULL));
 #ifdef WITH_TSC
                        rdtscll(*pintr1);
 #endif
-                       END_C_TRACE
                        Py_XDECREF(callargs);
                }
        } else {
index 0c0c443c3e46e630712abc547f3741062a78a37c..31e6541edd24a5f7eb66d228e1c9064475a5006d 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.in Revision: 1.458 .
+# From configure.in Revision: 1.459 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59 for python 2.4.
 #
@@ -869,7 +869,6 @@ Optional Packages:
                           deprecated; use --with(out)-threads
   --with-pth              use GNU pth threading libraries
   --with(out)-doc-strings disable/enable documentation strings
-  --with-c-profiling      Enable profiling of builtins and C extension functions
   --with(out)-tsc         enable/disable timestamp counter profile
   --with(out)-pymalloc    disable/enable specialized mallocs
   --with-wctype-functions use wctype.h functions
 echo "$as_me:$LINENO: result: $with_doc_strings" >&5
 echo "${ECHO_T}$with_doc_strings" >&6
 
-# Check for C call profiling support
-echo "$as_me:$LINENO: checking for --with-c-profiling" >&5
-echo $ECHO_N "checking for --with-c-profiling... $ECHO_C" >&6
-
-# Check whether --with-c-profiling or --without-c-profiling was given.
-if test "${with_c_profiling+set}" = set; then
-  withval="$with_c_profiling"
-
-if test "$withval" != no
-then
-
-cat >>confdefs.h <<\_ACEOF
-#define WITH_C_PROF 1
-_ACEOF
-
-    echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi;
-
 # Check for Python-specific malloc support
 echo "$as_me:$LINENO: checking for --with-tsc" >&5
 echo $ECHO_N "checking for --with-tsc... $ECHO_C" >&6
index c766eb18912b804e2f481033821bf72d2933677e..7e1387447a29ec9409e10a3d808a80b549ea9674 100644 (file)
@@ -1946,19 +1946,6 @@ then
 fi
 AC_MSG_RESULT($with_doc_strings)
 
-# Check for C call profiling support
-AC_MSG_CHECKING(for --with-c-profiling)
-AC_ARG_WITH(c-profiling,
-[  --with-c-profiling      Enable profiling of builtins and C extension functions], [
-if test "$withval" != no
-then
-  AC_DEFINE(WITH_C_PROF, 1,
-    [Define to enable profile hooks for C extension functions and builtins])
-    AC_MSG_RESULT(yes)
-else AC_MSG_RESULT(no)
-fi],
-[AC_MSG_RESULT(no)])
-
 # Check for Python-specific malloc support
 AC_MSG_CHECKING(for --with-tsc)
 AC_ARG_WITH(tsc,
index e939c013c6967537918f5ab02f2f9389a24ebebc..8cb0cffb78c3ff4d9b26fedec0659d3285ea4c46 100644 (file)
 /* Define if WINDOW in curses.h offers a field _flags. */
 #undef WINDOW_HAS_FLAGS
 
-/* Define to enable profile hooks for C extension functions and builtins */
-#undef WITH_C_PROF
-
 /* Define if you want documentation strings in extension modules */
 #undef WITH_DOC_STRINGS