mirror of https://github.com/python/cpython
bpo-46072: Add detailed failure stats for BINARY_OP (GH-31289)
This commit is contained in:
parent
a9da085015
commit
580cd9ab29
|
@ -0,0 +1 @@
|
|||
Add more detailed specialization failure statistics for :opcode:`BINARY_OP`.
|
|
@ -552,9 +552,28 @@ initial_counter_value(void) {
|
|||
#define SPEC_FAIL_SUBSCR_PY_OTHER 21
|
||||
#define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22
|
||||
|
||||
/* Binary add */
|
||||
/* Binary op */
|
||||
|
||||
#define SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES 12
|
||||
#define SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES 8
|
||||
#define SPEC_FAIL_BINARY_OP_ADD_OTHER 9
|
||||
#define SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES 10
|
||||
#define SPEC_FAIL_BINARY_OP_AND_INT 11
|
||||
#define SPEC_FAIL_BINARY_OP_AND_OTHER 12
|
||||
#define SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE 13
|
||||
#define SPEC_FAIL_BINARY_OP_LSHIFT 14
|
||||
#define SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY 15
|
||||
#define SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES 16
|
||||
#define SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER 17
|
||||
#define SPEC_FAIL_BINARY_OP_OR 18
|
||||
#define SPEC_FAIL_BINARY_OP_POWER 19
|
||||
#define SPEC_FAIL_BINARY_OP_REMAINDER 20
|
||||
#define SPEC_FAIL_BINARY_OP_RSHIFT 21
|
||||
#define SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES 22
|
||||
#define SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER 23
|
||||
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES 24
|
||||
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT 25
|
||||
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER 26
|
||||
#define SPEC_FAIL_BINARY_OP_XOR 27
|
||||
|
||||
/* Calls */
|
||||
#define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9
|
||||
|
@ -1745,6 +1764,76 @@ _Py_Specialize_CallNoKw(
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef Py_STATS
|
||||
static int
|
||||
binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
|
||||
{
|
||||
switch (oparg) {
|
||||
case NB_ADD:
|
||||
case NB_INPLACE_ADD:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_ADD_OTHER;
|
||||
case NB_AND:
|
||||
case NB_INPLACE_AND:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES;
|
||||
}
|
||||
if (PyLong_CheckExact(lhs)) {
|
||||
return SPEC_FAIL_BINARY_OP_AND_INT;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_AND_OTHER;
|
||||
case NB_FLOOR_DIVIDE:
|
||||
case NB_INPLACE_FLOOR_DIVIDE:
|
||||
return SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE;
|
||||
case NB_LSHIFT:
|
||||
case NB_INPLACE_LSHIFT:
|
||||
return SPEC_FAIL_BINARY_OP_LSHIFT;
|
||||
case NB_MATRIX_MULTIPLY:
|
||||
case NB_INPLACE_MATRIX_MULTIPLY:
|
||||
return SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY;
|
||||
case NB_MULTIPLY:
|
||||
case NB_INPLACE_MULTIPLY:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER;
|
||||
case NB_OR:
|
||||
case NB_INPLACE_OR:
|
||||
return SPEC_FAIL_BINARY_OP_OR;
|
||||
case NB_POWER:
|
||||
case NB_INPLACE_POWER:
|
||||
return SPEC_FAIL_BINARY_OP_POWER;
|
||||
case NB_REMAINDER:
|
||||
case NB_INPLACE_REMAINDER:
|
||||
return SPEC_FAIL_BINARY_OP_REMAINDER;
|
||||
case NB_RSHIFT:
|
||||
case NB_INPLACE_RSHIFT:
|
||||
return SPEC_FAIL_BINARY_OP_RSHIFT;
|
||||
case NB_SUBTRACT:
|
||||
case NB_INPLACE_SUBTRACT:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER;
|
||||
case NB_TRUE_DIVIDE:
|
||||
case NB_INPLACE_TRUE_DIVIDE:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES;
|
||||
}
|
||||
if (PyFloat_CheckExact(lhs)) {
|
||||
return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER;
|
||||
case NB_XOR:
|
||||
case NB_INPLACE_XOR:
|
||||
return SPEC_FAIL_BINARY_OP_XOR;
|
||||
}
|
||||
Py_UNREACHABLE();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
||||
SpecializedCacheEntry *cache)
|
||||
|
@ -1754,8 +1843,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
case NB_ADD:
|
||||
case NB_INPLACE_ADD:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES);
|
||||
goto failure;
|
||||
break;
|
||||
}
|
||||
if (PyUnicode_CheckExact(lhs)) {
|
||||
if (_Py_OPCODE(instr[1]) == STORE_FAST && Py_REFCNT(lhs) == 2) {
|
||||
|
@ -1780,8 +1868,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
case NB_MULTIPLY:
|
||||
case NB_INPLACE_MULTIPLY:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES);
|
||||
goto failure;
|
||||
break;
|
||||
}
|
||||
if (PyLong_CheckExact(lhs)) {
|
||||
*instr = _Py_MAKECODEUNIT(BINARY_OP_MULTIPLY_INT,
|
||||
|
@ -1797,8 +1884,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
case NB_SUBTRACT:
|
||||
case NB_INPLACE_SUBTRACT:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES);
|
||||
goto failure;
|
||||
break;
|
||||
}
|
||||
if (PyLong_CheckExact(lhs)) {
|
||||
*instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT,
|
||||
|
@ -1811,14 +1897,19 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
|||
goto success;
|
||||
}
|
||||
break;
|
||||
#ifndef Py_STATS
|
||||
default:
|
||||
// These operators don't have any available specializations. Rather
|
||||
// than repeatedly attempting to specialize them, just convert them
|
||||
// back to BINARY_OP (while still recording a failure, of course)!
|
||||
// back to BINARY_OP (unless we're collecting stats, where it's more
|
||||
// important to get accurate hit counts for the unadaptive version
|
||||
// and each of the different failure types):
|
||||
*instr = _Py_MAKECODEUNIT(BINARY_OP, adaptive->original_oparg);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OTHER);
|
||||
failure:
|
||||
SPECIALIZATION_FAIL(
|
||||
BINARY_OP, binary_op_fail_kind(adaptive->original_oparg, lhs, rhs));
|
||||
STAT_INC(BINARY_OP, failure);
|
||||
cache_backoff(adaptive);
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue