From db202010a0a1895994805a4ad64b515a12cfb9b3 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Fri, 5 Apr 2013 12:50:11 +0200 Subject: [PATCH] move profiling utility code into external .c file --- Cython/Compiler/Nodes.py | 150 +---------------------------------------------- Cython/Utility/Profile.c | 138 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 148 deletions(-) create mode 100644 Cython/Utility/Profile.c diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index dcbfbf7..a4cfa48 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1541,7 +1541,8 @@ class FuncDefNode(StatNode, BlockNode): warning(self.pos, "Cannot profile nogil function.", 1) profile = False if profile: - code.globalstate.use_utility_code(profile_utility_code) + code.globalstate.use_utility_code( + UtilityCode.load_cached("Profile", "Profile.c")) # Generate C code for header and body of function code.enter_cfunc_scope() @@ -8154,153 +8155,6 @@ bad: } """) -#------------------------------------------------------------------------------------ - -# Note that cPython ignores PyTrace_EXCEPTION, -# but maybe some other profilers don't. - -profile_utility_code = UtilityCode(proto=""" -#ifndef CYTHON_PROFILE - #define CYTHON_PROFILE 1 -#endif - -#ifndef CYTHON_PROFILE_REUSE_FRAME - #define CYTHON_PROFILE_REUSE_FRAME 0 -#endif - -#if CYTHON_PROFILE - - #include "compile.h" - #include "frameobject.h" - #include "traceback.h" - - #if CYTHON_PROFILE_REUSE_FRAME - #define CYTHON_FRAME_MODIFIER static - #define CYTHON_FRAME_DEL - #else - #define CYTHON_FRAME_MODIFIER - #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s) - #endif - - #define __Pyx_TraceDeclarations \\ - static PyCodeObject *%(FRAME_CODE)s = NULL; \\ - CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\ - int __Pyx_use_tracing = 0; - - #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\ - if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\ - __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\ - } - - #define __Pyx_TraceException() \\ - if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\ - PyObject *exc_info = __Pyx_GetExceptionTuple(); \\ - if (exc_info) { \\ - PyThreadState_GET()->c_profilefunc( \\ - PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\ - Py_DECREF(exc_info); \\ - } \\ - } - - #define __Pyx_TraceReturn(result) \\ - if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\ - PyThreadState_GET()->c_profilefunc( \\ - PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\ - CYTHON_FRAME_DEL; \\ - } - - static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/ - static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/ - -#else - - #define __Pyx_TraceDeclarations - #define __Pyx_TraceCall(funcname, srcfile, firstlineno) - #define __Pyx_TraceException() - #define __Pyx_TraceReturn(result) - -#endif /* CYTHON_PROFILE */ -""" -% { - "FRAME": Naming.frame_cname, - "FRAME_CODE": Naming.frame_code_cname, -}, -impl = """ - -#if CYTHON_PROFILE - -static int __Pyx_TraceSetupAndCall(PyCodeObject** code, - PyFrameObject** frame, - const char *funcname, - const char *srcfile, - int firstlineno) { - if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) { - if (*code == NULL) { - *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno); - if (*code == NULL) return 0; - } - *frame = PyFrame_New( - PyThreadState_GET(), /*PyThreadState *tstate*/ - *code, /*PyCodeObject *code*/ - PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/ - 0 /*PyObject *locals*/ - ); - if (*frame == NULL) return 0; - } - else { - (*frame)->f_tstate = PyThreadState_GET(); - } - return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0; -} - -static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) { - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - PyCodeObject *py_code = 0; - - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - py_srcfile = PyString_FromString(srcfile); - #else - py_funcname = PyUnicode_FromString(funcname); - py_srcfile = PyUnicode_FromString(srcfile); - #endif - if (!py_funcname | !py_srcfile) goto bad; - - py_code = PyCode_New( - 0, /*int argcount,*/ - #if PY_MAJOR_VERSION >= 3 - 0, /*int kwonlyargcount,*/ - #endif - 0, /*int nlocals,*/ - 0, /*int stacksize,*/ - 0, /*int flags,*/ - %(EMPTY_BYTES)s, /*PyObject *code,*/ - %(EMPTY_TUPLE)s, /*PyObject *consts,*/ - %(EMPTY_TUPLE)s, /*PyObject *names,*/ - %(EMPTY_TUPLE)s, /*PyObject *varnames,*/ - %(EMPTY_TUPLE)s, /*PyObject *freevars,*/ - %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - firstlineno, /*int firstlineno,*/ - %(EMPTY_BYTES)s /*PyObject *lnotab*/ - ); - -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - - return py_code; -} - -#endif /* CYTHON_PROFILE */ -""" % { - 'EMPTY_TUPLE' : Naming.empty_tuple, - 'EMPTY_BYTES' : Naming.empty_bytes, - "MODULE": Naming.module_cname, -}) - ################ Utility code for cython.parallel stuff ################ invalid_values_utility_code = UtilityCode( diff --git a/Cython/Utility/Profile.c b/Cython/Utility/Profile.c new file mode 100644 index 0000000..495e019 --- /dev/null +++ b/Cython/Utility/Profile.c @@ -0,0 +1,138 @@ +/////////////// Profile.proto /////////////// +//@substitute: naming + +// Note that cPython ignores PyTrace_EXCEPTION, +// but maybe some other profilers don't. + +#ifndef CYTHON_PROFILE + #define CYTHON_PROFILE 1 +#endif + +#ifndef CYTHON_PROFILE_REUSE_FRAME + #define CYTHON_PROFILE_REUSE_FRAME 0 +#endif + +#if CYTHON_PROFILE + + #include "compile.h" + #include "frameobject.h" + #include "traceback.h" + + #if CYTHON_PROFILE_REUSE_FRAME + #define CYTHON_FRAME_MODIFIER static + #define CYTHON_FRAME_DEL + #else + #define CYTHON_FRAME_MODIFIER + #define CYTHON_FRAME_DEL Py_DECREF($frame_cname) + #endif + + #define __Pyx_TraceDeclarations \ + static PyCodeObject *$frame_code_cname = NULL; \ + CYTHON_FRAME_MODIFIER PyFrameObject *$frame_cname = NULL; \ + int __Pyx_use_tracing = 0; + + #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \ + if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \ + __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \ + } + + #define __Pyx_TraceException() \ + if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \ + PyObject *exc_info = __Pyx_GetExceptionTuple(); \ + if (exc_info) { \ + PyThreadState_GET()->c_profilefunc( \ + PyThreadState_GET()->c_profileobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \ + Py_DECREF(exc_info); \ + } \ + } + + #define __Pyx_TraceReturn(result) \ + if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \ + PyThreadState_GET()->c_profilefunc( \ + PyThreadState_GET()->c_profileobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \ + CYTHON_FRAME_DEL; \ + } + + static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/ + static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/ + +#else + + #define __Pyx_TraceDeclarations + #define __Pyx_TraceCall(funcname, srcfile, firstlineno) + #define __Pyx_TraceException() + #define __Pyx_TraceReturn(result) + +#endif /* CYTHON_PROFILE */ + +/////////////// Profile /////////////// +//@substitute: naming + +#if CYTHON_PROFILE + +static int __Pyx_TraceSetupAndCall(PyCodeObject** code, + PyFrameObject** frame, + const char *funcname, + const char *srcfile, + int firstlineno) { + if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) { + if (*code == NULL) { + *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno); + if (*code == NULL) return 0; + } + *frame = PyFrame_New( + PyThreadState_GET(), /*PyThreadState *tstate*/ + *code, /*PyCodeObject *code*/ + PyModule_GetDict($module_cname), /*PyObject *globals*/ + 0 /*PyObject *locals*/ + ); + if (*frame == NULL) return 0; + } + else { + (*frame)->f_tstate = PyThreadState_GET(); + } + return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0; +} + +static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) { + PyObject *py_srcfile = 0; + PyObject *py_funcname = 0; + PyCodeObject *py_code = 0; + + #if PY_MAJOR_VERSION < 3 + py_funcname = PyString_FromString(funcname); + py_srcfile = PyString_FromString(srcfile); + #else + py_funcname = PyUnicode_FromString(funcname); + py_srcfile = PyUnicode_FromString(srcfile); + #endif + if (!py_funcname | !py_srcfile) goto bad; + + py_code = PyCode_New( + 0, /*int argcount,*/ + #if PY_MAJOR_VERSION >= 3 + 0, /*int kwonlyargcount,*/ + #endif + 0, /*int nlocals,*/ + 0, /*int stacksize,*/ + 0, /*int flags,*/ + $empty_bytes, /*PyObject *code,*/ + $empty_tuple, /*PyObject *consts,*/ + $empty_tuple, /*PyObject *names,*/ + $empty_tuple, /*PyObject *varnames,*/ + $empty_tuple, /*PyObject *freevars,*/ + $empty_tuple, /*PyObject *cellvars,*/ + py_srcfile, /*PyObject *filename,*/ + py_funcname, /*PyObject *name,*/ + firstlineno, /*int firstlineno,*/ + $empty_bytes /*PyObject *lnotab*/ + ); + +bad: + Py_XDECREF(py_srcfile); + Py_XDECREF(py_funcname); + + return py_code; +} + +#endif /* CYTHON_PROFILE */ -- 2.7.4