mirror of
				https://github.com/python/cpython.git
				synced 2025-11-01 06:01:29 +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
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Brandt Bucher
						Brandt Bucher