mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-46072: Add detailed failure stats for BINARY_OP (GH-31289)
This commit is contained in:
		
							parent
							
								
									a9da085015
								
							
						
					
					
						commit
						580cd9ab29
					
				
					 2 changed files with 103 additions and 11 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Brandt Bucher
						Brandt Bucher