summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-02-10 11:47:52 (GMT)
committerGitHub <noreply@github.com>2022-02-10 11:47:52 (GMT)
commitb0662ae5c83d8678506989cccbf7ba7bf61fea9d (patch)
treea8dd071fa771ad377f505333611e32b825266f3f
parentcfc1cecd7b6f0f27163b5bf519530284140cf5b2 (diff)
downloadcpython-b0662ae5c83d8678506989cccbf7ba7bf61fea9d.zip
cpython-b0662ae5c83d8678506989cccbf7ba7bf61fea9d.tar.gz
cpython-b0662ae5c83d8678506989cccbf7ba7bf61fea9d.tar.bz2
Add stats for PRECALL_FUNCTION. (GH-31250)
-rw-r--r--Python/ceval.c5
-rw-r--r--Python/specialize.c32
-rw-r--r--Tools/scripts/summarize_stats.py2
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:])