From a87752c94e6c48a492ecbdbb96fbdb6f59e67d99 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 6 Nov 2024 16:29:04 +0000 Subject: [PATCH 1/3] Add failing test --- Lib/test/test_capi/test_opt.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index c352325ff3d08a..7b3d9e4fd1126f 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -1486,6 +1486,14 @@ def fn(a): fn(A()) + def test_jit_error_pops(self): + """ + Tests that the correct number of pops are inserted into the + exit stub + """ + items = 17 * [None] + [[]] + with self.assertRaises(TypeError): + {item for item in items} if __name__ == "__main__": unittest.main() From 98f6f0f8ca9b0262d29094b23c5c87b1fd2c4c50 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 6 Nov 2024 16:30:43 +0000 Subject: [PATCH 2/3] Do not include peeks in uop pop effect --- Include/internal/pycore_uop_metadata.h | 112 +++++++++--------- .../cases_generator/uop_metadata_generator.py | 2 + 2 files changed, 58 insertions(+), 56 deletions(-) diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index ade297201f0ac2..98a41d1f23f569 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -658,7 +658,7 @@ int _PyUop_num_popped(int opcode, int oparg) case _TO_BOOL: return 1; case _TO_BOOL_BOOL: - return 1; + return 0; case _TO_BOOL_INT: return 1; case _TO_BOOL_LIST: @@ -672,11 +672,11 @@ int _PyUop_num_popped(int opcode, int oparg) case _UNARY_INVERT: return 1; case _GUARD_BOTH_INT: - return 2; + return 0; case _GUARD_NOS_INT: - return 2; + return 0; case _GUARD_TOS_INT: - return 1; + return 0; case _BINARY_OP_MULTIPLY_INT: return 2; case _BINARY_OP_ADD_INT: @@ -684,11 +684,11 @@ int _PyUop_num_popped(int opcode, int oparg) case _BINARY_OP_SUBTRACT_INT: return 2; case _GUARD_BOTH_FLOAT: - return 2; + return 0; case _GUARD_NOS_FLOAT: - return 2; + return 0; case _GUARD_TOS_FLOAT: - return 1; + return 0; case _BINARY_OP_MULTIPLY_FLOAT: return 2; case _BINARY_OP_ADD_FLOAT: @@ -696,7 +696,7 @@ int _PyUop_num_popped(int opcode, int oparg) case _BINARY_OP_SUBTRACT_FLOAT: return 2; case _GUARD_BOTH_UNICODE: - return 2; + return 0; case _BINARY_OP_ADD_UNICODE: return 2; case _BINARY_OP_INPLACE_ADD_UNICODE: @@ -716,13 +716,13 @@ int _PyUop_num_popped(int opcode, int oparg) case _BINARY_SUBSCR_DICT: return 2; case _BINARY_SUBSCR_CHECK_FUNC: - return 2; + return 0; case _BINARY_SUBSCR_INIT_CALL: return 2; case _LIST_APPEND: - return 2 + (oparg-1); + return 1; case _SET_ADD: - return 2 + (oparg-1); + return 1; case _STORE_SUBSCR: return 3; case _STORE_SUBSCR_LIST_INT: @@ -740,11 +740,11 @@ int _PyUop_num_popped(int opcode, int oparg) case _GET_AITER: return 1; case _GET_ANEXT: - return 1; + return 0; case _GET_AWAITABLE: return 1; case _SEND_GEN_FRAME: - return 2; + return 1; case _YIELD_VALUE: return 1; case _POP_EXCEPT: @@ -812,9 +812,9 @@ int _PyUop_num_popped(int opcode, int oparg) case _BUILD_LIST: return oparg; case _LIST_EXTEND: - return 2 + (oparg-1); + return 1; case _SET_UPDATE: - return 2 + (oparg-1); + return 1; case _BUILD_SET: return oparg; case _BUILD_MAP: @@ -822,11 +822,11 @@ int _PyUop_num_popped(int opcode, int oparg) case _SETUP_ANNOTATIONS: return 0; case _DICT_UPDATE: - return 2 + (oparg - 1); + return 1; case _DICT_MERGE: - return 5 + (oparg - 1); + return 1; case _MAP_ADD: - return 3 + (oparg - 1); + return 2; case _LOAD_SUPER_ATTR_ATTR: return 3; case _LOAD_SUPER_ATTR_METHOD: @@ -834,9 +834,9 @@ int _PyUop_num_popped(int opcode, int oparg) case _LOAD_ATTR: return 1; case _GUARD_TYPE_VERSION: - return 1; + return 0; case _CHECK_MANAGED_OBJECT_HAS_VALUES: - return 1; + return 0; case _LOAD_ATTR_INSTANCE_VALUE_0: return 1; case _LOAD_ATTR_INSTANCE_VALUE_1: @@ -844,11 +844,11 @@ int _PyUop_num_popped(int opcode, int oparg) case _LOAD_ATTR_INSTANCE_VALUE: return 1; case _CHECK_ATTR_MODULE: - return 1; + return 0; case _LOAD_ATTR_MODULE: return 1; case _CHECK_ATTR_WITH_HINT: - return 1; + return 0; case _LOAD_ATTR_WITH_HINT: return 1; case _LOAD_ATTR_SLOT_0: @@ -858,7 +858,7 @@ int _PyUop_num_popped(int opcode, int oparg) case _LOAD_ATTR_SLOT: return 1; case _CHECK_ATTR_CLASS: - return 1; + return 0; case _LOAD_ATTR_CLASS_0: return 1; case _LOAD_ATTR_CLASS_1: @@ -868,7 +868,7 @@ int _PyUop_num_popped(int opcode, int oparg) case _LOAD_ATTR_PROPERTY_FRAME: return 1; case _GUARD_DORV_NO_DICT: - return 1; + return 0; case _STORE_ATTR_INSTANCE_VALUE: return 2; case _STORE_ATTR_WITH_HINT: @@ -894,59 +894,59 @@ int _PyUop_num_popped(int opcode, int oparg) case _CHECK_EG_MATCH: return 2; case _CHECK_EXC_MATCH: - return 2; + return 1; case _IMPORT_NAME: return 2; case _IMPORT_FROM: - return 1; + return 0; case _IS_NONE: return 1; case _GET_LEN: - return 1; + return 0; case _MATCH_CLASS: return 3; case _MATCH_MAPPING: - return 1; + return 0; case _MATCH_SEQUENCE: - return 1; + return 0; case _MATCH_KEYS: - return 2; + return 0; case _GET_ITER: return 1; case _GET_YIELD_FROM_ITER: return 1; case _FOR_ITER_TIER_TWO: - return 1; + return 0; case _ITER_CHECK_LIST: - return 1; + return 0; case _GUARD_NOT_EXHAUSTED_LIST: - return 1; + return 0; case _ITER_NEXT_LIST: - return 1; + return 0; case _ITER_CHECK_TUPLE: - return 1; + return 0; case _GUARD_NOT_EXHAUSTED_TUPLE: - return 1; + return 0; case _ITER_NEXT_TUPLE: - return 1; + return 0; case _ITER_CHECK_RANGE: - return 1; + return 0; case _GUARD_NOT_EXHAUSTED_RANGE: - return 1; + return 0; case _ITER_NEXT_RANGE: - return 1; + return 0; case _FOR_ITER_GEN_FRAME: - return 1; + return 0; case _LOAD_SPECIAL: return 1; case _WITH_EXCEPT_START: - return 5; + return 0; case _PUSH_EXC_INFO: return 1; case _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT: - return 1; + return 0; case _GUARD_KEYS_VERSION: - return 1; + return 0; case _LOAD_ATTR_METHOD_WITH_VALUES: return 1; case _LOAD_ATTR_METHOD_NO_DICT: @@ -956,7 +956,7 @@ int _PyUop_num_popped(int opcode, int oparg) case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: return 1; case _CHECK_ATTR_METHOD_LAZY_DICT: - return 1; + return 0; case _LOAD_ATTR_METHOD_LAZY_DICT: return 1; case _MAYBE_EXPAND_METHOD: @@ -964,25 +964,25 @@ int _PyUop_num_popped(int opcode, int oparg) case _PY_FRAME_GENERAL: return 2 + oparg; case _CHECK_FUNCTION_VERSION: - return 2 + oparg; + return 0; case _CHECK_METHOD_VERSION: - return 2 + oparg; + return 0; case _EXPAND_METHOD: return 2 + oparg; case _CHECK_IS_NOT_PY_CALLABLE: - return 2 + oparg; + return 0; case _CALL_NON_PY_GENERAL: return 2 + oparg; case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: - return 2 + oparg; + return 0; case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: return 2 + oparg; case _CHECK_PEP_523: return 0; case _CHECK_FUNCTION_EXACT_ARGS: - return 2 + oparg; + return 0; case _CHECK_STACK_SPACE: - return 2 + oparg; + return 0; case _INIT_CALL_PY_EXACT_ARGS_0: return 2 + oparg; case _INIT_CALL_PY_EXACT_ARGS_1: @@ -1036,17 +1036,17 @@ int _PyUop_num_popped(int opcode, int oparg) case _PY_FRAME_KW: return 3 + oparg; case _CHECK_FUNCTION_VERSION_KW: - return 3 + oparg; + return 0; case _CHECK_METHOD_VERSION_KW: - return 3 + oparg; + return 0; case _EXPAND_METHOD_KW: return 3 + oparg; case _CHECK_IS_NOT_PY_CALLABLE_KW: - return 3 + oparg; + return 0; case _CALL_KW_NON_PY: return 3 + oparg; case _MAKE_CALLARGS_A_TUPLE: - return 3 + (oparg & 1); + return 1 + (oparg & 1); case _MAKE_FUNCTION: return 1; case _SET_FUNCTION_ATTRIBUTE: @@ -1062,7 +1062,7 @@ int _PyUop_num_popped(int opcode, int oparg) case _FORMAT_WITH_SPEC: return 2; case _COPY: - return 1 + (oparg-1); + return 0; case _BINARY_OP: return 2; case _SWAP: diff --git a/Tools/cases_generator/uop_metadata_generator.py b/Tools/cases_generator/uop_metadata_generator.py index 7b3325ada4a49f..6eb022899d6cae 100644 --- a/Tools/cases_generator/uop_metadata_generator.py +++ b/Tools/cases_generator/uop_metadata_generator.py @@ -51,6 +51,8 @@ def generate_names_and_flags(analysis: Analysis, out: CWriter) -> None: if uop.is_viable() and uop.properties.tier != 1: stack = Stack() for var in reversed(uop.stack.inputs): + if var.peek: + break stack.pop(var) popped = (-stack.base_offset).to_c() out.emit(f"case {uop.name}:\n") From a8771ab088489a14dd9c76253102d57419064ac1 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 6 Nov 2024 16:34:20 +0000 Subject: [PATCH 3/3] Add news --- .../2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst new file mode 100644 index 00000000000000..ebf6673782f02c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-06-16-34-11.gh-issue-126222.9NBfTn.rst @@ -0,0 +1,3 @@ +Do not include count of "peek" items in ``_PyUop_num_popped``. This ensures +that the correct number of items are popped from the stack when a micro-op +exits with an error.