OLD | NEW |
(Empty) | |
| 1 /////////////// Profile.proto /////////////// |
| 2 //@substitute: naming |
| 3 |
| 4 // Note that cPython ignores PyTrace_EXCEPTION, |
| 5 // but maybe some other profilers don't. |
| 6 |
| 7 #ifndef CYTHON_PROFILE |
| 8 #define CYTHON_PROFILE 1 |
| 9 #endif |
| 10 |
| 11 #ifndef CYTHON_TRACE |
| 12 #define CYTHON_TRACE 0 |
| 13 #endif |
| 14 |
| 15 #if CYTHON_TRACE |
| 16 #undef CYTHON_PROFILE_REUSE_FRAME |
| 17 #endif |
| 18 |
| 19 #ifndef CYTHON_PROFILE_REUSE_FRAME |
| 20 #define CYTHON_PROFILE_REUSE_FRAME 0 |
| 21 #endif |
| 22 |
| 23 #if CYTHON_PROFILE || CYTHON_TRACE |
| 24 |
| 25 #include "compile.h" |
| 26 #include "frameobject.h" |
| 27 #include "traceback.h" |
| 28 |
| 29 #if CYTHON_PROFILE_REUSE_FRAME |
| 30 #define CYTHON_FRAME_MODIFIER static |
| 31 #define CYTHON_FRAME_DEL |
| 32 #else |
| 33 #define CYTHON_FRAME_MODIFIER |
| 34 #define CYTHON_FRAME_DEL Py_CLEAR($frame_cname) |
| 35 #endif |
| 36 |
| 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; |
| 41 |
| 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_cn
ame, funcname, srcfile, firstlineno); \ |
| 46 } |
| 47 |
| 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();
\ |
| 54 if (exc_info) {
\ |
| 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);
\ |
| 61 }
\ |
| 62 tstate->use_tracing = 1;
\ |
| 63 } |
| 64 |
| 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*)resul
t); \ |
| 72 if (tstate->c_profilefunc)
\ |
| 73 tstate->c_profilefunc(
\ |
| 74 tstate->c_profileobj, $frame_cname, PyTrace_RETURN, (PyObject*)res
ult); \ |
| 75 CYTHON_FRAME_DEL;
\ |
| 76 tstate->use_tracing = 1;
\ |
| 77 } |
| 78 |
| 79 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const c
har *srcfile, int firstlineno); /*proto*/ |
| 80 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame,
const char *funcname, const char *srcfile, int firstlineno); /*proto*/ |
| 81 |
| 82 #else |
| 83 |
| 84 #define __Pyx_TraceDeclarations |
| 85 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) |
| 86 #define __Pyx_TraceException() |
| 87 #define __Pyx_TraceReturn(result) |
| 88 |
| 89 #endif /* CYTHON_PROFILE */ |
| 90 |
| 91 #if CYTHON_TRACE |
| 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;
\ |
| 99 } |
| 100 #else |
| 101 #define __Pyx_TraceLine(lineno) |
| 102 #endif |
| 103 |
| 104 /////////////// Profile /////////////// |
| 105 //@substitute: naming |
| 106 |
| 107 #if CYTHON_PROFILE |
| 108 |
| 109 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, |
| 110 PyFrameObject** frame, |
| 111 const char *funcname, |
| 112 const char *srcfile, |
| 113 int firstlineno) { |
| 114 int retval; |
| 115 PyThreadState* tstate = PyThreadState_GET(); |
| 116 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) { |
| 117 if (*code == NULL) { |
| 118 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno); |
| 119 if (*code == NULL) return 0; |
| 120 } |
| 121 *frame = PyFrame_New( |
| 122 tstate, /*PyThreadState *tstate*/ |
| 123 *code, /*PyCodeObject *code*/ |
| 124 $moddict_cname, /*PyObject *globals*/ |
| 125 0 /*PyObject *locals*/ |
| 126 ); |
| 127 if (*frame == NULL) return 0; |
| 128 if (CYTHON_TRACE && (*frame)->f_trace == NULL) { |
| 129 // this enables "f_lineno" lookup, at least in CPython ... |
| 130 Py_INCREF(Py_None); |
| 131 (*frame)->f_trace = Py_None; |
| 132 } |
| 133 #if PY_VERSION_HEX < 0x030400B1 |
| 134 } else { |
| 135 (*frame)->f_tstate = tstate; |
| 136 #endif |
| 137 } |
| 138 (*frame)->f_lineno = firstlineno; |
| 139 tstate->use_tracing = 0; |
| 140 #if CYTHON_TRACE |
| 141 if (tstate->c_tracefunc) |
| 142 tstate->c_tracefunc(tstate->c_traceobj, *frame, PyTrace_CALL, NULL); |
| 143 if (!tstate->c_profilefunc) |
| 144 retval = 1; |
| 145 else |
| 146 #endif |
| 147 retval = tstate->c_profilefunc(tstate->c_profileobj, *frame, PyTrace_CAL
L, NULL) == 0; |
| 148 tstate->use_tracing = (tstate->c_profilefunc || |
| 149 (CYTHON_TRACE && tstate->c_tracefunc)); |
| 150 return tstate->use_tracing && retval; |
| 151 } |
| 152 |
| 153 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const cha
r *srcfile, int firstlineno) { |
| 154 PyObject *py_srcfile = 0; |
| 155 PyObject *py_funcname = 0; |
| 156 PyCodeObject *py_code = 0; |
| 157 |
| 158 #if PY_MAJOR_VERSION < 3 |
| 159 py_funcname = PyString_FromString(funcname); |
| 160 py_srcfile = PyString_FromString(srcfile); |
| 161 #else |
| 162 py_funcname = PyUnicode_FromString(funcname); |
| 163 py_srcfile = PyUnicode_FromString(srcfile); |
| 164 #endif |
| 165 if (!py_funcname | !py_srcfile) goto bad; |
| 166 |
| 167 py_code = PyCode_New( |
| 168 0, /*int argcount,*/ |
| 169 #if PY_MAJOR_VERSION >= 3 |
| 170 0, /*int kwonlyargcount,*/ |
| 171 #endif |
| 172 0, /*int nlocals,*/ |
| 173 0, /*int stacksize,*/ |
| 174 0, /*int flags,*/ |
| 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*/ |
| 185 ); |
| 186 |
| 187 bad: |
| 188 Py_XDECREF(py_srcfile); |
| 189 Py_XDECREF(py_funcname); |
| 190 |
| 191 return py_code; |
| 192 } |
| 193 |
| 194 #endif /* CYTHON_PROFILE */ |
OLD | NEW |