mirror of
https://github.com/python/cpython
synced 2024-09-16 02:59:56 +00:00
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_PY_OTHER 21
|
||||||
#define SPEC_FAIL_SUBSCR_DICT_SUBCLASS_NO_OVERRIDE 22
|
#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 */
|
/* Calls */
|
||||||
#define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9
|
#define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9
|
||||||
|
@ -1745,6 +1764,76 @@ _Py_Specialize_CallNoKw(
|
||||||
return 0;
|
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
|
void
|
||||||
_Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
_Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
||||||
SpecializedCacheEntry *cache)
|
SpecializedCacheEntry *cache)
|
||||||
|
@ -1754,8 +1843,7 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
||||||
case NB_ADD:
|
case NB_ADD:
|
||||||
case NB_INPLACE_ADD:
|
case NB_INPLACE_ADD:
|
||||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES);
|
break;
|
||||||
goto failure;
|
|
||||||
}
|
}
|
||||||
if (PyUnicode_CheckExact(lhs)) {
|
if (PyUnicode_CheckExact(lhs)) {
|
||||||
if (_Py_OPCODE(instr[1]) == STORE_FAST && Py_REFCNT(lhs) == 2) {
|
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_MULTIPLY:
|
||||||
case NB_INPLACE_MULTIPLY:
|
case NB_INPLACE_MULTIPLY:
|
||||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES);
|
break;
|
||||||
goto failure;
|
|
||||||
}
|
}
|
||||||
if (PyLong_CheckExact(lhs)) {
|
if (PyLong_CheckExact(lhs)) {
|
||||||
*instr = _Py_MAKECODEUNIT(BINARY_OP_MULTIPLY_INT,
|
*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_SUBTRACT:
|
||||||
case NB_INPLACE_SUBTRACT:
|
case NB_INPLACE_SUBTRACT:
|
||||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_BINARY_OP_DIFFERENT_TYPES);
|
break;
|
||||||
goto failure;
|
|
||||||
}
|
}
|
||||||
if (PyLong_CheckExact(lhs)) {
|
if (PyLong_CheckExact(lhs)) {
|
||||||
*instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT,
|
*instr = _Py_MAKECODEUNIT(BINARY_OP_SUBTRACT_INT,
|
||||||
|
@ -1811,14 +1897,19 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr,
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifndef Py_STATS
|
||||||
default:
|
default:
|
||||||
// These operators don't have any available specializations. Rather
|
// These operators don't have any available specializations. Rather
|
||||||
// than repeatedly attempting to specialize them, just convert them
|
// 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);
|
*instr = _Py_MAKECODEUNIT(BINARY_OP, adaptive->original_oparg);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
SPECIALIZATION_FAIL(BINARY_OP, SPEC_FAIL_OTHER);
|
SPECIALIZATION_FAIL(
|
||||||
failure:
|
BINARY_OP, binary_op_fail_kind(adaptive->original_oparg, lhs, rhs));
|
||||||
STAT_INC(BINARY_OP, failure);
|
STAT_INC(BINARY_OP, failure);
|
||||||
cache_backoff(adaptive);
|
cache_backoff(adaptive);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue