Skip to content

Commit b0662ae

Browse files
authored
Add stats for PRECALL_FUNCTION. (GH-31250)
1 parent cfc1cec commit b0662ae

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

Python/ceval.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4447,6 +4447,11 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
44474447

44484448
call_shape.total_args = oparg;
44494449
call_shape.kwnames = NULL;
4450+
#ifdef Py_STATS
4451+
extern int _PySpecialization_ClassifyCallable(PyObject *);
4452+
_py_stats.opcode_stats[PRECALL_FUNCTION].specialization.failure++;
4453+
_py_stats.opcode_stats[PRECALL_FUNCTION].specialization.failure_kinds[_PySpecialization_ClassifyCallable(call_shape.callable)]++;
4454+
#endif
44504455
DISPATCH();
44514456
}
44524457

Python/specialize.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats)
175175
/* Mark some opcodes as specializable for stats,
176176
* even though we don't specialize them yet. */
177177
fprintf(out, " opcode[%d].specializable : 1\n", FOR_ITER);
178+
fprintf(out, " opcode[%d].specializable : 1\n", PRECALL_FUNCTION);
178179
fprintf(out, " opcode[%d].specializable : 1\n", UNPACK_SEQUENCE);
179180
for (int i = 0; i < 256; i++) {
180181
if (adaptive_opcodes[i]) {
@@ -556,14 +557,15 @@ initial_counter_value(void) {
556557
#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 17
557558
#define SPEC_FAIL_CALL_CLASS 18
558559
#define SPEC_FAIL_CALL_PYTHON_CLASS 19
559-
#define SPEC_FAIL_CALL_C_METHOD_CALL 20
560+
#define SPEC_FAIL_CALL_METHOD_DESCRIPTOR 20
560561
#define SPEC_FAIL_CALL_BOUND_METHOD 21
561562
#define SPEC_FAIL_CALL_STR 22
562563
#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 23
563564
#define SPEC_FAIL_CALL_CLASS_MUTABLE 24
564565
#define SPEC_FAIL_CALL_KWNAMES 25
565566
#define SPEC_FAIL_CALL_METHOD_WRAPPER 26
566567
#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 27
568+
#define SPEC_FAIL_CALL_PYFUNCTION 28
567569

568570
/* COMPARE_OP */
569571
#define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12
@@ -1651,7 +1653,13 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs,
16511653
static int
16521654
call_fail_kind(PyObject *callable)
16531655
{
1654-
if (PyInstanceMethod_Check(callable)) {
1656+
if (PyCFunction_CheckExact(callable)) {
1657+
return SPEC_FAIL_CALL_PYCFUNCTION;
1658+
}
1659+
else if (PyFunction_Check(callable)) {
1660+
return SPEC_FAIL_CALL_PYFUNCTION;
1661+
}
1662+
else if (PyInstanceMethod_Check(callable)) {
16551663
return SPEC_FAIL_CALL_INSTANCE_METHOD;
16561664
}
16571665
else if (PyMethod_Check(callable)) {
@@ -1662,7 +1670,15 @@ call_fail_kind(PyObject *callable)
16621670
return SPEC_FAIL_CALL_CMETHOD;
16631671
}
16641672
else if (PyType_Check(callable)) {
1665-
return SPEC_FAIL_CALL_CLASS;
1673+
if (((PyTypeObject *)callable)->tp_new == PyBaseObject_Type.tp_new) {
1674+
return SPEC_FAIL_CALL_PYTHON_CLASS;
1675+
}
1676+
else {
1677+
return SPEC_FAIL_CALL_CLASS;
1678+
}
1679+
}
1680+
else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) {
1681+
return SPEC_FAIL_CALL_METHOD_DESCRIPTOR;
16661682
}
16671683
else if (Py_TYPE(callable) == &PyWrapperDescr_Type) {
16681684
return SPEC_FAIL_CALL_OPERATOR_WRAPPER;
@@ -1905,6 +1921,8 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs,
19051921
adaptive->counter = initial_counter_value();
19061922
}
19071923

1924+
#ifdef Py_STATS
1925+
19081926
int
19091927
_PySpecialization_ClassifyIterator(PyObject *iter)
19101928
{
@@ -1966,3 +1984,11 @@ _PySpecialization_ClassifySequence(PyObject *seq)
19661984
}
19671985
return SPEC_FAIL_OTHER;
19681986
}
1987+
1988+
int
1989+
_PySpecialization_ClassifyCallable(PyObject *callable)
1990+
{
1991+
return call_fail_kind(callable);
1992+
}
1993+
1994+
#endif

Tools/scripts/summarize_stats.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ def kind_to_text(kind, defines, opname):
114114
opname = "ATTR"
115115
if opname.endswith("SUBSCR"):
116116
opname = "SUBSCR"
117+
if opname.startswith("PRECALL"):
118+
opname = "CALL"
117119
for name in defines[kind]:
118120
if name.startswith(opname):
119121
return pretty(name[len(opname)+1:])

0 commit comments

Comments
 (0)