]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add stats for PRECALL_FUNCTION. (GH-31250)
authorMark Shannon <mark@hotpy.org>
Thu, 10 Feb 2022 11:47:52 +0000 (11:47 +0000)
committerGitHub <noreply@github.com>
Thu, 10 Feb 2022 11:47:52 +0000 (11:47 +0000)
Python/ceval.c
Python/specialize.c
Tools/scripts/summarize_stats.py

index 02e4e7b9e4d54f51a4cfc925240d52159a6416dc..958ca11409c322788bd97749d38523a41cdf9278 100644 (file)
@@ -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();
         }
 
index b5e4de5d6d2171da92800332929d9907db009f81..940ab172d55fe25f3cd5401850c53117e0cecc84 100644 (file)
@@ -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
index 6e0286f52a0ea65f919fc03d57ad94137211a02c..f6e5b333b09fcb7280ba8ae02b0ca1f15455835e 100644 (file)
@@ -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:])