Pracownia_programowania/venv/Lib/site-packages/Cython/Utility/Profile.c

336 lines
16 KiB
C
Raw Normal View History

2020-02-01 19:54:00 +01:00
/////////////// Profile.proto ///////////////
//@requires: Exceptions.c::PyErrFetchRestore
//@substitute: naming
// Note that cPython ignores PyTrace_EXCEPTION,
// but maybe some other profilers don't.
#ifndef CYTHON_PROFILE
#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_PYSTON
#define CYTHON_PROFILE 0
#else
#define CYTHON_PROFILE 1
#endif
#endif
#ifndef CYTHON_TRACE_NOGIL
#define CYTHON_TRACE_NOGIL 0
#else
#if CYTHON_TRACE_NOGIL && !defined(CYTHON_TRACE)
#define CYTHON_TRACE 1
#endif
#endif
#ifndef CYTHON_TRACE
#define CYTHON_TRACE 0
#endif
#if CYTHON_TRACE
#undef CYTHON_PROFILE_REUSE_FRAME
#endif
#ifndef CYTHON_PROFILE_REUSE_FRAME
#define CYTHON_PROFILE_REUSE_FRAME 0
#endif
#if CYTHON_PROFILE || CYTHON_TRACE
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
#if CYTHON_PROFILE_REUSE_FRAME
#define CYTHON_FRAME_MODIFIER static
#define CYTHON_FRAME_DEL(frame)
#else
#define CYTHON_FRAME_MODIFIER
#define CYTHON_FRAME_DEL(frame) Py_CLEAR(frame)
#endif
#define __Pyx_TraceDeclarations \
static PyCodeObject *$frame_code_cname = NULL; \
CYTHON_FRAME_MODIFIER PyFrameObject *$frame_cname = NULL; \
int __Pyx_use_tracing = 0;
#define __Pyx_TraceFrameInit(codeobj) \
if (codeobj) $frame_code_cname = (PyCodeObject*) codeobj;
#ifdef WITH_THREAD
#define __Pyx_TraceCall(funcname, srcfile, firstlineno, nogil, goto_error) \
if (nogil) { \
if (CYTHON_TRACE_NOGIL) { \
PyThreadState *tstate; \
PyGILState_STATE state = PyGILState_Ensure(); \
tstate = __Pyx_PyThreadState_Current; \
if (unlikely(tstate->use_tracing) && !tstate->tracing && \
(tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \
__Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, tstate, funcname, srcfile, firstlineno); \
} \
PyGILState_Release(state); \
if (unlikely(__Pyx_use_tracing < 0)) goto_error; \
} \
} else { \
PyThreadState* tstate = PyThreadState_GET(); \
if (unlikely(tstate->use_tracing) && !tstate->tracing && \
(tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \
__Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, tstate, funcname, srcfile, firstlineno); \
if (unlikely(__Pyx_use_tracing < 0)) goto_error; \
} \
}
#else
#define __Pyx_TraceCall(funcname, srcfile, firstlineno, nogil, goto_error) \
{ PyThreadState* tstate = PyThreadState_GET(); \
if (unlikely(tstate->use_tracing) && !tstate->tracing && \
(tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \
__Pyx_use_tracing = __Pyx_TraceSetupAndCall(&$frame_code_cname, &$frame_cname, tstate, funcname, srcfile, firstlineno); \
if (unlikely(__Pyx_use_tracing < 0)) goto_error; \
} \
}
#endif
#define __Pyx_TraceException() \
if (likely(!__Pyx_use_tracing)); else { \
PyThreadState* tstate = __Pyx_PyThreadState_Current; \
if (tstate->use_tracing && \
(tstate->c_profilefunc || (CYTHON_TRACE && tstate->c_tracefunc))) { \
tstate->tracing++; \
tstate->use_tracing = 0; \
PyObject *exc_info = __Pyx_GetExceptionTuple(tstate); \
if (exc_info) { \
if (CYTHON_TRACE && tstate->c_tracefunc) \
tstate->c_tracefunc( \
tstate->c_traceobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \
tstate->c_profilefunc( \
tstate->c_profileobj, $frame_cname, PyTrace_EXCEPTION, exc_info); \
Py_DECREF(exc_info); \
} \
tstate->use_tracing = 1; \
tstate->tracing--; \
} \
}
static void __Pyx_call_return_trace_func(PyThreadState *tstate, PyFrameObject *frame, PyObject *result) {
PyObject *type, *value, *traceback;
__Pyx_ErrFetchInState(tstate, &type, &value, &traceback);
tstate->tracing++;
tstate->use_tracing = 0;
if (CYTHON_TRACE && tstate->c_tracefunc)
tstate->c_tracefunc(tstate->c_traceobj, frame, PyTrace_RETURN, result);
if (tstate->c_profilefunc)
tstate->c_profilefunc(tstate->c_profileobj, frame, PyTrace_RETURN, result);
CYTHON_FRAME_DEL(frame);
tstate->use_tracing = 1;
tstate->tracing--;
__Pyx_ErrRestoreInState(tstate, type, value, traceback);
}
#ifdef WITH_THREAD
#define __Pyx_TraceReturn(result, nogil) \
if (likely(!__Pyx_use_tracing)); else { \
if (nogil) { \
if (CYTHON_TRACE_NOGIL) { \
PyThreadState *tstate; \
PyGILState_STATE state = PyGILState_Ensure(); \
tstate = __Pyx_PyThreadState_Current; \
if (tstate->use_tracing) { \
__Pyx_call_return_trace_func(tstate, $frame_cname, (PyObject*)result); \
} \
PyGILState_Release(state); \
} \
} else { \
PyThreadState* tstate = __Pyx_PyThreadState_Current; \
if (tstate->use_tracing) { \
__Pyx_call_return_trace_func(tstate, $frame_cname, (PyObject*)result); \
} \
} \
}
#else
#define __Pyx_TraceReturn(result, nogil) \
if (likely(!__Pyx_use_tracing)); else { \
PyThreadState* tstate = __Pyx_PyThreadState_Current; \
if (tstate->use_tracing) { \
__Pyx_call_return_trace_func(tstate, $frame_cname, (PyObject*)result); \
} \
}
#endif
static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, PyThreadState* tstate, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
#else
#define __Pyx_TraceDeclarations
#define __Pyx_TraceFrameInit(codeobj)
// mark error label as used to avoid compiler warnings
#define __Pyx_TraceCall(funcname, srcfile, firstlineno, nogil, goto_error) if ((1)); else goto_error;
#define __Pyx_TraceException()
#define __Pyx_TraceReturn(result, nogil)
#endif /* CYTHON_PROFILE */
#if CYTHON_TRACE
// see call_trace_protected() in CPython's ceval.c
static int __Pyx_call_line_trace_func(PyThreadState *tstate, PyFrameObject *frame, int lineno) {
int ret;
PyObject *type, *value, *traceback;
__Pyx_ErrFetchInState(tstate, &type, &value, &traceback);
__Pyx_PyFrame_SetLineNumber(frame, lineno);
tstate->tracing++;
tstate->use_tracing = 0;
ret = tstate->c_tracefunc(tstate->c_traceobj, frame, PyTrace_LINE, NULL);
tstate->use_tracing = 1;
tstate->tracing--;
if (likely(!ret)) {
__Pyx_ErrRestoreInState(tstate, type, value, traceback);
} else {
Py_XDECREF(type);
Py_XDECREF(value);
Py_XDECREF(traceback);
}
return ret;
}
#ifdef WITH_THREAD
#define __Pyx_TraceLine(lineno, nogil, goto_error) \
if (likely(!__Pyx_use_tracing)); else { \
if (nogil) { \
if (CYTHON_TRACE_NOGIL) { \
int ret = 0; \
PyThreadState *tstate; \
PyGILState_STATE state = PyGILState_Ensure(); \
tstate = __Pyx_PyThreadState_Current; \
if (unlikely(tstate->use_tracing && tstate->c_tracefunc && $frame_cname->f_trace)) { \
ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \
} \
PyGILState_Release(state); \
if (unlikely(ret)) goto_error; \
} \
} else { \
PyThreadState* tstate = __Pyx_PyThreadState_Current; \
if (unlikely(tstate->use_tracing && tstate->c_tracefunc && $frame_cname->f_trace)) { \
int ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \
if (unlikely(ret)) goto_error; \
} \
} \
}
#else
#define __Pyx_TraceLine(lineno, nogil, goto_error) \
if (likely(!__Pyx_use_tracing)); else { \
PyThreadState* tstate = __Pyx_PyThreadState_Current; \
if (unlikely(tstate->use_tracing && tstate->c_tracefunc && $frame_cname->f_trace)) { \
int ret = __Pyx_call_line_trace_func(tstate, $frame_cname, lineno); \
if (unlikely(ret)) goto_error; \
} \
}
#endif
#else
// mark error label as used to avoid compiler warnings
#define __Pyx_TraceLine(lineno, nogil, goto_error) if ((1)); else goto_error;
#endif
/////////////// Profile ///////////////
//@substitute: naming
#if CYTHON_PROFILE
static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
PyFrameObject** frame,
PyThreadState* tstate,
const char *funcname,
const char *srcfile,
int firstlineno) {
PyObject *type, *value, *traceback;
int retval;
if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
if (*code == NULL) {
*code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
if (*code == NULL) return 0;
}
*frame = PyFrame_New(
tstate, /*PyThreadState *tstate*/
*code, /*PyCodeObject *code*/
$moddict_cname, /*PyObject *globals*/
0 /*PyObject *locals*/
);
if (*frame == NULL) return 0;
if (CYTHON_TRACE && (*frame)->f_trace == NULL) {
// this enables "f_lineno" lookup, at least in CPython ...
Py_INCREF(Py_None);
(*frame)->f_trace = Py_None;
}
#if PY_VERSION_HEX < 0x030400B1
} else {
(*frame)->f_tstate = tstate;
#endif
}
__Pyx_PyFrame_SetLineNumber(*frame, firstlineno);
retval = 1;
tstate->tracing++;
tstate->use_tracing = 0;
__Pyx_ErrFetchInState(tstate, &type, &value, &traceback);
#if CYTHON_TRACE
if (tstate->c_tracefunc)
retval = tstate->c_tracefunc(tstate->c_traceobj, *frame, PyTrace_CALL, NULL) == 0;
if (retval && tstate->c_profilefunc)
#endif
retval = tstate->c_profilefunc(tstate->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
tstate->use_tracing = (tstate->c_profilefunc ||
(CYTHON_TRACE && tstate->c_tracefunc));
tstate->tracing--;
if (retval) {
__Pyx_ErrRestoreInState(tstate, type, value, traceback);
return tstate->use_tracing && retval;
} else {
Py_XDECREF(type);
Py_XDECREF(value);
Py_XDECREF(traceback);
return -1;
}
}
static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
PyCodeObject *py_code = 0;
#if PY_MAJOR_VERSION >= 3
py_code = PyCode_NewEmpty(srcfile, funcname, firstlineno);
// make CPython use a fresh dict for "f_locals" at need (see GH #1836)
if (likely(py_code)) {
py_code->co_flags |= CO_OPTIMIZED | CO_NEWLOCALS;
}
#else
PyObject *py_srcfile = 0;
PyObject *py_funcname = 0;
py_funcname = PyString_FromString(funcname);
if (unlikely(!py_funcname)) goto bad;
py_srcfile = PyString_FromString(srcfile);
if (unlikely(!py_srcfile)) goto bad;
py_code = PyCode_New(
0, /*int argcount,*/
0, /*int nlocals,*/
0, /*int stacksize,*/
// make CPython use a fresh dict for "f_locals" at need (see GH #1836)
CO_OPTIMIZED | CO_NEWLOCALS, /*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);
#endif
return py_code;
}
#endif /* CYTHON_PROFILE */