From b0662ae5c83d8678506989cccbf7ba7bf61fea9d Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 10 Feb 2022 11:47:52 +0000 Subject: Add stats for PRECALL_FUNCTION. (GH-31250) --- Python/ceval.c | 5 +++++ Python/specialize.c | 32 +++++++++++++++++++++++++++++--- Tools/scripts/summarize_stats.py | 2 ++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 02e4e7b..958ca11 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -4447,6 +4447,11 @@ handle_eval_breaker: call_shape.total_args = oparg; call_shape.kwnames = NULL; +#ifdef Py_STATS + extern int _PySpecialization_ClassifyCallable(PyObject *); + _py_stats.opcode_stats[PRECALL_FUNCTION].specialization.failure++; + _py_stats.opcode_stats[PRECALL_FUNCTION].specialization.failure_kinds[_PySpecialization_ClassifyCallable(call_shape.callable)]++; +#endif DISPATCH(); } diff --git a/Python/specialize.c b/Python/specialize.c index b5e4de5..940ab17 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -175,6 +175,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats) /* Mark some opcodes as specializable for stats, * even though we don't specialize them yet. */ fprintf(out, " opcode[%d].specializable : 1\n", FOR_ITER); + fprintf(out, " opcode[%d].specializable : 1\n", PRECALL_FUNCTION); fprintf(out, " opcode[%d].specializable : 1\n", UNPACK_SEQUENCE); for (int i = 0; i < 256; i++) { if (adaptive_opcodes[i]) { @@ -556,7 +557,7 @@ initial_counter_value(void) { #define SPEC_FAIL_CALL_BAD_CALL_FLAGS 17 #define SPEC_FAIL_CALL_CLASS 18 #define SPEC_FAIL_CALL_PYTHON_CLASS 19 -#define SPEC_FAIL_CALL_C_METHOD_CALL 20 +#define SPEC_FAIL_CALL_METHOD_DESCRIPTOR 20 #define SPEC_FAIL_CALL_BOUND_METHOD 21 #define SPEC_FAIL_CALL_STR 22 #define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 23 @@ -564,6 +565,7 @@ initial_counter_value(void) { #define SPEC_FAIL_CALL_KWNAMES 25 #define SPEC_FAIL_CALL_METHOD_WRAPPER 26 #define SPEC_FAIL_CALL_OPERATOR_WRAPPER 27 +#define SPEC_FAIL_CALL_PYFUNCTION 28 /* COMPARE_OP */ #define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12 @@ -1651,7 +1653,13 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, static int call_fail_kind(PyObject *callable) { - if (PyInstanceMethod_Check(callable)) { + if (PyCFunction_CheckExact(callable)) { + return SPEC_FAIL_CALL_PYCFUNCTION; + } + else if (PyFunction_Check(callable)) { + return SPEC_FAIL_CALL_PYFUNCTION; + } + else if (PyInstanceMethod_Check(callable)) { return SPEC_FAIL_CALL_INSTANCE_METHOD; } else if (PyMethod_Check(callable)) { @@ -1662,7 +1670,15 @@ call_fail_kind(PyObject *callable) return SPEC_FAIL_CALL_CMETHOD; } else if (PyType_Check(callable)) { - return SPEC_FAIL_CALL_CLASS; + if (((PyTypeObject *)callable)->tp_new == PyBaseObject_Type.tp_new) { + return SPEC_FAIL_CALL_PYTHON_CLASS; + } + else { + return SPEC_FAIL_CALL_CLASS; + } + } + else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { + return SPEC_FAIL_CALL_METHOD_DESCRIPTOR; } else if (Py_TYPE(callable) == &PyWrapperDescr_Type) { return SPEC_FAIL_CALL_OPERATOR_WRAPPER; @@ -1905,6 +1921,8 @@ success: adaptive->counter = initial_counter_value(); } +#ifdef Py_STATS + int _PySpecialization_ClassifyIterator(PyObject *iter) { @@ -1966,3 +1984,11 @@ _PySpecialization_ClassifySequence(PyObject *seq) } return SPEC_FAIL_OTHER; } + +int +_PySpecialization_ClassifyCallable(PyObject *callable) +{ + return call_fail_kind(callable); +} + +#endif diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index 6e0286f..f6e5b33 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -114,6 +114,8 @@ def kind_to_text(kind, defines, opname): opname = "ATTR" if opname.endswith("SUBSCR"): opname = "SUBSCR" + if opname.startswith("PRECALL"): + opname = "CALL" for name in defines[kind]: if name.startswith(opname): return pretty(name[len(opname)+1:]) -- cgit v0.12