1 /////////////// Profile.proto ///////////////
4 // Note that cPython ignores PyTrace_EXCEPTION,
5 // but maybe some other profilers don't.
8 #define CYTHON_PROFILE 1
12 #define CYTHON_TRACE 0
16 #undef CYTHON_PROFILE_REUSE_FRAME
19 #ifndef CYTHON_PROFILE_REUSE_FRAME
20 #define CYTHON_PROFILE_REUSE_FRAME 0
23 #if CYTHON_PROFILE || CYTHON_TRACE
26 #include "frameobject.h"
27 #include "traceback.h"
29 #if CYTHON_PROFILE_REUSE_FRAME
30 #define CYTHON_FRAME_MODIFIER static
31 #define CYTHON_FRAME_DEL
33 #define CYTHON_FRAME_MODIFIER
34 #define CYTHON_FRAME_DEL Py_CLEAR($frame_cname)
37 #define __Pyx_TraceDeclarations \
38 static PyCodeObject *$frame_code_cname = NULL; \
39 CYTHON_FRAME_MODIFIER PyFrameObject *$frame_cname = NULL; \
40 int __Pyx_use_tracing = 0;
42 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \
43 if (unlikely(PyThreadState_GET()->use_tracing && \
44 (PyThreadState_GET()->c_profilefunc || (CYTHON_TRACE && PyThreadState_GET()->c_tracefunc)))) { \
45 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, funcname, srcfile, firstlineno); \
48 #define __Pyx_TraceException() \
49 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && \
50 (PyThreadState_GET()->c_profilefunc || (CYTHON_TRACE && PyThreadState_GET()->c_tracefunc))) { \
51 PyThreadState* tstate = PyThreadState_GET(); \
52 tstate->use_tracing = 0; \
53 PyObject *exc_info = __Pyx_GetExceptionTuple(); \
55 if (CYTHON_TRACE && tstate->c_tracefunc) \
56 tstate->c_tracefunc( \
57 tstate->c_traceobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \
58 tstate->c_profilefunc( \
59 tstate->c_profileobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \
60 Py_DECREF(exc_info); \
62 tstate->use_tracing = 1; \
65 #define __Pyx_TraceReturn(result) \
66 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing) { \
67 PyThreadState* tstate = PyThreadState_GET(); \
68 tstate->use_tracing = 0; \
69 if (CYTHON_TRACE && tstate->c_tracefunc) \
70 tstate->c_tracefunc( \
71 tstate->c_traceobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \
72 if (tstate->c_profilefunc) \
73 tstate->c_profilefunc( \
74 tstate->c_profileobj, $frame_cname, PyTrace_RETURN, (PyObject*)result); \
76 tstate->use_tracing = 1; \
79 static PyCodeObject
*__Pyx_createFrameCodeObject(const char *funcname
, const char *srcfile
, int firstlineno
); /*proto*/
80 static int __Pyx_TraceSetupAndCall(PyCodeObject
** code
, PyFrameObject
** frame
, const char *funcname
, const char *srcfile
, int firstlineno
); /*proto*/
84 #define __Pyx_TraceDeclarations
85 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
86 #define __Pyx_TraceException()
87 #define __Pyx_TraceReturn(result)
89 #endif /* CYTHON_PROFILE */
92 #define __Pyx_TraceLine(lineno) \
93 if (unlikely(__Pyx_use_tracing) && unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_tracefunc)) { \
94 PyThreadState* tstate = PyThreadState_GET(); \
95 $frame_cname->f_lineno = lineno; \
96 tstate->use_tracing = 0; \
97 tstate->c_tracefunc(tstate->c_traceobj, $frame_cname, PyTrace_LINE, NULL); \
98 tstate->use_tracing = 1; \
101 #define __Pyx_TraceLine(lineno)
104 /////////////// Profile ///////////////
105 //@substitute: naming
109 static int __Pyx_TraceSetupAndCall(PyCodeObject
** code
,
110 PyFrameObject
** frame
,
111 const char *funcname
,
115 PyThreadState
* tstate
= PyThreadState_GET();
116 if (*frame
== NULL
|| !CYTHON_PROFILE_REUSE_FRAME
) {
118 *code
= __Pyx_createFrameCodeObject(funcname
, srcfile
, firstlineno
);
119 if (*code
== NULL
) return 0;
121 *frame
= PyFrame_New(
122 tstate
, /*PyThreadState *tstate*/
123 *code
, /*PyCodeObject *code*/
124 $moddict_cname
, /*PyObject *globals*/
125 0 /*PyObject *locals*/
127 if (*frame
== NULL
) return 0;
128 if (CYTHON_TRACE
&& (*frame
)->f_trace
== NULL
) {
129 // this enables "f_lineno" lookup, at least in CPython ...
131 (*frame
)->f_trace
= Py_None
;
133 #if PY_VERSION_HEX < 0x030400B1
135 (*frame
)->f_tstate
= tstate
;
138 (*frame
)->f_lineno
= firstlineno
;
139 tstate
->use_tracing
= 0;
141 if (tstate
->c_tracefunc
)
142 tstate
->c_tracefunc(tstate
->c_traceobj
, *frame
, PyTrace_CALL
, NULL
);
143 if (!tstate
->c_profilefunc
)
147 retval
= tstate
->c_profilefunc(tstate
->c_profileobj
, *frame
, PyTrace_CALL
, NULL
) == 0;
148 tstate
->use_tracing
= (tstate
->c_profilefunc
||
149 (CYTHON_TRACE
&& tstate
->c_tracefunc
));
150 return tstate
->use_tracing
&& retval
;
153 static PyCodeObject
*__Pyx_createFrameCodeObject(const char *funcname
, const char *srcfile
, int firstlineno
) {
154 PyObject
*py_srcfile
= 0;
155 PyObject
*py_funcname
= 0;
156 PyCodeObject
*py_code
= 0;
158 #if PY_MAJOR_VERSION < 3
159 py_funcname
= PyString_FromString(funcname
);
160 py_srcfile
= PyString_FromString(srcfile
);
162 py_funcname
= PyUnicode_FromString(funcname
);
163 py_srcfile
= PyUnicode_FromString(srcfile
);
165 if (!py_funcname
| !py_srcfile
) goto bad
;
167 py_code
= PyCode_New(
169 #if PY_MAJOR_VERSION >= 3
170 0, /*int kwonlyargcount,*/
173 0, /*int stacksize,*/
175 $empty_bytes
, /*PyObject *code,*/
176 $empty_tuple
, /*PyObject *consts,*/
177 $empty_tuple
, /*PyObject *names,*/
178 $empty_tuple
, /*PyObject *varnames,*/
179 $empty_tuple
, /*PyObject *freevars,*/
180 $empty_tuple
, /*PyObject *cellvars,*/
181 py_srcfile
, /*PyObject *filename,*/
182 py_funcname
, /*PyObject *name,*/
183 firstlineno
, /*int firstlineno,*/
184 $empty_bytes
/*PyObject *lnotab*/
188 Py_XDECREF(py_srcfile
);
189 Py_XDECREF(py_funcname
);
194 #endif /* CYTHON_PROFILE */