summaryrefslogtreecommitdiffstats
path: root/Modules/_lsprof.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_lsprof.c')
-rw-r--r--Modules/_lsprof.c215
1 files changed, 121 insertions, 94 deletions
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c
index a4ba7d5..78d464d 100644
--- a/Modules/_lsprof.c
+++ b/Modules/_lsprof.c
@@ -55,12 +55,22 @@ module _lsprof
class _lsprof.Profiler "ProfilerObject *" "&ProfilerType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e349ac952152f336]*/
-static PyTypeObject PyProfiler_Type;
#include "clinic/_lsprof.c.h"
-#define PyProfiler_Check(op) PyObject_TypeCheck(op, &PyProfiler_Type)
-#define PyProfiler_CheckExact(op) Py_IS_TYPE(op, &PyProfiler_Type)
+typedef struct {
+ PyTypeObject *profiler_type;
+ PyTypeObject *stats_entry_type;
+ PyTypeObject *stats_subentry_type;
+} _lsprof_state;
+
+static inline _lsprof_state*
+_lsprof_get_state(PyObject *module)
+{
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (_lsprof_state *)state;
+}
/*** External Timers ***/
@@ -478,28 +488,24 @@ static PyStructSequence_Field profiler_subentry_fields[] = {
};
static PyStructSequence_Desc profiler_entry_desc = {
- "_lsprof.profiler_entry", /* name */
- NULL, /* doc */
- profiler_entry_fields,
- 6
+ .name = "_lsprof.profiler_entry",
+ .doc = "",
+ .fields = profiler_entry_fields,
+ .n_in_sequence = 6
};
static PyStructSequence_Desc profiler_subentry_desc = {
- "_lsprof.profiler_subentry", /* name */
- NULL, /* doc */
- profiler_subentry_fields,
- 5
+ .name = "_lsprof.profiler_subentry",
+ .doc = "",
+ .fields = profiler_subentry_fields,
+ .n_in_sequence = 5
};
-static int initialized;
-static PyTypeObject StatsEntryType;
-static PyTypeObject StatsSubEntryType;
-
-
typedef struct {
PyObject *list;
PyObject *sublist;
double factor;
+ _lsprof_state *state;
} statscollector_t;
static int statsForSubEntry(rotating_node_t *node, void *arg)
@@ -509,7 +515,7 @@ static int statsForSubEntry(rotating_node_t *node, void *arg)
ProfilerEntry *entry = (ProfilerEntry*) sentry->header.key;
int err;
PyObject *sinfo;
- sinfo = PyObject_CallFunction((PyObject*) &StatsSubEntryType,
+ sinfo = PyObject_CallFunction((PyObject*) collect->state->stats_subentry_type,
"((Olldd))",
entry->userObj,
sentry->callcount,
@@ -547,7 +553,7 @@ static int statsForEntry(rotating_node_t *node, void *arg)
collect->sublist = Py_None;
}
- info = PyObject_CallFunction((PyObject*) &StatsEntryType,
+ info = PyObject_CallFunction((PyObject*) collect->state->stats_entry_type,
"((OllddO))",
entry->userObj,
entry->callcount,
@@ -566,6 +572,8 @@ static int statsForEntry(rotating_node_t *node, void *arg)
/*[clinic input]
_lsprof.Profiler.getstats
+ cls: defining_class
+
list of profiler_entry objects.
getstats() -> list of profiler_entry objects
@@ -592,10 +600,11 @@ profiler_subentry objects:
[clinic start generated code]*/
static PyObject *
-_lsprof_Profiler_getstats_impl(ProfilerObject *self)
-/*[clinic end generated code: output=9461b451e9ef0f24 input=ade04fa384ce450a]*/
+_lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=1806ef720019ee03 input=445e193ef4522902]*/
{
statscollector_t collect;
+ collect.state = PyType_GetModuleState(cls);
if (pending_exception(self)) {
return NULL;
}
@@ -735,7 +744,9 @@ profiler_dealloc(ProfilerObject *op)
flush_unmatched(op);
clearEntries(op);
Py_XDECREF(op->externalTimer);
- Py_TYPE(op)->tp_free(op);
+ PyTypeObject *tp = Py_TYPE(op);
+ tp->tp_free(op);
+ Py_DECREF(tp);
}
static int
@@ -782,91 +793,107 @@ Profiler(timer=None, timeunit=None, subcalls=True, builtins=True)\n\
is, in seconds).\n\
");
-static PyTypeObject PyProfiler_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_lsprof.Profiler", /* tp_name */
- sizeof(ProfilerObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)profiler_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_as_async */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- profiler_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- profiler_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)profiler_init, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
- PyType_GenericNew, /* tp_new */
- PyObject_Del, /* tp_free */
+static PyType_Slot _lsprof_profiler_type_spec_slots[] = {
+ {Py_tp_doc, (void *)profiler_doc},
+ {Py_tp_methods, profiler_methods},
+ {Py_tp_dealloc, profiler_dealloc},
+ {Py_tp_init, profiler_init},
+ {Py_tp_alloc, PyType_GenericAlloc},
+ {Py_tp_new, PyType_GenericNew},
+ {Py_tp_free, PyObject_Del},
+ {0, 0}
+};
+
+static PyType_Spec _lsprof_profiler_type_spec = {
+ .name = "_lsprof.Profiler",
+ .basicsize = sizeof(ProfilerObject),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .slots = _lsprof_profiler_type_spec_slots,
};
static PyMethodDef moduleMethods[] = {
{NULL, NULL}
};
+static int
+_lsprof_traverse(PyObject *module, visitproc visit, void *arg)
+{
+ _lsprof_state *state = _lsprof_get_state(module);
+ Py_VISIT(state->profiler_type);
+ Py_VISIT(state->stats_entry_type);
+ Py_VISIT(state->stats_subentry_type);
+ return 0;
+}
+
+static int
+_lsprof_clear(PyObject *module)
+{
+ _lsprof_state *state = _lsprof_get_state(module);
+ Py_CLEAR(state->profiler_type);
+ Py_CLEAR(state->stats_entry_type);
+ Py_CLEAR(state->stats_subentry_type);
+ return 0;
+}
+
+static void
+_lsprof_free(void *module)
+{
+ _lsprof_clear((PyObject *)module);
+}
+
+static int
+_lsprof_exec(PyObject *module)
+{
+ _lsprof_state *state = PyModule_GetState(module);
+
+ state->profiler_type = (PyTypeObject *)PyType_FromModuleAndSpec(
+ module, &_lsprof_profiler_type_spec, NULL);
+ if (state->profiler_type == NULL) {
+ return -1;
+ }
+
+ if (PyModule_AddType(module, state->profiler_type) < 0) {
+ return -1;
+ }
+
+ state->stats_entry_type = PyStructSequence_NewType(&profiler_entry_desc);
+ if (state->stats_entry_type == NULL) {
+ return -1;
+ }
+ if (PyModule_AddType(module, state->stats_entry_type) < 0) {
+ return -1;
+ }
+
+ state->stats_subentry_type = PyStructSequence_NewType(&profiler_subentry_desc);
+ if (state->stats_subentry_type == NULL) {
+ return -1;
+ }
+ if (PyModule_AddType(module, state->stats_subentry_type) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static PyModuleDef_Slot _lsprofslots[] = {
+ {Py_mod_exec, _lsprof_exec},
+ {0, NULL}
+};
static struct PyModuleDef _lsprofmodule = {
PyModuleDef_HEAD_INIT,
- "_lsprof",
- "Fast profiler",
- -1,
- moduleMethods,
- NULL,
- NULL,
- NULL,
- NULL
+ .m_name = "_lsprof",
+ .m_doc = "Fast profiler",
+ .m_size = sizeof(_lsprof_state),
+ .m_methods = moduleMethods,
+ .m_slots = _lsprofslots,
+ .m_traverse = _lsprof_traverse,
+ .m_clear = _lsprof_clear,
+ .m_free = _lsprof_free
};
PyMODINIT_FUNC
PyInit__lsprof(void)
{
- PyObject *module, *d;
- module = PyModule_Create(&_lsprofmodule);
- if (module == NULL)
- return NULL;
- d = PyModule_GetDict(module);
- if (PyType_Ready(&PyProfiler_Type) < 0)
- return NULL;
- PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
-
- if (!initialized) {
- if (PyStructSequence_InitType2(&StatsEntryType,
- &profiler_entry_desc) < 0)
- return NULL;
- if (PyStructSequence_InitType2(&StatsSubEntryType,
- &profiler_subentry_desc) < 0)
- return NULL;
- }
- Py_INCREF((PyObject*) &StatsEntryType);
- Py_INCREF((PyObject*) &StatsSubEntryType);
- PyModule_AddObject(module, "profiler_entry",
- (PyObject*) &StatsEntryType);
- PyModule_AddObject(module, "profiler_subentry",
- (PyObject*) &StatsSubEntryType);
- initialized = 1;
- return module;
+ return PyModuleDef_Init(&_lsprofmodule);
}