mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
GH-90230: Add stats to breakdown the origin of calls to PyEval_EvalFrame (GH-93284)
This commit is contained in:
parent
8995177030
commit
bbcf42449e
13 changed files with 63 additions and 11 deletions
|
|
@ -103,6 +103,7 @@ _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) {
|
|||
// Private static inline function variant of public PyObject_CallNoArgs()
|
||||
static inline PyObject *
|
||||
_PyObject_CallNoArgs(PyObject *func) {
|
||||
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL);
|
||||
}
|
||||
|
|
@ -111,6 +112,7 @@ _PyObject_CallNoArgs(PyObject *func) {
|
|||
static inline PyObject *
|
||||
_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
|
||||
return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ extern PyObject* _PyEval_BuiltinsFromGlobals(
|
|||
static inline PyObject*
|
||||
_PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag)
|
||||
{
|
||||
EVAL_CALL_STAT_INC(EVAL_CALL_TOTAL);
|
||||
if (tstate->interp->eval_frame == NULL) {
|
||||
return _PyEval_EvalFrameDefault(tstate, frame, throwflag);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,6 +265,9 @@ extern int _PyStaticCode_InternStrings(PyCodeObject *co);
|
|||
#define OBJECT_STAT_INC(name) _py_stats.object_stats.name++
|
||||
#define OBJECT_STAT_INC_COND(name, cond) \
|
||||
do { if (cond) _py_stats.object_stats.name++; } while (0)
|
||||
#define EVAL_CALL_STAT_INC(name) _py_stats.call_stats.eval_calls[name]++
|
||||
#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \
|
||||
do { if (PyFunction_Check(callable)) _py_stats.call_stats.eval_calls[name]++; } while (0)
|
||||
|
||||
// Used by the _opcode extension which is built as a shared library
|
||||
PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
|
||||
|
|
@ -276,6 +279,8 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
|
|||
#define CALL_STAT_INC(name) ((void)0)
|
||||
#define OBJECT_STAT_INC(name) ((void)0)
|
||||
#define OBJECT_STAT_INC_COND(name, cond) ((void)0)
|
||||
#define EVAL_CALL_STAT_INC(name) ((void)0)
|
||||
#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0)
|
||||
#endif // !Py_STATS
|
||||
|
||||
// Cache values are only valid in memory, so use native endianness.
|
||||
|
|
|
|||
|
|
@ -10,6 +10,20 @@ extern "C" {
|
|||
|
||||
#define SPECIALIZATION_FAILURE_KINDS 32
|
||||
|
||||
/* Stats for determining who is calling PyEval_EvalFrame */
|
||||
#define EVAL_CALL_TOTAL 0
|
||||
#define EVAL_CALL_VECTOR 1
|
||||
#define EVAL_CALL_GENERATOR 2
|
||||
#define EVAL_CALL_LEGACY 3
|
||||
#define EVAL_CALL_FUNCTION_VECTORCALL 4
|
||||
#define EVAL_CALL_BUILD_CLASS 5
|
||||
#define EVAL_CALL_SLOT 6
|
||||
#define EVAL_CALL_FUNCTION_EX 7
|
||||
#define EVAL_CALL_API 8
|
||||
#define EVAL_CALL_METHOD 9
|
||||
|
||||
#define EVAL_CALL_KINDS 10
|
||||
|
||||
typedef struct _specialization_stats {
|
||||
uint64_t success;
|
||||
uint64_t failure;
|
||||
|
|
@ -31,6 +45,7 @@ typedef struct _call_stats {
|
|||
uint64_t pyeval_calls;
|
||||
uint64_t frames_pushed;
|
||||
uint64_t frame_objects_created;
|
||||
uint64_t eval_calls[EVAL_CALL_KINDS];
|
||||
} CallStats;
|
||||
|
||||
typedef struct _object_stats {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue