diff options
author | Mark Shannon <mark@hotpy.org> | 2022-02-10 11:47:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-10 11:47:52 (GMT) |
commit | b0662ae5c83d8678506989cccbf7ba7bf61fea9d (patch) | |
tree | a8dd071fa771ad377f505333611e32b825266f3f | |
parent | cfc1cecd7b6f0f27163b5bf519530284140cf5b2 (diff) | |
download | cpython-b0662ae5c83d8678506989cccbf7ba7bf61fea9d.zip cpython-b0662ae5c83d8678506989cccbf7ba7bf61fea9d.tar.gz cpython-b0662ae5c83d8678506989cccbf7ba7bf61fea9d.tar.bz2 |
Add stats for PRECALL_FUNCTION. (GH-31250)
-rw-r--r-- | Python/ceval.c | 5 | ||||
-rw-r--r-- | Python/specialize.c | 32 | ||||
-rw-r--r-- | 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:]) |