gh-126220: Adapt _lsprof to Argument Clinic (#126233)

Co-authored-by: Erlend E. Aasland <erlend.aasland@protonmail.com>
This commit is contained in:
sobolevn 2024-11-04 19:18:21 +03:00 committed by GitHub
parent 3032fcd90e
commit c806cd5af6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 518 additions and 118 deletions

View file

@ -1231,6 +1231,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict_mode)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict_mode));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(string)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(string));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sub_key)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sub_key));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(subcalls));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(symmetric_difference_update)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(symmetric_difference_update));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tabsize)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tabsize));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tag)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tag));
@ -1248,8 +1249,10 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeout)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeout));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timer));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(times)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(times));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeunit));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trace_callback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trace_callback));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback));

View file

@ -720,6 +720,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(strict_mode) STRUCT_FOR_ID(strict_mode)
STRUCT_FOR_ID(string) STRUCT_FOR_ID(string)
STRUCT_FOR_ID(sub_key) STRUCT_FOR_ID(sub_key)
STRUCT_FOR_ID(subcalls)
STRUCT_FOR_ID(symmetric_difference_update) STRUCT_FOR_ID(symmetric_difference_update)
STRUCT_FOR_ID(tabsize) STRUCT_FOR_ID(tabsize)
STRUCT_FOR_ID(tag) STRUCT_FOR_ID(tag)
@ -737,8 +738,10 @@ struct _Py_global_strings {
STRUCT_FOR_ID(threading) STRUCT_FOR_ID(threading)
STRUCT_FOR_ID(throw) STRUCT_FOR_ID(throw)
STRUCT_FOR_ID(timeout) STRUCT_FOR_ID(timeout)
STRUCT_FOR_ID(timer)
STRUCT_FOR_ID(times) STRUCT_FOR_ID(times)
STRUCT_FOR_ID(timetuple) STRUCT_FOR_ID(timetuple)
STRUCT_FOR_ID(timeunit)
STRUCT_FOR_ID(top) STRUCT_FOR_ID(top)
STRUCT_FOR_ID(trace_callback) STRUCT_FOR_ID(trace_callback)
STRUCT_FOR_ID(traceback) STRUCT_FOR_ID(traceback)

View file

@ -1229,6 +1229,7 @@ extern "C" {
INIT_ID(strict_mode), \ INIT_ID(strict_mode), \
INIT_ID(string), \ INIT_ID(string), \
INIT_ID(sub_key), \ INIT_ID(sub_key), \
INIT_ID(subcalls), \
INIT_ID(symmetric_difference_update), \ INIT_ID(symmetric_difference_update), \
INIT_ID(tabsize), \ INIT_ID(tabsize), \
INIT_ID(tag), \ INIT_ID(tag), \
@ -1246,8 +1247,10 @@ extern "C" {
INIT_ID(threading), \ INIT_ID(threading), \
INIT_ID(throw), \ INIT_ID(throw), \
INIT_ID(timeout), \ INIT_ID(timeout), \
INIT_ID(timer), \
INIT_ID(times), \ INIT_ID(times), \
INIT_ID(timetuple), \ INIT_ID(timetuple), \
INIT_ID(timeunit), \
INIT_ID(top), \ INIT_ID(top), \
INIT_ID(trace_callback), \ INIT_ID(trace_callback), \
INIT_ID(traceback), \ INIT_ID(traceback), \

View file

@ -2676,6 +2676,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string); _PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1)); assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1); assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(subcalls);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(symmetric_difference_update); string = &_Py_ID(symmetric_difference_update);
_PyUnicode_InternStatic(interp, &string); _PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1)); assert(_PyUnicode_CheckConsistency(string, 1));
@ -2744,6 +2748,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string); _PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1)); assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1); assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(timer);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(times); string = &_Py_ID(times);
_PyUnicode_InternStatic(interp, &string); _PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1)); assert(_PyUnicode_CheckConsistency(string, 1));
@ -2752,6 +2760,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
_PyUnicode_InternStatic(interp, &string); _PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1)); assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1); assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(timeunit);
_PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1));
assert(PyUnicode_GET_LENGTH(string) != 1);
string = &_Py_ID(top); string = &_Py_ID(top);
_PyUnicode_InternStatic(interp, &string); _PyUnicode_InternStatic(interp, &string);
assert(_PyUnicode_CheckConsistency(string, 1)); assert(_PyUnicode_CheckConsistency(string, 1));

View file

@ -606,29 +606,42 @@ setBuiltins(ProfilerObject *pObj, int nvalue)
return 0; return 0;
} }
PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) /*[clinic input]
_lsprof.Profiler._pystart_callback
code: object
instruction_offset: object
/
[clinic start generated code]*/
static PyObject *
_lsprof_Profiler__pystart_callback_impl(ProfilerObject *self, PyObject *code,
PyObject *instruction_offset)
/*[clinic end generated code: output=5fec8b7ad5ed25e8 input=b166e6953c579cda]*/
{ {
if (size < 2) { ptrace_enter_call((PyObject*)self, (void *)code, code);
PyErr_Format(PyExc_TypeError,
"_pystart_callback expected 2 arguments, got %zd",
size);
return NULL;
}
PyObject* code = args[0];
ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) /*[clinic input]
_lsprof.Profiler._pyreturn_callback
code: object
instruction_offset: object
retval: object
/
[clinic start generated code]*/
static PyObject *
_lsprof_Profiler__pyreturn_callback_impl(ProfilerObject *self,
PyObject *code,
PyObject *instruction_offset,
PyObject *retval)
/*[clinic end generated code: output=9e2f6fc1b882c51e input=667ffaeb2fa6fd1f]*/
{ {
if (size < 3) {
PyErr_Format(PyExc_TypeError,
"_pyreturn_callback expected 3 arguments, got %zd",
size);
return NULL;
}
PyObject* code = args[0];
ptrace_leave_call((PyObject*)self, (void *)code); ptrace_leave_call((PyObject*)self, (void *)code);
Py_RETURN_NONE; Py_RETURN_NONE;
@ -661,18 +674,24 @@ PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObje
return NULL; return NULL;
} }
PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) /*[clinic input]
{ _lsprof.Profiler._ccall_callback
if (size < 4) {
PyErr_Format(PyExc_TypeError,
"_ccall_callback expected 4 arguments, got %zd",
size);
return NULL;
}
if (self->flags & POF_BUILTINS) {
PyObject* callable = args[2];
PyObject* self_arg = args[3];
code: object
instruction_offset: object
callable: object
self_arg: object
/
[clinic start generated code]*/
static PyObject *
_lsprof_Profiler__ccall_callback_impl(ProfilerObject *self, PyObject *code,
PyObject *instruction_offset,
PyObject *callable, PyObject *self_arg)
/*[clinic end generated code: output=152db83cabd18cad input=0e66687cfb95c001]*/
{
if (self->flags & POF_BUILTINS) {
PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing);
if (cfunc) { if (cfunc) {
@ -685,18 +704,25 @@ PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t
Py_RETURN_NONE; Py_RETURN_NONE;
} }
PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) /*[clinic input]
{ _lsprof.Profiler._creturn_callback
if (size < 4) {
PyErr_Format(PyExc_TypeError,
"_creturn_callback expected 4 arguments, got %zd",
size);
return NULL;
}
if (self->flags & POF_BUILTINS) {
PyObject* callable = args[2];
PyObject* self_arg = args[3];
code: object
instruction_offset: object
callable: object
self_arg: object
/
[clinic start generated code]*/
static PyObject *
_lsprof_Profiler__creturn_callback_impl(ProfilerObject *self, PyObject *code,
PyObject *instruction_offset,
PyObject *callable,
PyObject *self_arg)
/*[clinic end generated code: output=1e886dde8fed8fb0 input=b18afe023746923a]*/
{
if (self->flags & POF_BUILTINS) {
PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing);
if (cfunc) { if (cfunc) {
@ -724,27 +750,27 @@ static const struct {
{0, NULL} {0, NULL}
}; };
PyDoc_STRVAR(enable_doc, "\
enable(subcalls=True, builtins=True)\n\ /*[clinic input]
\n\ _lsprof.Profiler.enable
Start collecting profiling information.\n\
If 'subcalls' is True, also records for each function\n\ subcalls: bool = True
statistics separated according to its current caller.\n\ If True, also records for each function
If 'builtins' is True, records the time spent in\n\ statistics separated according to its current caller.
built-in functions separately from their caller.\n\
"); builtins: bool = True
If True, records the time spent in
built-in functions separately from their caller.
Start collecting profiling information.
[clinic start generated code]*/
static PyObject * static PyObject *
profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) _lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls,
int builtins)
/*[clinic end generated code: output=1e747f9dc1edd571 input=9ab81405107ab7f1]*/
{ {
int subcalls = -1;
int builtins = -1;
static char *kwlist[] = {"subcalls", "builtins", 0};
int all_events = 0; int all_events = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pp:enable",
kwlist, &subcalls, &builtins))
return NULL;
if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) {
return NULL; return NULL;
} }
@ -800,14 +826,16 @@ flush_unmatched(ProfilerObject *pObj)
} }
PyDoc_STRVAR(disable_doc, "\
disable()\n\ /*[clinic input]
\n\ _lsprof.Profiler.disable
Stop collecting profiling information.\n\
"); Stop collecting profiling information.
[clinic start generated code]*/
static PyObject * static PyObject *
profiler_disable(ProfilerObject *self, PyObject* noarg) _lsprof_Profiler_disable_impl(ProfilerObject *self)
/*[clinic end generated code: output=838cffef7f651870 input=05700b3fc68d1f50]*/
{ {
if (self->flags & POF_EXT_TIMER) { if (self->flags & POF_EXT_TIMER) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
@ -858,21 +886,22 @@ profiler_disable(ProfilerObject *self, PyObject* noarg)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
PyDoc_STRVAR(clear_doc, "\ /*[clinic input]
clear()\n\ _lsprof.Profiler.clear
\n\
Clear all profiling information collected so far.\n\ Clear all profiling information collected so far.
"); [clinic start generated code]*/
static PyObject * static PyObject *
profiler_clear(ProfilerObject *pObj, PyObject* noarg) _lsprof_Profiler_clear_impl(ProfilerObject *self)
/*[clinic end generated code: output=dd1c668fb84b1335 input=fbe1f88c28be4f98]*/
{ {
if (pObj->flags & POF_EXT_TIMER) { if (self->flags & POF_EXT_TIMER) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"cannot clear profiler in external timer"); "cannot clear profiler in external timer");
return NULL; return NULL;
} }
clearEntries(pObj); clearEntries(self);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -903,33 +932,40 @@ profiler_dealloc(ProfilerObject *op)
Py_DECREF(tp); Py_DECREF(tp);
} }
/*[clinic input]
_lsprof.Profiler.__init__ as profiler_init
timer: object(c_default='NULL') = None
timeunit: double = 0.0
subcalls: bool = True
builtins: bool = True
Build a profiler object using the specified timer function.
The default timer is a fast built-in one based on real time.
For custom timer functions returning integers, 'timeunit' can
be a float specifying a scale (that is, how long each integer unit
is, in seconds).
[clinic start generated code]*/
static int static int
profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit,
int subcalls, int builtins)
/*[clinic end generated code: output=ac523803ec9f9df2 input=8285ca746f96a414]*/
{ {
PyObject *timer = NULL; if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) {
double timeunit = 0.0;
int subcalls = 1;
int builtins = 1;
static char *kwlist[] = {"timer", "timeunit",
"subcalls", "builtins", 0};
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odpp:Profiler", kwlist,
&timer, &timeunit,
&subcalls, &builtins))
return -1; return -1;
}
if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) self->externalTimerUnit = timeunit;
return -1; Py_XSETREF(self->externalTimer, Py_XNewRef(timer));
pObj->externalTimerUnit = timeunit; self->tool_id = PY_MONITORING_PROFILER_ID;
Py_XSETREF(pObj->externalTimer, Py_XNewRef(timer));
pObj->tool_id = PY_MONITORING_PROFILER_ID;
PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring");
if (!monitoring) { if (!monitoring) {
return -1; return -1;
} }
pObj->missing = PyObject_GetAttrString(monitoring, "MISSING"); self->missing = PyObject_GetAttrString(monitoring, "MISSING");
if (!pObj->missing) { if (!self->missing) {
Py_DECREF(monitoring); Py_DECREF(monitoring);
return -1; return -1;
} }
@ -939,35 +975,18 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw)
static PyMethodDef profiler_methods[] = { static PyMethodDef profiler_methods[] = {
_LSPROF_PROFILER_GETSTATS_METHODDEF _LSPROF_PROFILER_GETSTATS_METHODDEF
{"enable", _PyCFunction_CAST(profiler_enable), _LSPROF_PROFILER_ENABLE_METHODDEF
METH_VARARGS | METH_KEYWORDS, enable_doc}, _LSPROF_PROFILER_DISABLE_METHODDEF
{"disable", (PyCFunction)profiler_disable, _LSPROF_PROFILER_CLEAR_METHODDEF
METH_NOARGS, disable_doc}, _LSPROF_PROFILER__PYSTART_CALLBACK_METHODDEF
{"clear", (PyCFunction)profiler_clear, _LSPROF_PROFILER__PYRETURN_CALLBACK_METHODDEF
METH_NOARGS, clear_doc}, _LSPROF_PROFILER__CCALL_CALLBACK_METHODDEF
{"_pystart_callback", _PyCFunction_CAST(pystart_callback), _LSPROF_PROFILER__CRETURN_CALLBACK_METHODDEF
METH_FASTCALL, NULL},
{"_pyreturn_callback", _PyCFunction_CAST(pyreturn_callback),
METH_FASTCALL, NULL},
{"_ccall_callback", _PyCFunction_CAST(ccall_callback),
METH_FASTCALL, NULL},
{"_creturn_callback", _PyCFunction_CAST(creturn_callback),
METH_FASTCALL, NULL},
{NULL, NULL} {NULL, NULL}
}; };
PyDoc_STRVAR(profiler_doc, "\
Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\
\n\
Builds a profiler object using the specified timer function.\n\
The default timer is a fast built-in one based on real time.\n\
For custom timer functions returning integers, timeunit can\n\
be a float specifying a scale (i.e. how long each integer unit\n\
is, in seconds).\n\
");
static PyType_Slot _lsprof_profiler_type_spec_slots[] = { static PyType_Slot _lsprof_profiler_type_spec_slots[] = {
{Py_tp_doc, (void *)profiler_doc}, {Py_tp_doc, (void *)profiler_init__doc__},
{Py_tp_methods, profiler_methods}, {Py_tp_methods, profiler_methods},
{Py_tp_dealloc, profiler_dealloc}, {Py_tp_dealloc, profiler_dealloc},
{Py_tp_init, profiler_init}, {Py_tp_init, profiler_init},

View file

@ -2,6 +2,12 @@
preserve preserve
[clinic start generated code]*/ [clinic start generated code]*/
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
# include "pycore_gc.h" // PyGC_Head
# include "pycore_runtime.h" // _Py_ID()
#endif
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__,
"getstats($self, /)\n" "getstats($self, /)\n"
"--\n" "--\n"
@ -45,4 +51,358 @@ _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *con
} }
return _lsprof_Profiler_getstats_impl(self, cls); return _lsprof_Profiler_getstats_impl(self, cls);
} }
/*[clinic end generated code: output=5c9d87d89863dc83 input=a9049054013a1b77]*/
PyDoc_STRVAR(_lsprof_Profiler__pystart_callback__doc__,
"_pystart_callback($self, code, instruction_offset, /)\n"
"--\n"
"\n");
#define _LSPROF_PROFILER__PYSTART_CALLBACK_METHODDEF \
{"_pystart_callback", _PyCFunction_CAST(_lsprof_Profiler__pystart_callback), METH_FASTCALL, _lsprof_Profiler__pystart_callback__doc__},
static PyObject *
_lsprof_Profiler__pystart_callback_impl(ProfilerObject *self, PyObject *code,
PyObject *instruction_offset);
static PyObject *
_lsprof_Profiler__pystart_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *code;
PyObject *instruction_offset;
if (!_PyArg_CheckPositional("_pystart_callback", nargs, 2, 2)) {
goto exit;
}
code = args[0];
instruction_offset = args[1];
return_value = _lsprof_Profiler__pystart_callback_impl(self, code, instruction_offset);
exit:
return return_value;
}
PyDoc_STRVAR(_lsprof_Profiler__pyreturn_callback__doc__,
"_pyreturn_callback($self, code, instruction_offset, retval, /)\n"
"--\n"
"\n");
#define _LSPROF_PROFILER__PYRETURN_CALLBACK_METHODDEF \
{"_pyreturn_callback", _PyCFunction_CAST(_lsprof_Profiler__pyreturn_callback), METH_FASTCALL, _lsprof_Profiler__pyreturn_callback__doc__},
static PyObject *
_lsprof_Profiler__pyreturn_callback_impl(ProfilerObject *self,
PyObject *code,
PyObject *instruction_offset,
PyObject *retval);
static PyObject *
_lsprof_Profiler__pyreturn_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *code;
PyObject *instruction_offset;
PyObject *retval;
if (!_PyArg_CheckPositional("_pyreturn_callback", nargs, 3, 3)) {
goto exit;
}
code = args[0];
instruction_offset = args[1];
retval = args[2];
return_value = _lsprof_Profiler__pyreturn_callback_impl(self, code, instruction_offset, retval);
exit:
return return_value;
}
PyDoc_STRVAR(_lsprof_Profiler__ccall_callback__doc__,
"_ccall_callback($self, code, instruction_offset, callable, self_arg, /)\n"
"--\n"
"\n");
#define _LSPROF_PROFILER__CCALL_CALLBACK_METHODDEF \
{"_ccall_callback", _PyCFunction_CAST(_lsprof_Profiler__ccall_callback), METH_FASTCALL, _lsprof_Profiler__ccall_callback__doc__},
static PyObject *
_lsprof_Profiler__ccall_callback_impl(ProfilerObject *self, PyObject *code,
PyObject *instruction_offset,
PyObject *callable, PyObject *self_arg);
static PyObject *
_lsprof_Profiler__ccall_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *code;
PyObject *instruction_offset;
PyObject *callable;
PyObject *self_arg;
if (!_PyArg_CheckPositional("_ccall_callback", nargs, 4, 4)) {
goto exit;
}
code = args[0];
instruction_offset = args[1];
callable = args[2];
self_arg = args[3];
return_value = _lsprof_Profiler__ccall_callback_impl(self, code, instruction_offset, callable, self_arg);
exit:
return return_value;
}
PyDoc_STRVAR(_lsprof_Profiler__creturn_callback__doc__,
"_creturn_callback($self, code, instruction_offset, callable, self_arg,\n"
" /)\n"
"--\n"
"\n");
#define _LSPROF_PROFILER__CRETURN_CALLBACK_METHODDEF \
{"_creturn_callback", _PyCFunction_CAST(_lsprof_Profiler__creturn_callback), METH_FASTCALL, _lsprof_Profiler__creturn_callback__doc__},
static PyObject *
_lsprof_Profiler__creturn_callback_impl(ProfilerObject *self, PyObject *code,
PyObject *instruction_offset,
PyObject *callable,
PyObject *self_arg);
static PyObject *
_lsprof_Profiler__creturn_callback(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
PyObject *code;
PyObject *instruction_offset;
PyObject *callable;
PyObject *self_arg;
if (!_PyArg_CheckPositional("_creturn_callback", nargs, 4, 4)) {
goto exit;
}
code = args[0];
instruction_offset = args[1];
callable = args[2];
self_arg = args[3];
return_value = _lsprof_Profiler__creturn_callback_impl(self, code, instruction_offset, callable, self_arg);
exit:
return return_value;
}
PyDoc_STRVAR(_lsprof_Profiler_enable__doc__,
"enable($self, /, subcalls=True, builtins=True)\n"
"--\n"
"\n"
"Start collecting profiling information.\n"
"\n"
" subcalls\n"
" If True, also records for each function\n"
" statistics separated according to its current caller.\n"
" builtins\n"
" If True, records the time spent in\n"
" built-in functions separately from their caller.");
#define _LSPROF_PROFILER_ENABLE_METHODDEF \
{"enable", _PyCFunction_CAST(_lsprof_Profiler_enable), METH_FASTCALL|METH_KEYWORDS, _lsprof_Profiler_enable__doc__},
static PyObject *
_lsprof_Profiler_enable_impl(ProfilerObject *self, int subcalls,
int builtins);
static PyObject *
_lsprof_Profiler_enable(ProfilerObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 2
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_item = { &_Py_ID(subcalls), &_Py_ID(builtins), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
static const char * const _keywords[] = {"subcalls", "builtins", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "enable",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
int subcalls = 1;
int builtins = 1;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 2, 0, argsbuf);
if (!args) {
goto exit;
}
if (!noptargs) {
goto skip_optional_pos;
}
if (args[0]) {
subcalls = PyObject_IsTrue(args[0]);
if (subcalls < 0) {
goto exit;
}
if (!--noptargs) {
goto skip_optional_pos;
}
}
builtins = PyObject_IsTrue(args[1]);
if (builtins < 0) {
goto exit;
}
skip_optional_pos:
return_value = _lsprof_Profiler_enable_impl(self, subcalls, builtins);
exit:
return return_value;
}
PyDoc_STRVAR(_lsprof_Profiler_disable__doc__,
"disable($self, /)\n"
"--\n"
"\n"
"Stop collecting profiling information.");
#define _LSPROF_PROFILER_DISABLE_METHODDEF \
{"disable", (PyCFunction)_lsprof_Profiler_disable, METH_NOARGS, _lsprof_Profiler_disable__doc__},
static PyObject *
_lsprof_Profiler_disable_impl(ProfilerObject *self);
static PyObject *
_lsprof_Profiler_disable(ProfilerObject *self, PyObject *Py_UNUSED(ignored))
{
return _lsprof_Profiler_disable_impl(self);
}
PyDoc_STRVAR(_lsprof_Profiler_clear__doc__,
"clear($self, /)\n"
"--\n"
"\n"
"Clear all profiling information collected so far.");
#define _LSPROF_PROFILER_CLEAR_METHODDEF \
{"clear", (PyCFunction)_lsprof_Profiler_clear, METH_NOARGS, _lsprof_Profiler_clear__doc__},
static PyObject *
_lsprof_Profiler_clear_impl(ProfilerObject *self);
static PyObject *
_lsprof_Profiler_clear(ProfilerObject *self, PyObject *Py_UNUSED(ignored))
{
return _lsprof_Profiler_clear_impl(self);
}
PyDoc_STRVAR(profiler_init__doc__,
"Profiler(timer=None, timeunit=0.0, subcalls=True, builtins=True)\n"
"--\n"
"\n"
"Build a profiler object using the specified timer function.\n"
"\n"
"The default timer is a fast built-in one based on real time.\n"
"For custom timer functions returning integers, \'timeunit\' can\n"
"be a float specifying a scale (that is, how long each integer unit\n"
"is, in seconds).");
static int
profiler_init_impl(ProfilerObject *self, PyObject *timer, double timeunit,
int subcalls, int builtins);
static int
profiler_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
int return_value = -1;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 4
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_item = { &_Py_ID(timer), &_Py_ID(timeunit), &_Py_ID(subcalls), &_Py_ID(builtins), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
static const char * const _keywords[] = {"timer", "timeunit", "subcalls", "builtins", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "Profiler",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[4];
PyObject * const *fastargs;
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0;
PyObject *timer = NULL;
double timeunit = 0.0;
int subcalls = 1;
int builtins = 1;
fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 4, 0, argsbuf);
if (!fastargs) {
goto exit;
}
if (!noptargs) {
goto skip_optional_pos;
}
if (fastargs[0]) {
timer = fastargs[0];
if (!--noptargs) {
goto skip_optional_pos;
}
}
if (fastargs[1]) {
if (PyFloat_CheckExact(fastargs[1])) {
timeunit = PyFloat_AS_DOUBLE(fastargs[1]);
}
else
{
timeunit = PyFloat_AsDouble(fastargs[1]);
if (timeunit == -1.0 && PyErr_Occurred()) {
goto exit;
}
}
if (!--noptargs) {
goto skip_optional_pos;
}
}
if (fastargs[2]) {
subcalls = PyObject_IsTrue(fastargs[2]);
if (subcalls < 0) {
goto exit;
}
if (!--noptargs) {
goto skip_optional_pos;
}
}
builtins = PyObject_IsTrue(fastargs[3]);
if (builtins < 0) {
goto exit;
}
skip_optional_pos:
return_value = profiler_init_impl((ProfilerObject *)self, timer, timeunit, subcalls, builtins);
exit:
return return_value;
}
/*[clinic end generated code: output=0b71f52bee9a7bb1 input=a9049054013a1b77]*/