From 786f464c740a2f2bf60871feaf73df87b315877b Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Sat, 20 Dec 2025 01:43:36 +0800 Subject: [PATCH 1/7] gh-142961: Fix constant folding len(tuple) in JIT (GH-142963) --- Include/internal/pycore_uop_ids.h | 1543 +++++++++-------- Include/internal/pycore_uop_metadata.h | 21 + Lib/test/test_capi/test_opt.py | 12 + ...-12-19-00-59-29.gh-issue-142961.q8WRSq.rst | 1 + Python/bytecodes.c | 7 + Python/executor_cases.c.h | 100 ++ Python/optimizer_bytecodes.c | 6 +- Python/optimizer_cases.c.h | 18 +- 8 files changed, 931 insertions(+), 777 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-19-00-59-29.gh-issue-142961.q8WRSq.rst diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index e9851b767bc835..6130e5cad21bf4 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -314,788 +314,793 @@ extern "C" { #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _SPILL_OR_RELOAD 524 -#define _START_EXECUTOR 525 -#define _STORE_ATTR 526 -#define _STORE_ATTR_INSTANCE_VALUE 527 -#define _STORE_ATTR_SLOT 528 -#define _STORE_ATTR_WITH_HINT 529 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 524 +#define _SPILL_OR_RELOAD 525 +#define _START_EXECUTOR 526 +#define _STORE_ATTR 527 +#define _STORE_ATTR_INSTANCE_VALUE 528 +#define _STORE_ATTR_SLOT 529 +#define _STORE_ATTR_WITH_HINT 530 #define _STORE_DEREF STORE_DEREF -#define _STORE_FAST 530 -#define _STORE_FAST_0 531 -#define _STORE_FAST_1 532 -#define _STORE_FAST_2 533 -#define _STORE_FAST_3 534 -#define _STORE_FAST_4 535 -#define _STORE_FAST_5 536 -#define _STORE_FAST_6 537 -#define _STORE_FAST_7 538 +#define _STORE_FAST 531 +#define _STORE_FAST_0 532 +#define _STORE_FAST_1 533 +#define _STORE_FAST_2 534 +#define _STORE_FAST_3 535 +#define _STORE_FAST_4 536 +#define _STORE_FAST_5 537 +#define _STORE_FAST_6 538 +#define _STORE_FAST_7 539 #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 539 -#define _STORE_SUBSCR 540 -#define _STORE_SUBSCR_DICT 541 -#define _STORE_SUBSCR_LIST_INT 542 -#define _SWAP 543 -#define _SWAP_2 544 -#define _SWAP_3 545 -#define _TIER2_RESUME_CHECK 546 -#define _TO_BOOL 547 +#define _STORE_SLICE 540 +#define _STORE_SUBSCR 541 +#define _STORE_SUBSCR_DICT 542 +#define _STORE_SUBSCR_LIST_INT 543 +#define _SWAP 544 +#define _SWAP_2 545 +#define _SWAP_3 546 +#define _TIER2_RESUME_CHECK 547 +#define _TO_BOOL 548 #define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_INT TO_BOOL_INT -#define _TO_BOOL_LIST 548 +#define _TO_BOOL_LIST 549 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 549 +#define _TO_BOOL_STR 550 #define _TRACE_RECORD TRACE_RECORD #define _UNARY_INVERT UNARY_INVERT #define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 550 -#define _UNPACK_SEQUENCE_LIST 551 -#define _UNPACK_SEQUENCE_TUPLE 552 -#define _UNPACK_SEQUENCE_TWO_TUPLE 553 +#define _UNPACK_SEQUENCE 551 +#define _UNPACK_SEQUENCE_LIST 552 +#define _UNPACK_SEQUENCE_TUPLE 553 +#define _UNPACK_SEQUENCE_TWO_TUPLE 554 #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 553 -#define _BINARY_OP_r21 554 -#define _BINARY_OP_ADD_FLOAT_r03 555 -#define _BINARY_OP_ADD_FLOAT_r13 556 -#define _BINARY_OP_ADD_FLOAT_r23 557 -#define _BINARY_OP_ADD_INT_r03 558 -#define _BINARY_OP_ADD_INT_r13 559 -#define _BINARY_OP_ADD_INT_r23 560 -#define _BINARY_OP_ADD_UNICODE_r03 561 -#define _BINARY_OP_ADD_UNICODE_r13 562 -#define _BINARY_OP_ADD_UNICODE_r23 563 -#define _BINARY_OP_EXTEND_r21 564 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r20 565 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 566 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 567 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 568 -#define _BINARY_OP_MULTIPLY_INT_r03 569 -#define _BINARY_OP_MULTIPLY_INT_r13 570 -#define _BINARY_OP_MULTIPLY_INT_r23 571 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 572 -#define _BINARY_OP_SUBSCR_DICT_r21 573 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 574 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 575 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 576 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 577 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 578 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 579 -#define _BINARY_OP_SUBSCR_STR_INT_r23 580 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r21 581 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 582 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 583 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 584 -#define _BINARY_OP_SUBTRACT_INT_r03 585 -#define _BINARY_OP_SUBTRACT_INT_r13 586 -#define _BINARY_OP_SUBTRACT_INT_r23 587 -#define _BINARY_SLICE_r31 588 -#define _BUILD_INTERPOLATION_r01 589 -#define _BUILD_LIST_r01 590 -#define _BUILD_MAP_r01 591 -#define _BUILD_SET_r01 592 -#define _BUILD_SLICE_r01 593 -#define _BUILD_STRING_r01 594 -#define _BUILD_TEMPLATE_r21 595 -#define _BUILD_TUPLE_r01 596 -#define _CALL_BUILTIN_CLASS_r01 597 -#define _CALL_BUILTIN_FAST_r01 598 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 599 -#define _CALL_BUILTIN_O_r03 600 -#define _CALL_INTRINSIC_1_r11 601 -#define _CALL_INTRINSIC_2_r21 602 -#define _CALL_ISINSTANCE_r31 603 -#define _CALL_KW_NON_PY_r11 604 -#define _CALL_LEN_r33 605 -#define _CALL_LIST_APPEND_r02 606 -#define _CALL_LIST_APPEND_r12 607 -#define _CALL_LIST_APPEND_r22 608 -#define _CALL_LIST_APPEND_r32 609 -#define _CALL_METHOD_DESCRIPTOR_FAST_r01 610 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 611 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 612 -#define _CALL_METHOD_DESCRIPTOR_O_r01 613 -#define _CALL_NON_PY_GENERAL_r01 614 -#define _CALL_STR_1_r32 615 -#define _CALL_TUPLE_1_r32 616 -#define _CALL_TYPE_1_r31 617 -#define _CHECK_AND_ALLOCATE_OBJECT_r00 618 -#define _CHECK_ATTR_CLASS_r01 619 -#define _CHECK_ATTR_CLASS_r11 620 -#define _CHECK_ATTR_CLASS_r22 621 -#define _CHECK_ATTR_CLASS_r33 622 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 623 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 624 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 625 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 626 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 627 -#define _CHECK_EG_MATCH_r22 628 -#define _CHECK_EXC_MATCH_r22 629 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 630 -#define _CHECK_FUNCTION_VERSION_r00 631 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 632 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 633 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 634 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 635 -#define _CHECK_FUNCTION_VERSION_KW_r11 636 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 637 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 638 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 639 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 640 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 641 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 642 -#define _CHECK_METHOD_VERSION_r00 643 -#define _CHECK_METHOD_VERSION_KW_r11 644 -#define _CHECK_PEP_523_r00 645 -#define _CHECK_PEP_523_r11 646 -#define _CHECK_PEP_523_r22 647 -#define _CHECK_PEP_523_r33 648 -#define _CHECK_PERIODIC_r00 649 -#define _CHECK_PERIODIC_AT_END_r00 650 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 651 -#define _CHECK_RECURSION_REMAINING_r00 652 -#define _CHECK_RECURSION_REMAINING_r11 653 -#define _CHECK_RECURSION_REMAINING_r22 654 -#define _CHECK_RECURSION_REMAINING_r33 655 -#define _CHECK_STACK_SPACE_r00 656 -#define _CHECK_STACK_SPACE_OPERAND_r00 657 -#define _CHECK_STACK_SPACE_OPERAND_r11 658 -#define _CHECK_STACK_SPACE_OPERAND_r22 659 -#define _CHECK_STACK_SPACE_OPERAND_r33 660 -#define _CHECK_VALIDITY_r00 661 -#define _CHECK_VALIDITY_r11 662 -#define _CHECK_VALIDITY_r22 663 -#define _CHECK_VALIDITY_r33 664 -#define _COLD_DYNAMIC_EXIT_r00 665 -#define _COLD_EXIT_r00 666 -#define _COMPARE_OP_r21 667 -#define _COMPARE_OP_FLOAT_r01 668 -#define _COMPARE_OP_FLOAT_r11 669 -#define _COMPARE_OP_FLOAT_r21 670 -#define _COMPARE_OP_FLOAT_r32 671 -#define _COMPARE_OP_INT_r23 672 -#define _COMPARE_OP_STR_r21 673 -#define _CONTAINS_OP_r21 674 -#define _CONTAINS_OP_DICT_r21 675 -#define _CONTAINS_OP_SET_r21 676 -#define _CONVERT_VALUE_r11 677 -#define _COPY_r01 678 -#define _COPY_1_r02 679 -#define _COPY_1_r12 680 -#define _COPY_1_r23 681 -#define _COPY_2_r03 682 -#define _COPY_2_r13 683 -#define _COPY_2_r23 684 -#define _COPY_3_r03 685 -#define _COPY_3_r13 686 -#define _COPY_3_r23 687 -#define _COPY_3_r33 688 -#define _COPY_FREE_VARS_r00 689 -#define _COPY_FREE_VARS_r11 690 -#define _COPY_FREE_VARS_r22 691 -#define _COPY_FREE_VARS_r33 692 -#define _CREATE_INIT_FRAME_r01 693 -#define _DELETE_ATTR_r10 694 -#define _DELETE_DEREF_r00 695 -#define _DELETE_FAST_r00 696 -#define _DELETE_GLOBAL_r00 697 -#define _DELETE_NAME_r00 698 -#define _DELETE_SUBSCR_r20 699 -#define _DEOPT_r00 700 -#define _DEOPT_r10 701 -#define _DEOPT_r20 702 -#define _DEOPT_r30 703 -#define _DICT_MERGE_r10 704 -#define _DICT_UPDATE_r10 705 -#define _DO_CALL_r01 706 -#define _DO_CALL_FUNCTION_EX_r31 707 -#define _DO_CALL_KW_r11 708 -#define _DYNAMIC_EXIT_r00 709 -#define _DYNAMIC_EXIT_r10 710 -#define _DYNAMIC_EXIT_r20 711 -#define _DYNAMIC_EXIT_r30 712 -#define _END_FOR_r10 713 -#define _END_SEND_r21 714 -#define _ERROR_POP_N_r00 715 -#define _EXIT_INIT_CHECK_r10 716 -#define _EXIT_TRACE_r00 717 -#define _EXIT_TRACE_r10 718 -#define _EXIT_TRACE_r20 719 -#define _EXIT_TRACE_r30 720 -#define _EXPAND_METHOD_r00 721 -#define _EXPAND_METHOD_KW_r11 722 -#define _FATAL_ERROR_r00 723 -#define _FATAL_ERROR_r11 724 -#define _FATAL_ERROR_r22 725 -#define _FATAL_ERROR_r33 726 -#define _FORMAT_SIMPLE_r11 727 -#define _FORMAT_WITH_SPEC_r21 728 -#define _FOR_ITER_r23 729 -#define _FOR_ITER_GEN_FRAME_r23 730 -#define _FOR_ITER_TIER_TWO_r23 731 -#define _GET_AITER_r11 732 -#define _GET_ANEXT_r12 733 -#define _GET_AWAITABLE_r11 734 -#define _GET_ITER_r12 735 -#define _GET_LEN_r12 736 -#define _GET_YIELD_FROM_ITER_r11 737 -#define _GUARD_BINARY_OP_EXTEND_r22 738 -#define _GUARD_CALLABLE_ISINSTANCE_r03 739 -#define _GUARD_CALLABLE_ISINSTANCE_r13 740 -#define _GUARD_CALLABLE_ISINSTANCE_r23 741 -#define _GUARD_CALLABLE_ISINSTANCE_r33 742 -#define _GUARD_CALLABLE_LEN_r03 743 -#define _GUARD_CALLABLE_LEN_r13 744 -#define _GUARD_CALLABLE_LEN_r23 745 -#define _GUARD_CALLABLE_LEN_r33 746 -#define _GUARD_CALLABLE_LIST_APPEND_r03 747 -#define _GUARD_CALLABLE_LIST_APPEND_r13 748 -#define _GUARD_CALLABLE_LIST_APPEND_r23 749 -#define _GUARD_CALLABLE_LIST_APPEND_r33 750 -#define _GUARD_CALLABLE_STR_1_r03 751 -#define _GUARD_CALLABLE_STR_1_r13 752 -#define _GUARD_CALLABLE_STR_1_r23 753 -#define _GUARD_CALLABLE_STR_1_r33 754 -#define _GUARD_CALLABLE_TUPLE_1_r03 755 -#define _GUARD_CALLABLE_TUPLE_1_r13 756 -#define _GUARD_CALLABLE_TUPLE_1_r23 757 -#define _GUARD_CALLABLE_TUPLE_1_r33 758 -#define _GUARD_CALLABLE_TYPE_1_r03 759 -#define _GUARD_CALLABLE_TYPE_1_r13 760 -#define _GUARD_CALLABLE_TYPE_1_r23 761 -#define _GUARD_CALLABLE_TYPE_1_r33 762 -#define _GUARD_DORV_NO_DICT_r01 763 -#define _GUARD_DORV_NO_DICT_r11 764 -#define _GUARD_DORV_NO_DICT_r22 765 -#define _GUARD_DORV_NO_DICT_r33 766 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 767 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 768 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 769 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 770 -#define _GUARD_GLOBALS_VERSION_r00 771 -#define _GUARD_GLOBALS_VERSION_r11 772 -#define _GUARD_GLOBALS_VERSION_r22 773 -#define _GUARD_GLOBALS_VERSION_r33 774 -#define _GUARD_IP_RETURN_GENERATOR_r00 775 -#define _GUARD_IP_RETURN_GENERATOR_r11 776 -#define _GUARD_IP_RETURN_GENERATOR_r22 777 -#define _GUARD_IP_RETURN_GENERATOR_r33 778 -#define _GUARD_IP_RETURN_VALUE_r00 779 -#define _GUARD_IP_RETURN_VALUE_r11 780 -#define _GUARD_IP_RETURN_VALUE_r22 781 -#define _GUARD_IP_RETURN_VALUE_r33 782 -#define _GUARD_IP_YIELD_VALUE_r00 783 -#define _GUARD_IP_YIELD_VALUE_r11 784 -#define _GUARD_IP_YIELD_VALUE_r22 785 -#define _GUARD_IP_YIELD_VALUE_r33 786 -#define _GUARD_IP__PUSH_FRAME_r00 787 -#define _GUARD_IP__PUSH_FRAME_r11 788 -#define _GUARD_IP__PUSH_FRAME_r22 789 -#define _GUARD_IP__PUSH_FRAME_r33 790 -#define _GUARD_IS_FALSE_POP_r00 791 -#define _GUARD_IS_FALSE_POP_r10 792 -#define _GUARD_IS_FALSE_POP_r21 793 -#define _GUARD_IS_FALSE_POP_r32 794 -#define _GUARD_IS_NONE_POP_r00 795 -#define _GUARD_IS_NONE_POP_r10 796 -#define _GUARD_IS_NONE_POP_r21 797 -#define _GUARD_IS_NONE_POP_r32 798 -#define _GUARD_IS_NOT_NONE_POP_r10 799 -#define _GUARD_IS_TRUE_POP_r00 800 -#define _GUARD_IS_TRUE_POP_r10 801 -#define _GUARD_IS_TRUE_POP_r21 802 -#define _GUARD_IS_TRUE_POP_r32 803 -#define _GUARD_KEYS_VERSION_r01 804 -#define _GUARD_KEYS_VERSION_r11 805 -#define _GUARD_KEYS_VERSION_r22 806 -#define _GUARD_KEYS_VERSION_r33 807 -#define _GUARD_NOS_DICT_r02 808 -#define _GUARD_NOS_DICT_r12 809 -#define _GUARD_NOS_DICT_r22 810 -#define _GUARD_NOS_DICT_r33 811 -#define _GUARD_NOS_FLOAT_r02 812 -#define _GUARD_NOS_FLOAT_r12 813 -#define _GUARD_NOS_FLOAT_r22 814 -#define _GUARD_NOS_FLOAT_r33 815 -#define _GUARD_NOS_INT_r02 816 -#define _GUARD_NOS_INT_r12 817 -#define _GUARD_NOS_INT_r22 818 -#define _GUARD_NOS_INT_r33 819 -#define _GUARD_NOS_LIST_r02 820 -#define _GUARD_NOS_LIST_r12 821 -#define _GUARD_NOS_LIST_r22 822 -#define _GUARD_NOS_LIST_r33 823 -#define _GUARD_NOS_NOT_NULL_r02 824 -#define _GUARD_NOS_NOT_NULL_r12 825 -#define _GUARD_NOS_NOT_NULL_r22 826 -#define _GUARD_NOS_NOT_NULL_r33 827 -#define _GUARD_NOS_NULL_r02 828 -#define _GUARD_NOS_NULL_r12 829 -#define _GUARD_NOS_NULL_r22 830 -#define _GUARD_NOS_NULL_r33 831 -#define _GUARD_NOS_OVERFLOWED_r02 832 -#define _GUARD_NOS_OVERFLOWED_r12 833 -#define _GUARD_NOS_OVERFLOWED_r22 834 -#define _GUARD_NOS_OVERFLOWED_r33 835 -#define _GUARD_NOS_TUPLE_r02 836 -#define _GUARD_NOS_TUPLE_r12 837 -#define _GUARD_NOS_TUPLE_r22 838 -#define _GUARD_NOS_TUPLE_r33 839 -#define _GUARD_NOS_UNICODE_r02 840 -#define _GUARD_NOS_UNICODE_r12 841 -#define _GUARD_NOS_UNICODE_r22 842 -#define _GUARD_NOS_UNICODE_r33 843 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 844 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 845 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 846 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 847 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 848 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 849 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 850 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 851 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 852 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 853 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 854 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 855 -#define _GUARD_THIRD_NULL_r03 856 -#define _GUARD_THIRD_NULL_r13 857 -#define _GUARD_THIRD_NULL_r23 858 -#define _GUARD_THIRD_NULL_r33 859 -#define _GUARD_TOS_ANY_SET_r01 860 -#define _GUARD_TOS_ANY_SET_r11 861 -#define _GUARD_TOS_ANY_SET_r22 862 -#define _GUARD_TOS_ANY_SET_r33 863 -#define _GUARD_TOS_DICT_r01 864 -#define _GUARD_TOS_DICT_r11 865 -#define _GUARD_TOS_DICT_r22 866 -#define _GUARD_TOS_DICT_r33 867 -#define _GUARD_TOS_FLOAT_r01 868 -#define _GUARD_TOS_FLOAT_r11 869 -#define _GUARD_TOS_FLOAT_r22 870 -#define _GUARD_TOS_FLOAT_r33 871 -#define _GUARD_TOS_INT_r01 872 -#define _GUARD_TOS_INT_r11 873 -#define _GUARD_TOS_INT_r22 874 -#define _GUARD_TOS_INT_r33 875 -#define _GUARD_TOS_LIST_r01 876 -#define _GUARD_TOS_LIST_r11 877 -#define _GUARD_TOS_LIST_r22 878 -#define _GUARD_TOS_LIST_r33 879 -#define _GUARD_TOS_OVERFLOWED_r01 880 -#define _GUARD_TOS_OVERFLOWED_r11 881 -#define _GUARD_TOS_OVERFLOWED_r22 882 -#define _GUARD_TOS_OVERFLOWED_r33 883 -#define _GUARD_TOS_SLICE_r01 884 -#define _GUARD_TOS_SLICE_r11 885 -#define _GUARD_TOS_SLICE_r22 886 -#define _GUARD_TOS_SLICE_r33 887 -#define _GUARD_TOS_TUPLE_r01 888 -#define _GUARD_TOS_TUPLE_r11 889 -#define _GUARD_TOS_TUPLE_r22 890 -#define _GUARD_TOS_TUPLE_r33 891 -#define _GUARD_TOS_UNICODE_r01 892 -#define _GUARD_TOS_UNICODE_r11 893 -#define _GUARD_TOS_UNICODE_r22 894 -#define _GUARD_TOS_UNICODE_r33 895 -#define _GUARD_TYPE_VERSION_r01 896 -#define _GUARD_TYPE_VERSION_r11 897 -#define _GUARD_TYPE_VERSION_r22 898 -#define _GUARD_TYPE_VERSION_r33 899 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 900 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 901 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 902 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 903 -#define _HANDLE_PENDING_AND_DEOPT_r00 904 -#define _HANDLE_PENDING_AND_DEOPT_r10 905 -#define _HANDLE_PENDING_AND_DEOPT_r20 906 -#define _HANDLE_PENDING_AND_DEOPT_r30 907 -#define _IMPORT_FROM_r12 908 -#define _IMPORT_NAME_r21 909 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 910 -#define _INIT_CALL_PY_EXACT_ARGS_r01 911 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 912 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 913 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 914 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 915 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 916 -#define _INSERT_NULL_r10 917 -#define _INSTRUMENTED_FOR_ITER_r23 918 -#define _INSTRUMENTED_INSTRUCTION_r00 919 -#define _INSTRUMENTED_JUMP_FORWARD_r00 920 -#define _INSTRUMENTED_JUMP_FORWARD_r11 921 -#define _INSTRUMENTED_JUMP_FORWARD_r22 922 -#define _INSTRUMENTED_JUMP_FORWARD_r33 923 -#define _INSTRUMENTED_LINE_r00 924 -#define _INSTRUMENTED_NOT_TAKEN_r00 925 -#define _INSTRUMENTED_NOT_TAKEN_r11 926 -#define _INSTRUMENTED_NOT_TAKEN_r22 927 -#define _INSTRUMENTED_NOT_TAKEN_r33 928 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 929 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 930 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 931 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 932 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 933 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 934 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 935 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 936 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 937 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 938 -#define _IS_NONE_r11 939 -#define _IS_OP_r21 940 -#define _ITER_CHECK_LIST_r02 941 -#define _ITER_CHECK_LIST_r12 942 -#define _ITER_CHECK_LIST_r22 943 -#define _ITER_CHECK_LIST_r33 944 -#define _ITER_CHECK_RANGE_r02 945 -#define _ITER_CHECK_RANGE_r12 946 -#define _ITER_CHECK_RANGE_r22 947 -#define _ITER_CHECK_RANGE_r33 948 -#define _ITER_CHECK_TUPLE_r02 949 -#define _ITER_CHECK_TUPLE_r12 950 -#define _ITER_CHECK_TUPLE_r22 951 -#define _ITER_CHECK_TUPLE_r33 952 -#define _ITER_JUMP_LIST_r02 953 -#define _ITER_JUMP_LIST_r12 954 -#define _ITER_JUMP_LIST_r22 955 -#define _ITER_JUMP_LIST_r33 956 -#define _ITER_JUMP_RANGE_r02 957 -#define _ITER_JUMP_RANGE_r12 958 -#define _ITER_JUMP_RANGE_r22 959 -#define _ITER_JUMP_RANGE_r33 960 -#define _ITER_JUMP_TUPLE_r02 961 -#define _ITER_JUMP_TUPLE_r12 962 -#define _ITER_JUMP_TUPLE_r22 963 -#define _ITER_JUMP_TUPLE_r33 964 -#define _ITER_NEXT_LIST_r23 965 -#define _ITER_NEXT_LIST_TIER_TWO_r23 966 -#define _ITER_NEXT_RANGE_r03 967 -#define _ITER_NEXT_RANGE_r13 968 -#define _ITER_NEXT_RANGE_r23 969 -#define _ITER_NEXT_TUPLE_r03 970 -#define _ITER_NEXT_TUPLE_r13 971 -#define _ITER_NEXT_TUPLE_r23 972 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 973 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 974 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 975 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 976 -#define _JUMP_TO_TOP_r00 977 -#define _LIST_APPEND_r10 978 -#define _LIST_EXTEND_r10 979 -#define _LOAD_ATTR_r10 980 -#define _LOAD_ATTR_CLASS_r11 981 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 982 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 983 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 984 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 985 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 986 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 987 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 988 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 989 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 990 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 991 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 992 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 993 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 994 -#define _LOAD_ATTR_MODULE_r11 995 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 996 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 997 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 998 -#define _LOAD_ATTR_SLOT_r11 999 -#define _LOAD_ATTR_WITH_HINT_r11 1000 -#define _LOAD_BUILD_CLASS_r01 1001 -#define _LOAD_BYTECODE_r00 1002 -#define _LOAD_COMMON_CONSTANT_r01 1003 -#define _LOAD_COMMON_CONSTANT_r12 1004 -#define _LOAD_COMMON_CONSTANT_r23 1005 -#define _LOAD_CONST_r01 1006 -#define _LOAD_CONST_r12 1007 -#define _LOAD_CONST_r23 1008 -#define _LOAD_CONST_INLINE_r01 1009 -#define _LOAD_CONST_INLINE_r12 1010 -#define _LOAD_CONST_INLINE_r23 1011 -#define _LOAD_CONST_INLINE_BORROW_r01 1012 -#define _LOAD_CONST_INLINE_BORROW_r12 1013 -#define _LOAD_CONST_INLINE_BORROW_r23 1014 -#define _LOAD_CONST_UNDER_INLINE_r02 1015 -#define _LOAD_CONST_UNDER_INLINE_r12 1016 -#define _LOAD_CONST_UNDER_INLINE_r23 1017 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1018 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1019 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1020 -#define _LOAD_DEREF_r01 1021 -#define _LOAD_FAST_r01 1022 -#define _LOAD_FAST_r12 1023 -#define _LOAD_FAST_r23 1024 -#define _LOAD_FAST_0_r01 1025 -#define _LOAD_FAST_0_r12 1026 -#define _LOAD_FAST_0_r23 1027 -#define _LOAD_FAST_1_r01 1028 -#define _LOAD_FAST_1_r12 1029 -#define _LOAD_FAST_1_r23 1030 -#define _LOAD_FAST_2_r01 1031 -#define _LOAD_FAST_2_r12 1032 -#define _LOAD_FAST_2_r23 1033 -#define _LOAD_FAST_3_r01 1034 -#define _LOAD_FAST_3_r12 1035 -#define _LOAD_FAST_3_r23 1036 -#define _LOAD_FAST_4_r01 1037 -#define _LOAD_FAST_4_r12 1038 -#define _LOAD_FAST_4_r23 1039 -#define _LOAD_FAST_5_r01 1040 -#define _LOAD_FAST_5_r12 1041 -#define _LOAD_FAST_5_r23 1042 -#define _LOAD_FAST_6_r01 1043 -#define _LOAD_FAST_6_r12 1044 -#define _LOAD_FAST_6_r23 1045 -#define _LOAD_FAST_7_r01 1046 -#define _LOAD_FAST_7_r12 1047 -#define _LOAD_FAST_7_r23 1048 -#define _LOAD_FAST_AND_CLEAR_r01 1049 -#define _LOAD_FAST_AND_CLEAR_r12 1050 -#define _LOAD_FAST_AND_CLEAR_r23 1051 -#define _LOAD_FAST_BORROW_r01 1052 -#define _LOAD_FAST_BORROW_r12 1053 -#define _LOAD_FAST_BORROW_r23 1054 -#define _LOAD_FAST_BORROW_0_r01 1055 -#define _LOAD_FAST_BORROW_0_r12 1056 -#define _LOAD_FAST_BORROW_0_r23 1057 -#define _LOAD_FAST_BORROW_1_r01 1058 -#define _LOAD_FAST_BORROW_1_r12 1059 -#define _LOAD_FAST_BORROW_1_r23 1060 -#define _LOAD_FAST_BORROW_2_r01 1061 -#define _LOAD_FAST_BORROW_2_r12 1062 -#define _LOAD_FAST_BORROW_2_r23 1063 -#define _LOAD_FAST_BORROW_3_r01 1064 -#define _LOAD_FAST_BORROW_3_r12 1065 -#define _LOAD_FAST_BORROW_3_r23 1066 -#define _LOAD_FAST_BORROW_4_r01 1067 -#define _LOAD_FAST_BORROW_4_r12 1068 -#define _LOAD_FAST_BORROW_4_r23 1069 -#define _LOAD_FAST_BORROW_5_r01 1070 -#define _LOAD_FAST_BORROW_5_r12 1071 -#define _LOAD_FAST_BORROW_5_r23 1072 -#define _LOAD_FAST_BORROW_6_r01 1073 -#define _LOAD_FAST_BORROW_6_r12 1074 -#define _LOAD_FAST_BORROW_6_r23 1075 -#define _LOAD_FAST_BORROW_7_r01 1076 -#define _LOAD_FAST_BORROW_7_r12 1077 -#define _LOAD_FAST_BORROW_7_r23 1078 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1079 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1080 -#define _LOAD_FAST_CHECK_r01 1081 -#define _LOAD_FAST_CHECK_r12 1082 -#define _LOAD_FAST_CHECK_r23 1083 -#define _LOAD_FAST_LOAD_FAST_r02 1084 -#define _LOAD_FAST_LOAD_FAST_r13 1085 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1086 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1087 -#define _LOAD_GLOBAL_r00 1088 -#define _LOAD_GLOBAL_BUILTINS_r01 1089 -#define _LOAD_GLOBAL_MODULE_r01 1090 -#define _LOAD_LOCALS_r01 1091 -#define _LOAD_LOCALS_r12 1092 -#define _LOAD_LOCALS_r23 1093 -#define _LOAD_NAME_r01 1094 -#define _LOAD_SMALL_INT_r01 1095 -#define _LOAD_SMALL_INT_r12 1096 -#define _LOAD_SMALL_INT_r23 1097 -#define _LOAD_SMALL_INT_0_r01 1098 -#define _LOAD_SMALL_INT_0_r12 1099 -#define _LOAD_SMALL_INT_0_r23 1100 -#define _LOAD_SMALL_INT_1_r01 1101 -#define _LOAD_SMALL_INT_1_r12 1102 -#define _LOAD_SMALL_INT_1_r23 1103 -#define _LOAD_SMALL_INT_2_r01 1104 -#define _LOAD_SMALL_INT_2_r12 1105 -#define _LOAD_SMALL_INT_2_r23 1106 -#define _LOAD_SMALL_INT_3_r01 1107 -#define _LOAD_SMALL_INT_3_r12 1108 -#define _LOAD_SMALL_INT_3_r23 1109 -#define _LOAD_SPECIAL_r00 1110 -#define _LOAD_SUPER_ATTR_ATTR_r31 1111 -#define _LOAD_SUPER_ATTR_METHOD_r32 1112 -#define _MAKE_CALLARGS_A_TUPLE_r33 1113 -#define _MAKE_CELL_r00 1114 -#define _MAKE_FUNCTION_r11 1115 -#define _MAKE_WARM_r00 1116 -#define _MAKE_WARM_r11 1117 -#define _MAKE_WARM_r22 1118 -#define _MAKE_WARM_r33 1119 -#define _MAP_ADD_r20 1120 -#define _MATCH_CLASS_r31 1121 -#define _MATCH_KEYS_r23 1122 -#define _MATCH_MAPPING_r02 1123 -#define _MATCH_MAPPING_r12 1124 -#define _MATCH_MAPPING_r23 1125 -#define _MATCH_SEQUENCE_r02 1126 -#define _MATCH_SEQUENCE_r12 1127 -#define _MATCH_SEQUENCE_r23 1128 -#define _MAYBE_EXPAND_METHOD_r00 1129 -#define _MAYBE_EXPAND_METHOD_KW_r11 1130 -#define _MONITOR_CALL_r00 1131 -#define _MONITOR_CALL_KW_r11 1132 -#define _MONITOR_JUMP_BACKWARD_r00 1133 -#define _MONITOR_JUMP_BACKWARD_r11 1134 -#define _MONITOR_JUMP_BACKWARD_r22 1135 -#define _MONITOR_JUMP_BACKWARD_r33 1136 -#define _MONITOR_RESUME_r00 1137 -#define _NOP_r00 1138 -#define _NOP_r11 1139 -#define _NOP_r22 1140 -#define _NOP_r33 1141 -#define _POP_CALL_r20 1142 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1143 -#define _POP_CALL_ONE_r30 1144 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1145 -#define _POP_CALL_TWO_r30 1146 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1147 -#define _POP_EXCEPT_r10 1148 -#define _POP_ITER_r20 1149 -#define _POP_JUMP_IF_FALSE_r00 1150 -#define _POP_JUMP_IF_FALSE_r10 1151 -#define _POP_JUMP_IF_FALSE_r21 1152 -#define _POP_JUMP_IF_FALSE_r32 1153 -#define _POP_JUMP_IF_TRUE_r00 1154 -#define _POP_JUMP_IF_TRUE_r10 1155 -#define _POP_JUMP_IF_TRUE_r21 1156 -#define _POP_JUMP_IF_TRUE_r32 1157 -#define _POP_TOP_r10 1158 -#define _POP_TOP_FLOAT_r00 1159 -#define _POP_TOP_FLOAT_r10 1160 -#define _POP_TOP_FLOAT_r21 1161 -#define _POP_TOP_FLOAT_r32 1162 -#define _POP_TOP_INT_r00 1163 -#define _POP_TOP_INT_r10 1164 -#define _POP_TOP_INT_r21 1165 -#define _POP_TOP_INT_r32 1166 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1167 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1168 -#define _POP_TOP_NOP_r00 1169 -#define _POP_TOP_NOP_r10 1170 -#define _POP_TOP_NOP_r21 1171 -#define _POP_TOP_NOP_r32 1172 -#define _POP_TOP_UNICODE_r00 1173 -#define _POP_TOP_UNICODE_r10 1174 -#define _POP_TOP_UNICODE_r21 1175 -#define _POP_TOP_UNICODE_r32 1176 -#define _POP_TWO_r20 1177 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1178 -#define _PUSH_EXC_INFO_r02 1179 -#define _PUSH_EXC_INFO_r12 1180 -#define _PUSH_EXC_INFO_r23 1181 -#define _PUSH_FRAME_r10 1182 -#define _PUSH_NULL_r01 1183 -#define _PUSH_NULL_r12 1184 -#define _PUSH_NULL_r23 1185 -#define _PUSH_NULL_CONDITIONAL_r00 1186 -#define _PY_FRAME_GENERAL_r01 1187 -#define _PY_FRAME_KW_r11 1188 -#define _QUICKEN_RESUME_r00 1189 -#define _QUICKEN_RESUME_r11 1190 -#define _QUICKEN_RESUME_r22 1191 -#define _QUICKEN_RESUME_r33 1192 -#define _REPLACE_WITH_TRUE_r11 1193 -#define _RESUME_CHECK_r00 1194 -#define _RESUME_CHECK_r11 1195 -#define _RESUME_CHECK_r22 1196 -#define _RESUME_CHECK_r33 1197 -#define _RETURN_GENERATOR_r01 1198 -#define _RETURN_VALUE_r11 1199 -#define _SAVE_RETURN_OFFSET_r00 1200 -#define _SAVE_RETURN_OFFSET_r11 1201 -#define _SAVE_RETURN_OFFSET_r22 1202 -#define _SAVE_RETURN_OFFSET_r33 1203 -#define _SEND_r22 1204 -#define _SEND_GEN_FRAME_r22 1205 -#define _SETUP_ANNOTATIONS_r00 1206 -#define _SET_ADD_r10 1207 -#define _SET_FUNCTION_ATTRIBUTE_r01 1208 -#define _SET_FUNCTION_ATTRIBUTE_r11 1209 -#define _SET_FUNCTION_ATTRIBUTE_r21 1210 -#define _SET_FUNCTION_ATTRIBUTE_r32 1211 -#define _SET_IP_r00 1212 -#define _SET_IP_r11 1213 -#define _SET_IP_r22 1214 -#define _SET_IP_r33 1215 -#define _SET_UPDATE_r10 1216 -#define _SPILL_OR_RELOAD_r01 1217 -#define _SPILL_OR_RELOAD_r02 1218 -#define _SPILL_OR_RELOAD_r03 1219 -#define _SPILL_OR_RELOAD_r10 1220 -#define _SPILL_OR_RELOAD_r12 1221 -#define _SPILL_OR_RELOAD_r13 1222 -#define _SPILL_OR_RELOAD_r20 1223 -#define _SPILL_OR_RELOAD_r21 1224 -#define _SPILL_OR_RELOAD_r23 1225 -#define _SPILL_OR_RELOAD_r30 1226 -#define _SPILL_OR_RELOAD_r31 1227 -#define _SPILL_OR_RELOAD_r32 1228 -#define _START_EXECUTOR_r00 1229 -#define _STORE_ATTR_r20 1230 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1231 -#define _STORE_ATTR_SLOT_r21 1232 -#define _STORE_ATTR_WITH_HINT_r21 1233 -#define _STORE_DEREF_r10 1234 -#define _STORE_FAST_r10 1235 -#define _STORE_FAST_0_r10 1236 -#define _STORE_FAST_1_r10 1237 -#define _STORE_FAST_2_r10 1238 -#define _STORE_FAST_3_r10 1239 -#define _STORE_FAST_4_r10 1240 -#define _STORE_FAST_5_r10 1241 -#define _STORE_FAST_6_r10 1242 -#define _STORE_FAST_7_r10 1243 -#define _STORE_FAST_LOAD_FAST_r11 1244 -#define _STORE_FAST_STORE_FAST_r20 1245 -#define _STORE_GLOBAL_r10 1246 -#define _STORE_NAME_r10 1247 -#define _STORE_SLICE_r30 1248 -#define _STORE_SUBSCR_r30 1249 -#define _STORE_SUBSCR_DICT_r31 1250 -#define _STORE_SUBSCR_LIST_INT_r32 1251 -#define _SWAP_r11 1252 -#define _SWAP_2_r02 1253 -#define _SWAP_2_r12 1254 -#define _SWAP_2_r22 1255 -#define _SWAP_2_r33 1256 -#define _SWAP_3_r03 1257 -#define _SWAP_3_r13 1258 -#define _SWAP_3_r23 1259 -#define _SWAP_3_r33 1260 -#define _TIER2_RESUME_CHECK_r00 1261 -#define _TIER2_RESUME_CHECK_r11 1262 -#define _TIER2_RESUME_CHECK_r22 1263 -#define _TIER2_RESUME_CHECK_r33 1264 -#define _TO_BOOL_r11 1265 -#define _TO_BOOL_BOOL_r01 1266 -#define _TO_BOOL_BOOL_r11 1267 -#define _TO_BOOL_BOOL_r22 1268 -#define _TO_BOOL_BOOL_r33 1269 -#define _TO_BOOL_INT_r11 1270 -#define _TO_BOOL_LIST_r11 1271 -#define _TO_BOOL_NONE_r01 1272 -#define _TO_BOOL_NONE_r11 1273 -#define _TO_BOOL_NONE_r22 1274 -#define _TO_BOOL_NONE_r33 1275 -#define _TO_BOOL_STR_r11 1276 -#define _TRACE_RECORD_r00 1277 -#define _UNARY_INVERT_r11 1278 -#define _UNARY_NEGATIVE_r11 1279 -#define _UNARY_NOT_r01 1280 -#define _UNARY_NOT_r11 1281 -#define _UNARY_NOT_r22 1282 -#define _UNARY_NOT_r33 1283 -#define _UNPACK_EX_r10 1284 -#define _UNPACK_SEQUENCE_r10 1285 -#define _UNPACK_SEQUENCE_LIST_r10 1286 -#define _UNPACK_SEQUENCE_TUPLE_r10 1287 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1288 -#define _WITH_EXCEPT_START_r33 1289 -#define _YIELD_VALUE_r11 1290 -#define MAX_UOP_REGS_ID 1290 +#define MAX_UOP_ID 554 +#define _BINARY_OP_r21 555 +#define _BINARY_OP_ADD_FLOAT_r03 556 +#define _BINARY_OP_ADD_FLOAT_r13 557 +#define _BINARY_OP_ADD_FLOAT_r23 558 +#define _BINARY_OP_ADD_INT_r03 559 +#define _BINARY_OP_ADD_INT_r13 560 +#define _BINARY_OP_ADD_INT_r23 561 +#define _BINARY_OP_ADD_UNICODE_r03 562 +#define _BINARY_OP_ADD_UNICODE_r13 563 +#define _BINARY_OP_ADD_UNICODE_r23 564 +#define _BINARY_OP_EXTEND_r21 565 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r20 566 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 567 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 568 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 569 +#define _BINARY_OP_MULTIPLY_INT_r03 570 +#define _BINARY_OP_MULTIPLY_INT_r13 571 +#define _BINARY_OP_MULTIPLY_INT_r23 572 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 573 +#define _BINARY_OP_SUBSCR_DICT_r21 574 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 575 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 576 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 577 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 578 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 579 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r21 580 +#define _BINARY_OP_SUBSCR_STR_INT_r23 581 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r21 582 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 583 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 584 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 585 +#define _BINARY_OP_SUBTRACT_INT_r03 586 +#define _BINARY_OP_SUBTRACT_INT_r13 587 +#define _BINARY_OP_SUBTRACT_INT_r23 588 +#define _BINARY_SLICE_r31 589 +#define _BUILD_INTERPOLATION_r01 590 +#define _BUILD_LIST_r01 591 +#define _BUILD_MAP_r01 592 +#define _BUILD_SET_r01 593 +#define _BUILD_SLICE_r01 594 +#define _BUILD_STRING_r01 595 +#define _BUILD_TEMPLATE_r21 596 +#define _BUILD_TUPLE_r01 597 +#define _CALL_BUILTIN_CLASS_r01 598 +#define _CALL_BUILTIN_FAST_r01 599 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r01 600 +#define _CALL_BUILTIN_O_r03 601 +#define _CALL_INTRINSIC_1_r11 602 +#define _CALL_INTRINSIC_2_r21 603 +#define _CALL_ISINSTANCE_r31 604 +#define _CALL_KW_NON_PY_r11 605 +#define _CALL_LEN_r33 606 +#define _CALL_LIST_APPEND_r02 607 +#define _CALL_LIST_APPEND_r12 608 +#define _CALL_LIST_APPEND_r22 609 +#define _CALL_LIST_APPEND_r32 610 +#define _CALL_METHOD_DESCRIPTOR_FAST_r01 611 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r01 612 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r01 613 +#define _CALL_METHOD_DESCRIPTOR_O_r01 614 +#define _CALL_NON_PY_GENERAL_r01 615 +#define _CALL_STR_1_r32 616 +#define _CALL_TUPLE_1_r32 617 +#define _CALL_TYPE_1_r31 618 +#define _CHECK_AND_ALLOCATE_OBJECT_r00 619 +#define _CHECK_ATTR_CLASS_r01 620 +#define _CHECK_ATTR_CLASS_r11 621 +#define _CHECK_ATTR_CLASS_r22 622 +#define _CHECK_ATTR_CLASS_r33 623 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 624 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 625 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 626 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 627 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 628 +#define _CHECK_EG_MATCH_r22 629 +#define _CHECK_EXC_MATCH_r22 630 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 631 +#define _CHECK_FUNCTION_VERSION_r00 632 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 633 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 634 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 635 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 636 +#define _CHECK_FUNCTION_VERSION_KW_r11 637 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 638 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 639 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 640 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 641 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 642 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 643 +#define _CHECK_METHOD_VERSION_r00 644 +#define _CHECK_METHOD_VERSION_KW_r11 645 +#define _CHECK_PEP_523_r00 646 +#define _CHECK_PEP_523_r11 647 +#define _CHECK_PEP_523_r22 648 +#define _CHECK_PEP_523_r33 649 +#define _CHECK_PERIODIC_r00 650 +#define _CHECK_PERIODIC_AT_END_r00 651 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 652 +#define _CHECK_RECURSION_REMAINING_r00 653 +#define _CHECK_RECURSION_REMAINING_r11 654 +#define _CHECK_RECURSION_REMAINING_r22 655 +#define _CHECK_RECURSION_REMAINING_r33 656 +#define _CHECK_STACK_SPACE_r00 657 +#define _CHECK_STACK_SPACE_OPERAND_r00 658 +#define _CHECK_STACK_SPACE_OPERAND_r11 659 +#define _CHECK_STACK_SPACE_OPERAND_r22 660 +#define _CHECK_STACK_SPACE_OPERAND_r33 661 +#define _CHECK_VALIDITY_r00 662 +#define _CHECK_VALIDITY_r11 663 +#define _CHECK_VALIDITY_r22 664 +#define _CHECK_VALIDITY_r33 665 +#define _COLD_DYNAMIC_EXIT_r00 666 +#define _COLD_EXIT_r00 667 +#define _COMPARE_OP_r21 668 +#define _COMPARE_OP_FLOAT_r01 669 +#define _COMPARE_OP_FLOAT_r11 670 +#define _COMPARE_OP_FLOAT_r21 671 +#define _COMPARE_OP_FLOAT_r32 672 +#define _COMPARE_OP_INT_r23 673 +#define _COMPARE_OP_STR_r21 674 +#define _CONTAINS_OP_r21 675 +#define _CONTAINS_OP_DICT_r21 676 +#define _CONTAINS_OP_SET_r21 677 +#define _CONVERT_VALUE_r11 678 +#define _COPY_r01 679 +#define _COPY_1_r02 680 +#define _COPY_1_r12 681 +#define _COPY_1_r23 682 +#define _COPY_2_r03 683 +#define _COPY_2_r13 684 +#define _COPY_2_r23 685 +#define _COPY_3_r03 686 +#define _COPY_3_r13 687 +#define _COPY_3_r23 688 +#define _COPY_3_r33 689 +#define _COPY_FREE_VARS_r00 690 +#define _COPY_FREE_VARS_r11 691 +#define _COPY_FREE_VARS_r22 692 +#define _COPY_FREE_VARS_r33 693 +#define _CREATE_INIT_FRAME_r01 694 +#define _DELETE_ATTR_r10 695 +#define _DELETE_DEREF_r00 696 +#define _DELETE_FAST_r00 697 +#define _DELETE_GLOBAL_r00 698 +#define _DELETE_NAME_r00 699 +#define _DELETE_SUBSCR_r20 700 +#define _DEOPT_r00 701 +#define _DEOPT_r10 702 +#define _DEOPT_r20 703 +#define _DEOPT_r30 704 +#define _DICT_MERGE_r10 705 +#define _DICT_UPDATE_r10 706 +#define _DO_CALL_r01 707 +#define _DO_CALL_FUNCTION_EX_r31 708 +#define _DO_CALL_KW_r11 709 +#define _DYNAMIC_EXIT_r00 710 +#define _DYNAMIC_EXIT_r10 711 +#define _DYNAMIC_EXIT_r20 712 +#define _DYNAMIC_EXIT_r30 713 +#define _END_FOR_r10 714 +#define _END_SEND_r21 715 +#define _ERROR_POP_N_r00 716 +#define _EXIT_INIT_CHECK_r10 717 +#define _EXIT_TRACE_r00 718 +#define _EXIT_TRACE_r10 719 +#define _EXIT_TRACE_r20 720 +#define _EXIT_TRACE_r30 721 +#define _EXPAND_METHOD_r00 722 +#define _EXPAND_METHOD_KW_r11 723 +#define _FATAL_ERROR_r00 724 +#define _FATAL_ERROR_r11 725 +#define _FATAL_ERROR_r22 726 +#define _FATAL_ERROR_r33 727 +#define _FORMAT_SIMPLE_r11 728 +#define _FORMAT_WITH_SPEC_r21 729 +#define _FOR_ITER_r23 730 +#define _FOR_ITER_GEN_FRAME_r23 731 +#define _FOR_ITER_TIER_TWO_r23 732 +#define _GET_AITER_r11 733 +#define _GET_ANEXT_r12 734 +#define _GET_AWAITABLE_r11 735 +#define _GET_ITER_r12 736 +#define _GET_LEN_r12 737 +#define _GET_YIELD_FROM_ITER_r11 738 +#define _GUARD_BINARY_OP_EXTEND_r22 739 +#define _GUARD_CALLABLE_ISINSTANCE_r03 740 +#define _GUARD_CALLABLE_ISINSTANCE_r13 741 +#define _GUARD_CALLABLE_ISINSTANCE_r23 742 +#define _GUARD_CALLABLE_ISINSTANCE_r33 743 +#define _GUARD_CALLABLE_LEN_r03 744 +#define _GUARD_CALLABLE_LEN_r13 745 +#define _GUARD_CALLABLE_LEN_r23 746 +#define _GUARD_CALLABLE_LEN_r33 747 +#define _GUARD_CALLABLE_LIST_APPEND_r03 748 +#define _GUARD_CALLABLE_LIST_APPEND_r13 749 +#define _GUARD_CALLABLE_LIST_APPEND_r23 750 +#define _GUARD_CALLABLE_LIST_APPEND_r33 751 +#define _GUARD_CALLABLE_STR_1_r03 752 +#define _GUARD_CALLABLE_STR_1_r13 753 +#define _GUARD_CALLABLE_STR_1_r23 754 +#define _GUARD_CALLABLE_STR_1_r33 755 +#define _GUARD_CALLABLE_TUPLE_1_r03 756 +#define _GUARD_CALLABLE_TUPLE_1_r13 757 +#define _GUARD_CALLABLE_TUPLE_1_r23 758 +#define _GUARD_CALLABLE_TUPLE_1_r33 759 +#define _GUARD_CALLABLE_TYPE_1_r03 760 +#define _GUARD_CALLABLE_TYPE_1_r13 761 +#define _GUARD_CALLABLE_TYPE_1_r23 762 +#define _GUARD_CALLABLE_TYPE_1_r33 763 +#define _GUARD_DORV_NO_DICT_r01 764 +#define _GUARD_DORV_NO_DICT_r11 765 +#define _GUARD_DORV_NO_DICT_r22 766 +#define _GUARD_DORV_NO_DICT_r33 767 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 768 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 769 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 770 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 771 +#define _GUARD_GLOBALS_VERSION_r00 772 +#define _GUARD_GLOBALS_VERSION_r11 773 +#define _GUARD_GLOBALS_VERSION_r22 774 +#define _GUARD_GLOBALS_VERSION_r33 775 +#define _GUARD_IP_RETURN_GENERATOR_r00 776 +#define _GUARD_IP_RETURN_GENERATOR_r11 777 +#define _GUARD_IP_RETURN_GENERATOR_r22 778 +#define _GUARD_IP_RETURN_GENERATOR_r33 779 +#define _GUARD_IP_RETURN_VALUE_r00 780 +#define _GUARD_IP_RETURN_VALUE_r11 781 +#define _GUARD_IP_RETURN_VALUE_r22 782 +#define _GUARD_IP_RETURN_VALUE_r33 783 +#define _GUARD_IP_YIELD_VALUE_r00 784 +#define _GUARD_IP_YIELD_VALUE_r11 785 +#define _GUARD_IP_YIELD_VALUE_r22 786 +#define _GUARD_IP_YIELD_VALUE_r33 787 +#define _GUARD_IP__PUSH_FRAME_r00 788 +#define _GUARD_IP__PUSH_FRAME_r11 789 +#define _GUARD_IP__PUSH_FRAME_r22 790 +#define _GUARD_IP__PUSH_FRAME_r33 791 +#define _GUARD_IS_FALSE_POP_r00 792 +#define _GUARD_IS_FALSE_POP_r10 793 +#define _GUARD_IS_FALSE_POP_r21 794 +#define _GUARD_IS_FALSE_POP_r32 795 +#define _GUARD_IS_NONE_POP_r00 796 +#define _GUARD_IS_NONE_POP_r10 797 +#define _GUARD_IS_NONE_POP_r21 798 +#define _GUARD_IS_NONE_POP_r32 799 +#define _GUARD_IS_NOT_NONE_POP_r10 800 +#define _GUARD_IS_TRUE_POP_r00 801 +#define _GUARD_IS_TRUE_POP_r10 802 +#define _GUARD_IS_TRUE_POP_r21 803 +#define _GUARD_IS_TRUE_POP_r32 804 +#define _GUARD_KEYS_VERSION_r01 805 +#define _GUARD_KEYS_VERSION_r11 806 +#define _GUARD_KEYS_VERSION_r22 807 +#define _GUARD_KEYS_VERSION_r33 808 +#define _GUARD_NOS_DICT_r02 809 +#define _GUARD_NOS_DICT_r12 810 +#define _GUARD_NOS_DICT_r22 811 +#define _GUARD_NOS_DICT_r33 812 +#define _GUARD_NOS_FLOAT_r02 813 +#define _GUARD_NOS_FLOAT_r12 814 +#define _GUARD_NOS_FLOAT_r22 815 +#define _GUARD_NOS_FLOAT_r33 816 +#define _GUARD_NOS_INT_r02 817 +#define _GUARD_NOS_INT_r12 818 +#define _GUARD_NOS_INT_r22 819 +#define _GUARD_NOS_INT_r33 820 +#define _GUARD_NOS_LIST_r02 821 +#define _GUARD_NOS_LIST_r12 822 +#define _GUARD_NOS_LIST_r22 823 +#define _GUARD_NOS_LIST_r33 824 +#define _GUARD_NOS_NOT_NULL_r02 825 +#define _GUARD_NOS_NOT_NULL_r12 826 +#define _GUARD_NOS_NOT_NULL_r22 827 +#define _GUARD_NOS_NOT_NULL_r33 828 +#define _GUARD_NOS_NULL_r02 829 +#define _GUARD_NOS_NULL_r12 830 +#define _GUARD_NOS_NULL_r22 831 +#define _GUARD_NOS_NULL_r33 832 +#define _GUARD_NOS_OVERFLOWED_r02 833 +#define _GUARD_NOS_OVERFLOWED_r12 834 +#define _GUARD_NOS_OVERFLOWED_r22 835 +#define _GUARD_NOS_OVERFLOWED_r33 836 +#define _GUARD_NOS_TUPLE_r02 837 +#define _GUARD_NOS_TUPLE_r12 838 +#define _GUARD_NOS_TUPLE_r22 839 +#define _GUARD_NOS_TUPLE_r33 840 +#define _GUARD_NOS_UNICODE_r02 841 +#define _GUARD_NOS_UNICODE_r12 842 +#define _GUARD_NOS_UNICODE_r22 843 +#define _GUARD_NOS_UNICODE_r33 844 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 845 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 846 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 847 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 848 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 849 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 850 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 851 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 852 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 853 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 854 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 855 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 856 +#define _GUARD_THIRD_NULL_r03 857 +#define _GUARD_THIRD_NULL_r13 858 +#define _GUARD_THIRD_NULL_r23 859 +#define _GUARD_THIRD_NULL_r33 860 +#define _GUARD_TOS_ANY_SET_r01 861 +#define _GUARD_TOS_ANY_SET_r11 862 +#define _GUARD_TOS_ANY_SET_r22 863 +#define _GUARD_TOS_ANY_SET_r33 864 +#define _GUARD_TOS_DICT_r01 865 +#define _GUARD_TOS_DICT_r11 866 +#define _GUARD_TOS_DICT_r22 867 +#define _GUARD_TOS_DICT_r33 868 +#define _GUARD_TOS_FLOAT_r01 869 +#define _GUARD_TOS_FLOAT_r11 870 +#define _GUARD_TOS_FLOAT_r22 871 +#define _GUARD_TOS_FLOAT_r33 872 +#define _GUARD_TOS_INT_r01 873 +#define _GUARD_TOS_INT_r11 874 +#define _GUARD_TOS_INT_r22 875 +#define _GUARD_TOS_INT_r33 876 +#define _GUARD_TOS_LIST_r01 877 +#define _GUARD_TOS_LIST_r11 878 +#define _GUARD_TOS_LIST_r22 879 +#define _GUARD_TOS_LIST_r33 880 +#define _GUARD_TOS_OVERFLOWED_r01 881 +#define _GUARD_TOS_OVERFLOWED_r11 882 +#define _GUARD_TOS_OVERFLOWED_r22 883 +#define _GUARD_TOS_OVERFLOWED_r33 884 +#define _GUARD_TOS_SLICE_r01 885 +#define _GUARD_TOS_SLICE_r11 886 +#define _GUARD_TOS_SLICE_r22 887 +#define _GUARD_TOS_SLICE_r33 888 +#define _GUARD_TOS_TUPLE_r01 889 +#define _GUARD_TOS_TUPLE_r11 890 +#define _GUARD_TOS_TUPLE_r22 891 +#define _GUARD_TOS_TUPLE_r33 892 +#define _GUARD_TOS_UNICODE_r01 893 +#define _GUARD_TOS_UNICODE_r11 894 +#define _GUARD_TOS_UNICODE_r22 895 +#define _GUARD_TOS_UNICODE_r33 896 +#define _GUARD_TYPE_VERSION_r01 897 +#define _GUARD_TYPE_VERSION_r11 898 +#define _GUARD_TYPE_VERSION_r22 899 +#define _GUARD_TYPE_VERSION_r33 900 +#define _GUARD_TYPE_VERSION_AND_LOCK_r01 901 +#define _GUARD_TYPE_VERSION_AND_LOCK_r11 902 +#define _GUARD_TYPE_VERSION_AND_LOCK_r22 903 +#define _GUARD_TYPE_VERSION_AND_LOCK_r33 904 +#define _HANDLE_PENDING_AND_DEOPT_r00 905 +#define _HANDLE_PENDING_AND_DEOPT_r10 906 +#define _HANDLE_PENDING_AND_DEOPT_r20 907 +#define _HANDLE_PENDING_AND_DEOPT_r30 908 +#define _IMPORT_FROM_r12 909 +#define _IMPORT_NAME_r21 910 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 911 +#define _INIT_CALL_PY_EXACT_ARGS_r01 912 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 913 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 914 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 915 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 916 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 917 +#define _INSERT_NULL_r10 918 +#define _INSTRUMENTED_FOR_ITER_r23 919 +#define _INSTRUMENTED_INSTRUCTION_r00 920 +#define _INSTRUMENTED_JUMP_FORWARD_r00 921 +#define _INSTRUMENTED_JUMP_FORWARD_r11 922 +#define _INSTRUMENTED_JUMP_FORWARD_r22 923 +#define _INSTRUMENTED_JUMP_FORWARD_r33 924 +#define _INSTRUMENTED_LINE_r00 925 +#define _INSTRUMENTED_NOT_TAKEN_r00 926 +#define _INSTRUMENTED_NOT_TAKEN_r11 927 +#define _INSTRUMENTED_NOT_TAKEN_r22 928 +#define _INSTRUMENTED_NOT_TAKEN_r33 929 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 930 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 931 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 932 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 933 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 934 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 935 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 936 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 937 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 938 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 939 +#define _IS_NONE_r11 940 +#define _IS_OP_r21 941 +#define _ITER_CHECK_LIST_r02 942 +#define _ITER_CHECK_LIST_r12 943 +#define _ITER_CHECK_LIST_r22 944 +#define _ITER_CHECK_LIST_r33 945 +#define _ITER_CHECK_RANGE_r02 946 +#define _ITER_CHECK_RANGE_r12 947 +#define _ITER_CHECK_RANGE_r22 948 +#define _ITER_CHECK_RANGE_r33 949 +#define _ITER_CHECK_TUPLE_r02 950 +#define _ITER_CHECK_TUPLE_r12 951 +#define _ITER_CHECK_TUPLE_r22 952 +#define _ITER_CHECK_TUPLE_r33 953 +#define _ITER_JUMP_LIST_r02 954 +#define _ITER_JUMP_LIST_r12 955 +#define _ITER_JUMP_LIST_r22 956 +#define _ITER_JUMP_LIST_r33 957 +#define _ITER_JUMP_RANGE_r02 958 +#define _ITER_JUMP_RANGE_r12 959 +#define _ITER_JUMP_RANGE_r22 960 +#define _ITER_JUMP_RANGE_r33 961 +#define _ITER_JUMP_TUPLE_r02 962 +#define _ITER_JUMP_TUPLE_r12 963 +#define _ITER_JUMP_TUPLE_r22 964 +#define _ITER_JUMP_TUPLE_r33 965 +#define _ITER_NEXT_LIST_r23 966 +#define _ITER_NEXT_LIST_TIER_TWO_r23 967 +#define _ITER_NEXT_RANGE_r03 968 +#define _ITER_NEXT_RANGE_r13 969 +#define _ITER_NEXT_RANGE_r23 970 +#define _ITER_NEXT_TUPLE_r03 971 +#define _ITER_NEXT_TUPLE_r13 972 +#define _ITER_NEXT_TUPLE_r23 973 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 974 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 975 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 976 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 977 +#define _JUMP_TO_TOP_r00 978 +#define _LIST_APPEND_r10 979 +#define _LIST_EXTEND_r10 980 +#define _LOAD_ATTR_r10 981 +#define _LOAD_ATTR_CLASS_r11 982 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 983 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 984 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 985 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 986 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 987 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 988 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 989 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 990 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 991 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 992 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 993 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 994 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 995 +#define _LOAD_ATTR_MODULE_r11 996 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 997 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 998 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 999 +#define _LOAD_ATTR_SLOT_r11 1000 +#define _LOAD_ATTR_WITH_HINT_r11 1001 +#define _LOAD_BUILD_CLASS_r01 1002 +#define _LOAD_BYTECODE_r00 1003 +#define _LOAD_COMMON_CONSTANT_r01 1004 +#define _LOAD_COMMON_CONSTANT_r12 1005 +#define _LOAD_COMMON_CONSTANT_r23 1006 +#define _LOAD_CONST_r01 1007 +#define _LOAD_CONST_r12 1008 +#define _LOAD_CONST_r23 1009 +#define _LOAD_CONST_INLINE_r01 1010 +#define _LOAD_CONST_INLINE_r12 1011 +#define _LOAD_CONST_INLINE_r23 1012 +#define _LOAD_CONST_INLINE_BORROW_r01 1013 +#define _LOAD_CONST_INLINE_BORROW_r12 1014 +#define _LOAD_CONST_INLINE_BORROW_r23 1015 +#define _LOAD_CONST_UNDER_INLINE_r02 1016 +#define _LOAD_CONST_UNDER_INLINE_r12 1017 +#define _LOAD_CONST_UNDER_INLINE_r23 1018 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1019 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1020 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1021 +#define _LOAD_DEREF_r01 1022 +#define _LOAD_FAST_r01 1023 +#define _LOAD_FAST_r12 1024 +#define _LOAD_FAST_r23 1025 +#define _LOAD_FAST_0_r01 1026 +#define _LOAD_FAST_0_r12 1027 +#define _LOAD_FAST_0_r23 1028 +#define _LOAD_FAST_1_r01 1029 +#define _LOAD_FAST_1_r12 1030 +#define _LOAD_FAST_1_r23 1031 +#define _LOAD_FAST_2_r01 1032 +#define _LOAD_FAST_2_r12 1033 +#define _LOAD_FAST_2_r23 1034 +#define _LOAD_FAST_3_r01 1035 +#define _LOAD_FAST_3_r12 1036 +#define _LOAD_FAST_3_r23 1037 +#define _LOAD_FAST_4_r01 1038 +#define _LOAD_FAST_4_r12 1039 +#define _LOAD_FAST_4_r23 1040 +#define _LOAD_FAST_5_r01 1041 +#define _LOAD_FAST_5_r12 1042 +#define _LOAD_FAST_5_r23 1043 +#define _LOAD_FAST_6_r01 1044 +#define _LOAD_FAST_6_r12 1045 +#define _LOAD_FAST_6_r23 1046 +#define _LOAD_FAST_7_r01 1047 +#define _LOAD_FAST_7_r12 1048 +#define _LOAD_FAST_7_r23 1049 +#define _LOAD_FAST_AND_CLEAR_r01 1050 +#define _LOAD_FAST_AND_CLEAR_r12 1051 +#define _LOAD_FAST_AND_CLEAR_r23 1052 +#define _LOAD_FAST_BORROW_r01 1053 +#define _LOAD_FAST_BORROW_r12 1054 +#define _LOAD_FAST_BORROW_r23 1055 +#define _LOAD_FAST_BORROW_0_r01 1056 +#define _LOAD_FAST_BORROW_0_r12 1057 +#define _LOAD_FAST_BORROW_0_r23 1058 +#define _LOAD_FAST_BORROW_1_r01 1059 +#define _LOAD_FAST_BORROW_1_r12 1060 +#define _LOAD_FAST_BORROW_1_r23 1061 +#define _LOAD_FAST_BORROW_2_r01 1062 +#define _LOAD_FAST_BORROW_2_r12 1063 +#define _LOAD_FAST_BORROW_2_r23 1064 +#define _LOAD_FAST_BORROW_3_r01 1065 +#define _LOAD_FAST_BORROW_3_r12 1066 +#define _LOAD_FAST_BORROW_3_r23 1067 +#define _LOAD_FAST_BORROW_4_r01 1068 +#define _LOAD_FAST_BORROW_4_r12 1069 +#define _LOAD_FAST_BORROW_4_r23 1070 +#define _LOAD_FAST_BORROW_5_r01 1071 +#define _LOAD_FAST_BORROW_5_r12 1072 +#define _LOAD_FAST_BORROW_5_r23 1073 +#define _LOAD_FAST_BORROW_6_r01 1074 +#define _LOAD_FAST_BORROW_6_r12 1075 +#define _LOAD_FAST_BORROW_6_r23 1076 +#define _LOAD_FAST_BORROW_7_r01 1077 +#define _LOAD_FAST_BORROW_7_r12 1078 +#define _LOAD_FAST_BORROW_7_r23 1079 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1080 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1081 +#define _LOAD_FAST_CHECK_r01 1082 +#define _LOAD_FAST_CHECK_r12 1083 +#define _LOAD_FAST_CHECK_r23 1084 +#define _LOAD_FAST_LOAD_FAST_r02 1085 +#define _LOAD_FAST_LOAD_FAST_r13 1086 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1087 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1088 +#define _LOAD_GLOBAL_r00 1089 +#define _LOAD_GLOBAL_BUILTINS_r01 1090 +#define _LOAD_GLOBAL_MODULE_r01 1091 +#define _LOAD_LOCALS_r01 1092 +#define _LOAD_LOCALS_r12 1093 +#define _LOAD_LOCALS_r23 1094 +#define _LOAD_NAME_r01 1095 +#define _LOAD_SMALL_INT_r01 1096 +#define _LOAD_SMALL_INT_r12 1097 +#define _LOAD_SMALL_INT_r23 1098 +#define _LOAD_SMALL_INT_0_r01 1099 +#define _LOAD_SMALL_INT_0_r12 1100 +#define _LOAD_SMALL_INT_0_r23 1101 +#define _LOAD_SMALL_INT_1_r01 1102 +#define _LOAD_SMALL_INT_1_r12 1103 +#define _LOAD_SMALL_INT_1_r23 1104 +#define _LOAD_SMALL_INT_2_r01 1105 +#define _LOAD_SMALL_INT_2_r12 1106 +#define _LOAD_SMALL_INT_2_r23 1107 +#define _LOAD_SMALL_INT_3_r01 1108 +#define _LOAD_SMALL_INT_3_r12 1109 +#define _LOAD_SMALL_INT_3_r23 1110 +#define _LOAD_SPECIAL_r00 1111 +#define _LOAD_SUPER_ATTR_ATTR_r31 1112 +#define _LOAD_SUPER_ATTR_METHOD_r32 1113 +#define _MAKE_CALLARGS_A_TUPLE_r33 1114 +#define _MAKE_CELL_r00 1115 +#define _MAKE_FUNCTION_r11 1116 +#define _MAKE_WARM_r00 1117 +#define _MAKE_WARM_r11 1118 +#define _MAKE_WARM_r22 1119 +#define _MAKE_WARM_r33 1120 +#define _MAP_ADD_r20 1121 +#define _MATCH_CLASS_r31 1122 +#define _MATCH_KEYS_r23 1123 +#define _MATCH_MAPPING_r02 1124 +#define _MATCH_MAPPING_r12 1125 +#define _MATCH_MAPPING_r23 1126 +#define _MATCH_SEQUENCE_r02 1127 +#define _MATCH_SEQUENCE_r12 1128 +#define _MATCH_SEQUENCE_r23 1129 +#define _MAYBE_EXPAND_METHOD_r00 1130 +#define _MAYBE_EXPAND_METHOD_KW_r11 1131 +#define _MONITOR_CALL_r00 1132 +#define _MONITOR_CALL_KW_r11 1133 +#define _MONITOR_JUMP_BACKWARD_r00 1134 +#define _MONITOR_JUMP_BACKWARD_r11 1135 +#define _MONITOR_JUMP_BACKWARD_r22 1136 +#define _MONITOR_JUMP_BACKWARD_r33 1137 +#define _MONITOR_RESUME_r00 1138 +#define _NOP_r00 1139 +#define _NOP_r11 1140 +#define _NOP_r22 1141 +#define _NOP_r33 1142 +#define _POP_CALL_r20 1143 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1144 +#define _POP_CALL_ONE_r30 1145 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1146 +#define _POP_CALL_TWO_r30 1147 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1148 +#define _POP_EXCEPT_r10 1149 +#define _POP_ITER_r20 1150 +#define _POP_JUMP_IF_FALSE_r00 1151 +#define _POP_JUMP_IF_FALSE_r10 1152 +#define _POP_JUMP_IF_FALSE_r21 1153 +#define _POP_JUMP_IF_FALSE_r32 1154 +#define _POP_JUMP_IF_TRUE_r00 1155 +#define _POP_JUMP_IF_TRUE_r10 1156 +#define _POP_JUMP_IF_TRUE_r21 1157 +#define _POP_JUMP_IF_TRUE_r32 1158 +#define _POP_TOP_r10 1159 +#define _POP_TOP_FLOAT_r00 1160 +#define _POP_TOP_FLOAT_r10 1161 +#define _POP_TOP_FLOAT_r21 1162 +#define _POP_TOP_FLOAT_r32 1163 +#define _POP_TOP_INT_r00 1164 +#define _POP_TOP_INT_r10 1165 +#define _POP_TOP_INT_r21 1166 +#define _POP_TOP_INT_r32 1167 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1168 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1169 +#define _POP_TOP_NOP_r00 1170 +#define _POP_TOP_NOP_r10 1171 +#define _POP_TOP_NOP_r21 1172 +#define _POP_TOP_NOP_r32 1173 +#define _POP_TOP_UNICODE_r00 1174 +#define _POP_TOP_UNICODE_r10 1175 +#define _POP_TOP_UNICODE_r21 1176 +#define _POP_TOP_UNICODE_r32 1177 +#define _POP_TWO_r20 1178 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1179 +#define _PUSH_EXC_INFO_r02 1180 +#define _PUSH_EXC_INFO_r12 1181 +#define _PUSH_EXC_INFO_r23 1182 +#define _PUSH_FRAME_r10 1183 +#define _PUSH_NULL_r01 1184 +#define _PUSH_NULL_r12 1185 +#define _PUSH_NULL_r23 1186 +#define _PUSH_NULL_CONDITIONAL_r00 1187 +#define _PY_FRAME_GENERAL_r01 1188 +#define _PY_FRAME_KW_r11 1189 +#define _QUICKEN_RESUME_r00 1190 +#define _QUICKEN_RESUME_r11 1191 +#define _QUICKEN_RESUME_r22 1192 +#define _QUICKEN_RESUME_r33 1193 +#define _REPLACE_WITH_TRUE_r11 1194 +#define _RESUME_CHECK_r00 1195 +#define _RESUME_CHECK_r11 1196 +#define _RESUME_CHECK_r22 1197 +#define _RESUME_CHECK_r33 1198 +#define _RETURN_GENERATOR_r01 1199 +#define _RETURN_VALUE_r11 1200 +#define _SAVE_RETURN_OFFSET_r00 1201 +#define _SAVE_RETURN_OFFSET_r11 1202 +#define _SAVE_RETURN_OFFSET_r22 1203 +#define _SAVE_RETURN_OFFSET_r33 1204 +#define _SEND_r22 1205 +#define _SEND_GEN_FRAME_r22 1206 +#define _SETUP_ANNOTATIONS_r00 1207 +#define _SET_ADD_r10 1208 +#define _SET_FUNCTION_ATTRIBUTE_r01 1209 +#define _SET_FUNCTION_ATTRIBUTE_r11 1210 +#define _SET_FUNCTION_ATTRIBUTE_r21 1211 +#define _SET_FUNCTION_ATTRIBUTE_r32 1212 +#define _SET_IP_r00 1213 +#define _SET_IP_r11 1214 +#define _SET_IP_r22 1215 +#define _SET_IP_r33 1216 +#define _SET_UPDATE_r10 1217 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1218 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1219 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1220 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1221 +#define _SPILL_OR_RELOAD_r01 1222 +#define _SPILL_OR_RELOAD_r02 1223 +#define _SPILL_OR_RELOAD_r03 1224 +#define _SPILL_OR_RELOAD_r10 1225 +#define _SPILL_OR_RELOAD_r12 1226 +#define _SPILL_OR_RELOAD_r13 1227 +#define _SPILL_OR_RELOAD_r20 1228 +#define _SPILL_OR_RELOAD_r21 1229 +#define _SPILL_OR_RELOAD_r23 1230 +#define _SPILL_OR_RELOAD_r30 1231 +#define _SPILL_OR_RELOAD_r31 1232 +#define _SPILL_OR_RELOAD_r32 1233 +#define _START_EXECUTOR_r00 1234 +#define _STORE_ATTR_r20 1235 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1236 +#define _STORE_ATTR_SLOT_r21 1237 +#define _STORE_ATTR_WITH_HINT_r21 1238 +#define _STORE_DEREF_r10 1239 +#define _STORE_FAST_r10 1240 +#define _STORE_FAST_0_r10 1241 +#define _STORE_FAST_1_r10 1242 +#define _STORE_FAST_2_r10 1243 +#define _STORE_FAST_3_r10 1244 +#define _STORE_FAST_4_r10 1245 +#define _STORE_FAST_5_r10 1246 +#define _STORE_FAST_6_r10 1247 +#define _STORE_FAST_7_r10 1248 +#define _STORE_FAST_LOAD_FAST_r11 1249 +#define _STORE_FAST_STORE_FAST_r20 1250 +#define _STORE_GLOBAL_r10 1251 +#define _STORE_NAME_r10 1252 +#define _STORE_SLICE_r30 1253 +#define _STORE_SUBSCR_r30 1254 +#define _STORE_SUBSCR_DICT_r31 1255 +#define _STORE_SUBSCR_LIST_INT_r32 1256 +#define _SWAP_r11 1257 +#define _SWAP_2_r02 1258 +#define _SWAP_2_r12 1259 +#define _SWAP_2_r22 1260 +#define _SWAP_2_r33 1261 +#define _SWAP_3_r03 1262 +#define _SWAP_3_r13 1263 +#define _SWAP_3_r23 1264 +#define _SWAP_3_r33 1265 +#define _TIER2_RESUME_CHECK_r00 1266 +#define _TIER2_RESUME_CHECK_r11 1267 +#define _TIER2_RESUME_CHECK_r22 1268 +#define _TIER2_RESUME_CHECK_r33 1269 +#define _TO_BOOL_r11 1270 +#define _TO_BOOL_BOOL_r01 1271 +#define _TO_BOOL_BOOL_r11 1272 +#define _TO_BOOL_BOOL_r22 1273 +#define _TO_BOOL_BOOL_r33 1274 +#define _TO_BOOL_INT_r11 1275 +#define _TO_BOOL_LIST_r11 1276 +#define _TO_BOOL_NONE_r01 1277 +#define _TO_BOOL_NONE_r11 1278 +#define _TO_BOOL_NONE_r22 1279 +#define _TO_BOOL_NONE_r33 1280 +#define _TO_BOOL_STR_r11 1281 +#define _TRACE_RECORD_r00 1282 +#define _UNARY_INVERT_r11 1283 +#define _UNARY_NEGATIVE_r11 1284 +#define _UNARY_NOT_r01 1285 +#define _UNARY_NOT_r11 1286 +#define _UNARY_NOT_r22 1287 +#define _UNARY_NOT_r33 1288 +#define _UNPACK_EX_r10 1289 +#define _UNPACK_SEQUENCE_r10 1290 +#define _UNPACK_SEQUENCE_LIST_r10 1291 +#define _UNPACK_SEQUENCE_TUPLE_r10 1292 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1293 +#define _WITH_EXCEPT_START_r33 1294 +#define _YIELD_VALUE_r11 1295 +#define MAX_UOP_REGS_ID 1295 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 3a6bf7b3d76a8f..1281eeb041daab 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -335,6 +335,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_POP_TWO_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG, [_POP_CALL_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG, [_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG, + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW] = 0, [_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW] = HAS_ESCAPES_FLAG, [_LOAD_CONST_UNDER_INLINE] = 0, [_LOAD_CONST_UNDER_INLINE_BORROW] = 0, @@ -3065,6 +3066,15 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { 1, 3, _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 }, }, }, + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW] = { + .best = { 0, 1, 2, 3 }, + .entries = { + { 3, 0, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 }, + { 3, 1, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 }, + { 3, 2, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 }, + { 3, 3, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 }, + }, + }, [_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW] = { .best = { 3, 3, 3, 3 }, .entries = { @@ -3817,6 +3827,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_POP_TWO_LOAD_CONST_INLINE_BORROW_r21] = _POP_TWO_LOAD_CONST_INLINE_BORROW, [_POP_CALL_LOAD_CONST_INLINE_BORROW_r21] = _POP_CALL_LOAD_CONST_INLINE_BORROW, [_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31] = _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW, + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW, + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW, + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW, + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33] = _SHUFFLE_3_LOAD_CONST_INLINE_BORROW, [_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31] = _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW, [_LOAD_CONST_UNDER_INLINE_r02] = _LOAD_CONST_UNDER_INLINE, [_LOAD_CONST_UNDER_INLINE_r12] = _LOAD_CONST_UNDER_INLINE, @@ -4762,6 +4776,11 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_SET_IP_r33] = "_SET_IP_r33", [_SET_UPDATE] = "_SET_UPDATE", [_SET_UPDATE_r10] = "_SET_UPDATE_r10", + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW", + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03", + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13", + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23", + [_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33] = "_SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33", [_SPILL_OR_RELOAD] = "_SPILL_OR_RELOAD", [_SPILL_OR_RELOAD_r01] = "_SPILL_OR_RELOAD_r01", [_SPILL_OR_RELOAD_r02] = "_SPILL_OR_RELOAD_r02", @@ -5479,6 +5498,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 2; case _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW: return 3; + case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW: + return 3; case _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW: return 4; case _LOAD_CONST_UNDER_INLINE: diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 88ac1664fe5ddf..9a822834c14f36 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3008,6 +3008,18 @@ class Obj: for _ in range(TIER2_THRESHOLD+1): obj.attr = EvilAttr(obj.__dict__) + def test_constant_fold_tuple(self): + def testfunc(n): + for _ in range(n): + t = (1,) + p = len(t) + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + + self.assertNotIn("_CALL_LEN", uops) + def test_binary_subscr_list_int(self): def testfunc(n): l = [1] diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-19-00-59-29.gh-issue-142961.q8WRSq.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-19-00-59-29.gh-issue-142961.q8WRSq.rst new file mode 100644 index 00000000000000..4b75ab232d50e4 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-19-00-59-29.gh-issue-142961.q8WRSq.rst @@ -0,0 +1 @@ +Fix a segfault in the JIT when constant folding ``len(tuple)``. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 4ce7968ddc2929..1291fe56a59d5b 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -5285,6 +5285,13 @@ dummy_func( value = PyStackRef_FromPyObjectBorrow(ptr); } + tier2 op(_SHUFFLE_3_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null, arg -- res, a, c)) { + res = PyStackRef_FromPyObjectBorrow(ptr); + a = arg; + c = callable; + INPUTS_DEAD(); + } + tier2 op(_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, callable, null, pop1, pop2 -- value)) { PyStackRef_CLOSE(pop2); PyStackRef_CLOSE(pop1); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 74bd939c87d4ec..2305df6ad5aaf1 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -16532,6 +16532,106 @@ break; } + case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef arg; + _PyStackRef callable; + _PyStackRef res; + _PyStackRef a; + _PyStackRef c; + arg = stack_pointer[-1]; + callable = stack_pointer[-3]; + PyObject *ptr = (PyObject *)CURRENT_OPERAND0_64(); + res = PyStackRef_FromPyObjectBorrow(ptr); + a = arg; + c = callable; + _tos_cache2 = c; + _tos_cache1 = a; + _tos_cache0 = res; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -3; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef arg; + _PyStackRef callable; + _PyStackRef res; + _PyStackRef a; + _PyStackRef c; + _PyStackRef _stack_item_0 = _tos_cache0; + arg = _stack_item_0; + callable = stack_pointer[-2]; + PyObject *ptr = (PyObject *)CURRENT_OPERAND0_64(); + res = PyStackRef_FromPyObjectBorrow(ptr); + a = arg; + c = callable; + _tos_cache2 = c; + _tos_cache1 = a; + _tos_cache0 = res; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef arg; + _PyStackRef callable; + _PyStackRef res; + _PyStackRef a; + _PyStackRef c; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + arg = _stack_item_1; + callable = stack_pointer[-1]; + PyObject *ptr = (PyObject *)CURRENT_OPERAND0_64(); + res = PyStackRef_FromPyObjectBorrow(ptr); + a = arg; + c = callable; + _tos_cache2 = c; + _tos_cache1 = a; + _tos_cache0 = res; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef arg; + _PyStackRef callable; + _PyStackRef res; + _PyStackRef a; + _PyStackRef c; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + arg = _stack_item_2; + callable = _stack_item_0; + PyObject *ptr = (PyObject *)CURRENT_OPERAND0_64(); + res = PyStackRef_FromPyObjectBorrow(ptr); + a = arg; + c = callable; + _tos_cache2 = c; + _tos_cache1 = a; + _tos_cache0 = res; + SET_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31: { CHECK_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index f36139db954cb8..d2527fd85e3f12 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -529,10 +529,6 @@ dummy_func(void) { value = PyJitRef_Borrow(sym_new_const(ctx, ptr)); } - op(_POP_CALL_ONE_LOAD_CONST_INLINE_BORROW, (ptr/4, unused, unused, unused -- value)) { - value = PyJitRef_Borrow(sym_new_const(ctx, ptr)); - } - op(_POP_CALL_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, unused, unused, unused, unused -- value)) { value = PyJitRef_Borrow(sym_new_const(ctx, ptr)); } @@ -1263,7 +1259,7 @@ dummy_func(void) { goto error; } if (_Py_IsImmortal(temp)) { - REPLACE_OP(this_instr, _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW, + REPLACE_OP(this_instr, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); } res = sym_new_const(ctx, temp); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 69a2a32e4f15df..0389c6192e1cac 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2862,7 +2862,7 @@ goto error; } if (_Py_IsImmortal(temp)) { - REPLACE_OP(this_instr, _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW, + REPLACE_OP(this_instr, _SHUFFLE_3_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)temp); } res = sym_new_const(ctx, temp); @@ -3424,8 +3424,7 @@ case _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW: { JitOptRef value; - PyObject *ptr = (PyObject *)this_instr->operand0; - value = PyJitRef_Borrow(sym_new_const(ctx, ptr)); + value = sym_new_not_null(ctx); CHECK_STACK_BOUNDS(-2); stack_pointer[-3] = value; stack_pointer += -2; @@ -3433,6 +3432,19 @@ break; } + case _SHUFFLE_3_LOAD_CONST_INLINE_BORROW: { + JitOptRef res; + JitOptRef a; + JitOptRef c; + res = sym_new_not_null(ctx); + a = sym_new_not_null(ctx); + c = sym_new_not_null(ctx); + stack_pointer[-3] = res; + stack_pointer[-2] = a; + stack_pointer[-1] = c; + break; + } + case _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW: { JitOptRef value; PyObject *ptr = (PyObject *)this_instr->operand0; From 6a4f10325d58deb1906b39d68dc8e84f4c2bf5a4 Mon Sep 17 00:00:00 2001 From: stratakis Date: Fri, 19 Dec 2025 19:14:52 +0100 Subject: [PATCH 2/7] gh-142776: Ensure fp file descriptor is closed on all code paths in import.c (GH-142777) --- .../2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst | 1 + Python/import.c | 14 ++++---------- 2 files changed, 5 insertions(+), 10 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst new file mode 100644 index 00000000000000..3039b04d89cb88 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-18-01-00-14.gh-issue-142776.ACaoeP.rst @@ -0,0 +1 @@ +Fix a file descriptor leak in import.c diff --git a/Python/import.c b/Python/import.c index db433dbc971d76..466c5868ab7ee8 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4762,6 +4762,7 @@ static PyObject * _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) /*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/ { + FILE *fp = NULL; PyObject *mod = NULL; PyThreadState *tstate = _PyThreadState_GET(); @@ -4804,16 +4805,12 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) /* We would move this (and the fclose() below) into * _PyImport_GetModuleExportHooks(), but it isn't clear if the intervening * code relies on fp still being open. */ - FILE *fp; if (file != NULL) { fp = Py_fopen(info.filename, "r"); if (fp == NULL) { goto finally; } } - else { - fp = NULL; - } PyModInitFunction p0 = NULL; PyModExportFunction ex0 = NULL; @@ -4822,7 +4819,7 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) mod = import_run_modexport(tstate, ex0, &info, spec); // Modules created from slots handle GIL enablement (Py_mod_gil slot) // when they're created. - goto cleanup; + goto finally; } if (p0 == NULL) { goto finally; @@ -4845,13 +4842,10 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) } #endif -cleanup: - // XXX Shouldn't this happen in the error cases too (i.e. in "finally")? - if (fp) { +finally: + if (fp != NULL) { fclose(fp); } - -finally: _Py_ext_module_loader_info_clear(&info); return mod; } From 6b4bc6e6a240966cfec488c25c83c40a101a94c8 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Sat, 20 Dec 2025 03:06:34 +0800 Subject: [PATCH 3/7] gh-134584: JIT: Borrow references for immortal promoted globals (GH-142921) JIT: Borrow references for immortal promoted globals --- Lib/test/test_capi/test_opt.py | 38 ++++++++++++++++++++++++++++++++++ Python/optimizer_bytecodes.c | 14 +++++++++++-- Python/optimizer_cases.c.h | 14 +++++++++++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 9a822834c14f36..3ea93277dab295 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3008,6 +3008,44 @@ class Obj: for _ in range(TIER2_THRESHOLD+1): obj.attr = EvilAttr(obj.__dict__) + def test_promoted_global_refcount_eliminated(self): + result = script_helper.run_python_until_end('-c', textwrap.dedent(""" + import _testinternalcapi + import opcode + import _opcode + + def get_first_executor(func): + code = func.__code__ + co_code = code.co_code + for i in range(0, len(co_code), 2): + try: + return _opcode.get_executor(code, i) + except ValueError: + pass + return None + + def get_opnames(ex): + return {item[0] for item in ex} + + + def testfunc(n): + y = [] + for i in range(n): + x = tuple(y) + return x + + testfunc(_testinternalcapi.TIER2_THRESHOLD) + + ex = get_first_executor(testfunc) + assert ex is not None + uops = get_opnames(ex) + assert "_LOAD_GLOBAL_BUILTIN" not in uops + assert "_LOAD_CONST_INLINE_BORROW" in uops + assert "_POP_TOP_NOP" in uops + assert "_POP_TOP" not in uops + """), PYTHON_JIT="1") + self.assertEqual(result[0].rc, 0, result) + def test_constant_fold_tuple(self): def testfunc(n): for _ in range(n): diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index d2527fd85e3f12..cd789db1fe89d2 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1376,7 +1376,12 @@ dummy_func(void) { res = sym_new_not_null(ctx); } else { - res = sym_new_const(ctx, cnst); + if (_Py_IsImmortal(cnst)) { + res = PyJitRef_Borrow(sym_new_const(ctx, cnst)); + } + else { + res = sym_new_const(ctx, cnst); + } } } @@ -1411,7 +1416,12 @@ dummy_func(void) { res = sym_new_not_null(ctx); } else { - res = sym_new_const(ctx, cnst); + if (_Py_IsImmortal(cnst)) { + res = PyJitRef_Borrow(sym_new_const(ctx, cnst)); + } + else { + res = sym_new_const(ctx, cnst); + } } } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 0389c6192e1cac..85d3d041215103 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1330,7 +1330,12 @@ res = sym_new_not_null(ctx); } else { - res = sym_new_const(ctx, cnst); + if (_Py_IsImmortal(cnst)) { + res = PyJitRef_Borrow(sym_new_const(ctx, cnst)); + } + else { + res = sym_new_const(ctx, cnst); + } } CHECK_STACK_BOUNDS(1); stack_pointer[0] = res; @@ -1367,7 +1372,12 @@ res = sym_new_not_null(ctx); } else { - res = sym_new_const(ctx, cnst); + if (_Py_IsImmortal(cnst)) { + res = PyJitRef_Borrow(sym_new_const(ctx, cnst)); + } + else { + res = sym_new_const(ctx, cnst); + } } CHECK_STACK_BOUNDS(1); stack_pointer[0] = res; From e2a7db717507a66b49bb796391530147b3acab93 Mon Sep 17 00:00:00 2001 From: Shamil Date: Fri, 19 Dec 2025 22:07:11 +0300 Subject: [PATCH 4/7] gh-142476: fix memory leak when creating JIT executors (GH-142492) --- .../2025-12-13-01-11-03.gh-issue-142476.44Sp4N.rst | 2 ++ Python/optimizer.c | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-12-13-01-11-03.gh-issue-142476.44Sp4N.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-13-01-11-03.gh-issue-142476.44Sp4N.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-13-01-11-03.gh-issue-142476.44Sp4N.rst new file mode 100644 index 00000000000000..eae1f3a1ce53b6 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-13-01-11-03.gh-issue-142476.44Sp4N.rst @@ -0,0 +1,2 @@ +Fix a memory leak in the experimental Tier 2 optimizer when creating +executors. Patched by Shamil Abdulaev. diff --git a/Python/optimizer.c b/Python/optimizer.c index 1e905850e3de6b..16abced6edbeec 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -185,12 +185,17 @@ _PyOptimizer_Optimize( else { executor->vm_data.code = NULL; } + executor->vm_data.chain_depth = chain_depth; + assert(executor->vm_data.valid); _PyExitData *exit = _tstate->jit_tracer_state.initial_state.exit; if (exit != NULL) { exit->executor = executor; } - executor->vm_data.chain_depth = chain_depth; - assert(executor->vm_data.valid); + else { + // An executor inserted into the code object now has a strong reference + // to it from the code object. Thus, we don't need this reference anymore. + Py_DECREF(executor); + } interp->compiling = false; return 1; #else From 08bc03ff2a5545a165ba57f4ca73b8ff705dc757 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 19 Dec 2025 14:10:37 -0500 Subject: [PATCH 5/7] gh-120321: Make gi_frame_state transitions atomic in FT build (gh-142599) This makes generator frame state transitions atomic in the free threading build, which avoids segfaults when trying to execute a generator from multiple threads concurrently. There are still a few operations that aren't thread-safe and may crash if performed concurrently on the same generator/coroutine: * Accessing gi_yieldfrom/cr_await/ag_await * Accessing gi_frame/cr_frame/ag_frame * Async generator operations --- Include/cpython/pyatomic.h | 3 + Include/cpython/pyatomic_gcc.h | 4 + Include/cpython/pyatomic_msc.h | 13 + Include/cpython/pyatomic_std.h | 8 + .../internal/pycore_pyatomic_ft_wrappers.h | 9 + Include/internal/pycore_tstate.h | 7 + Include/internal/pycore_uop_ids.h | 1134 +++++++++-------- Include/internal/pycore_uop_metadata.h | 10 +- .../test_free_threading/test_generators.py | 71 ++ Objects/genobject.c | 518 ++++---- Python/bytecodes.c | 19 +- Python/ceval.c | 15 +- Python/ceval_macros.h | 25 + Python/executor_cases.c.h | 94 +- Python/generated_cases.c.h | 22 +- Tools/cases_generator/analyzer.py | 1 + 16 files changed, 1097 insertions(+), 856 deletions(-) diff --git a/Include/cpython/pyatomic.h b/Include/cpython/pyatomic.h index 790640309f1e03..ce907fd6a4c453 100644 --- a/Include/cpython/pyatomic.h +++ b/Include/cpython/pyatomic.h @@ -523,6 +523,9 @@ _Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value); static inline void _Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value); +static inline void +_Py_atomic_store_int8_release(int8_t *obj, int8_t value); + static inline void _Py_atomic_store_int_release(int *obj, int value); diff --git a/Include/cpython/pyatomic_gcc.h b/Include/cpython/pyatomic_gcc.h index 1566b83b9f6a1b..c045213c898a03 100644 --- a/Include/cpython/pyatomic_gcc.h +++ b/Include/cpython/pyatomic_gcc.h @@ -572,6 +572,10 @@ static inline void _Py_atomic_store_int_release(int *obj, int value) { __atomic_store_n(obj, value, __ATOMIC_RELEASE); } +static inline void +_Py_atomic_store_int8_release(int8_t *obj, int8_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); } + static inline void _Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value) { __atomic_store_n(obj, value, __ATOMIC_RELEASE); } diff --git a/Include/cpython/pyatomic_msc.h b/Include/cpython/pyatomic_msc.h index d155955df0cddf..8b9dd3eb0f8e16 100644 --- a/Include/cpython/pyatomic_msc.h +++ b/Include/cpython/pyatomic_msc.h @@ -1066,6 +1066,19 @@ _Py_atomic_store_int_release(int *obj, int value) #endif } +static inline void +_Py_atomic_store_int8_release(int8_t *obj, int8_t value) +{ +#if defined(_M_X64) || defined(_M_IX86) + *(int8_t volatile *)obj = value; +#elif defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(unsigned __int8); + __stlr8((unsigned __int8 volatile *)obj, (unsigned __int8)value); +#else +# error "no implementation of _Py_atomic_store_int8_release" +#endif +} + static inline void _Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value) { diff --git a/Include/cpython/pyatomic_std.h b/Include/cpython/pyatomic_std.h index 7176f667a4082c..cfc8dbefc63d09 100644 --- a/Include/cpython/pyatomic_std.h +++ b/Include/cpython/pyatomic_std.h @@ -1023,6 +1023,14 @@ _Py_atomic_store_int_release(int *obj, int value) memory_order_release); } +static inline void +_Py_atomic_store_int8_release(int8_t *obj, int8_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(int8_t)*)obj, value, + memory_order_release); +} + static inline void _Py_atomic_store_uint_release(unsigned int *obj, unsigned int value) { diff --git a/Include/internal/pycore_pyatomic_ft_wrappers.h b/Include/internal/pycore_pyatomic_ft_wrappers.h index 1a6d5075361f3c..70a32db663b293 100644 --- a/Include/internal/pycore_pyatomic_ft_wrappers.h +++ b/Include/internal/pycore_pyatomic_ft_wrappers.h @@ -41,6 +41,8 @@ extern "C" { _Py_atomic_load_uint8(&value) #define FT_ATOMIC_STORE_UINT8(value, new_value) \ _Py_atomic_store_uint8(&value, new_value) +#define FT_ATOMIC_LOAD_INT8_RELAXED(value) \ + _Py_atomic_load_int8_relaxed(&value) #define FT_ATOMIC_LOAD_UINT8_RELAXED(value) \ _Py_atomic_load_uint8_relaxed(&value) #define FT_ATOMIC_LOAD_UINT16_RELAXED(value) \ @@ -55,6 +57,10 @@ extern "C" { _Py_atomic_store_ptr_release(&value, new_value) #define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) \ _Py_atomic_store_uintptr_release(&value, new_value) +#define FT_ATOMIC_STORE_INT8_RELAXED(value, new_value) \ + _Py_atomic_store_int8_relaxed(&value, new_value) +#define FT_ATOMIC_STORE_INT8_RELEASE(value, new_value) \ + _Py_atomic_store_int8_release(&value, new_value) #define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) \ _Py_atomic_store_ssize_relaxed(&value, new_value) #define FT_ATOMIC_STORE_SSIZE_RELEASE(value, new_value) \ @@ -134,6 +140,7 @@ extern "C" { #define FT_ATOMIC_LOAD_PTR_RELAXED(value) value #define FT_ATOMIC_LOAD_UINT8(value) value #define FT_ATOMIC_STORE_UINT8(value, new_value) value = new_value +#define FT_ATOMIC_LOAD_INT8_RELAXED(value) value #define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value #define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value #define FT_ATOMIC_LOAD_UINT32_RELAXED(value) value @@ -141,6 +148,8 @@ extern "C" { #define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value #define FT_ATOMIC_STORE_PTR_RELEASE(value, new_value) value = new_value #define FT_ATOMIC_STORE_UINTPTR_RELEASE(value, new_value) value = new_value +#define FT_ATOMIC_STORE_INT8_RELAXED(value, new_value) value = new_value +#define FT_ATOMIC_STORE_INT8_RELEASE(value, new_value) value = new_value #define FT_ATOMIC_STORE_SSIZE_RELAXED(value, new_value) value = new_value #define FT_ATOMIC_STORE_SSIZE_RELEASE(value, new_value) value = new_value #define FT_ATOMIC_STORE_UINT8_RELAXED(value, new_value) value = new_value diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h index c4f723ac8abbbe..a57f1f45c135a6 100644 --- a/Include/internal/pycore_tstate.h +++ b/Include/internal/pycore_tstate.h @@ -82,6 +82,13 @@ typedef struct _PyThreadStateImpl { PyObject *asyncio_running_loop; // Strong reference PyObject *asyncio_running_task; // Strong reference + // Distinguishes between yield and return from PyEval_EvalFrame(). + // See gen_send_ex2() in Objects/genobject.c + enum { + GENERATOR_RETURN = 0, + GENERATOR_YIELD = 1, + } generator_return_kind; + /* Head of circular linked-list of all tasks which are instances of `asyncio.Task` or subclasses of it used in `asyncio.all_tasks`. */ diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 6130e5cad21bf4..a11959fb4057df 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -535,572 +535,574 @@ extern "C" { #define _FORMAT_SIMPLE_r11 728 #define _FORMAT_WITH_SPEC_r21 729 #define _FOR_ITER_r23 730 -#define _FOR_ITER_GEN_FRAME_r23 731 -#define _FOR_ITER_TIER_TWO_r23 732 -#define _GET_AITER_r11 733 -#define _GET_ANEXT_r12 734 -#define _GET_AWAITABLE_r11 735 -#define _GET_ITER_r12 736 -#define _GET_LEN_r12 737 -#define _GET_YIELD_FROM_ITER_r11 738 -#define _GUARD_BINARY_OP_EXTEND_r22 739 -#define _GUARD_CALLABLE_ISINSTANCE_r03 740 -#define _GUARD_CALLABLE_ISINSTANCE_r13 741 -#define _GUARD_CALLABLE_ISINSTANCE_r23 742 -#define _GUARD_CALLABLE_ISINSTANCE_r33 743 -#define _GUARD_CALLABLE_LEN_r03 744 -#define _GUARD_CALLABLE_LEN_r13 745 -#define _GUARD_CALLABLE_LEN_r23 746 -#define _GUARD_CALLABLE_LEN_r33 747 -#define _GUARD_CALLABLE_LIST_APPEND_r03 748 -#define _GUARD_CALLABLE_LIST_APPEND_r13 749 -#define _GUARD_CALLABLE_LIST_APPEND_r23 750 -#define _GUARD_CALLABLE_LIST_APPEND_r33 751 -#define _GUARD_CALLABLE_STR_1_r03 752 -#define _GUARD_CALLABLE_STR_1_r13 753 -#define _GUARD_CALLABLE_STR_1_r23 754 -#define _GUARD_CALLABLE_STR_1_r33 755 -#define _GUARD_CALLABLE_TUPLE_1_r03 756 -#define _GUARD_CALLABLE_TUPLE_1_r13 757 -#define _GUARD_CALLABLE_TUPLE_1_r23 758 -#define _GUARD_CALLABLE_TUPLE_1_r33 759 -#define _GUARD_CALLABLE_TYPE_1_r03 760 -#define _GUARD_CALLABLE_TYPE_1_r13 761 -#define _GUARD_CALLABLE_TYPE_1_r23 762 -#define _GUARD_CALLABLE_TYPE_1_r33 763 -#define _GUARD_DORV_NO_DICT_r01 764 -#define _GUARD_DORV_NO_DICT_r11 765 -#define _GUARD_DORV_NO_DICT_r22 766 -#define _GUARD_DORV_NO_DICT_r33 767 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 768 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 769 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 770 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 771 -#define _GUARD_GLOBALS_VERSION_r00 772 -#define _GUARD_GLOBALS_VERSION_r11 773 -#define _GUARD_GLOBALS_VERSION_r22 774 -#define _GUARD_GLOBALS_VERSION_r33 775 -#define _GUARD_IP_RETURN_GENERATOR_r00 776 -#define _GUARD_IP_RETURN_GENERATOR_r11 777 -#define _GUARD_IP_RETURN_GENERATOR_r22 778 -#define _GUARD_IP_RETURN_GENERATOR_r33 779 -#define _GUARD_IP_RETURN_VALUE_r00 780 -#define _GUARD_IP_RETURN_VALUE_r11 781 -#define _GUARD_IP_RETURN_VALUE_r22 782 -#define _GUARD_IP_RETURN_VALUE_r33 783 -#define _GUARD_IP_YIELD_VALUE_r00 784 -#define _GUARD_IP_YIELD_VALUE_r11 785 -#define _GUARD_IP_YIELD_VALUE_r22 786 -#define _GUARD_IP_YIELD_VALUE_r33 787 -#define _GUARD_IP__PUSH_FRAME_r00 788 -#define _GUARD_IP__PUSH_FRAME_r11 789 -#define _GUARD_IP__PUSH_FRAME_r22 790 -#define _GUARD_IP__PUSH_FRAME_r33 791 -#define _GUARD_IS_FALSE_POP_r00 792 -#define _GUARD_IS_FALSE_POP_r10 793 -#define _GUARD_IS_FALSE_POP_r21 794 -#define _GUARD_IS_FALSE_POP_r32 795 -#define _GUARD_IS_NONE_POP_r00 796 -#define _GUARD_IS_NONE_POP_r10 797 -#define _GUARD_IS_NONE_POP_r21 798 -#define _GUARD_IS_NONE_POP_r32 799 -#define _GUARD_IS_NOT_NONE_POP_r10 800 -#define _GUARD_IS_TRUE_POP_r00 801 -#define _GUARD_IS_TRUE_POP_r10 802 -#define _GUARD_IS_TRUE_POP_r21 803 -#define _GUARD_IS_TRUE_POP_r32 804 -#define _GUARD_KEYS_VERSION_r01 805 -#define _GUARD_KEYS_VERSION_r11 806 -#define _GUARD_KEYS_VERSION_r22 807 -#define _GUARD_KEYS_VERSION_r33 808 -#define _GUARD_NOS_DICT_r02 809 -#define _GUARD_NOS_DICT_r12 810 -#define _GUARD_NOS_DICT_r22 811 -#define _GUARD_NOS_DICT_r33 812 -#define _GUARD_NOS_FLOAT_r02 813 -#define _GUARD_NOS_FLOAT_r12 814 -#define _GUARD_NOS_FLOAT_r22 815 -#define _GUARD_NOS_FLOAT_r33 816 -#define _GUARD_NOS_INT_r02 817 -#define _GUARD_NOS_INT_r12 818 -#define _GUARD_NOS_INT_r22 819 -#define _GUARD_NOS_INT_r33 820 -#define _GUARD_NOS_LIST_r02 821 -#define _GUARD_NOS_LIST_r12 822 -#define _GUARD_NOS_LIST_r22 823 -#define _GUARD_NOS_LIST_r33 824 -#define _GUARD_NOS_NOT_NULL_r02 825 -#define _GUARD_NOS_NOT_NULL_r12 826 -#define _GUARD_NOS_NOT_NULL_r22 827 -#define _GUARD_NOS_NOT_NULL_r33 828 -#define _GUARD_NOS_NULL_r02 829 -#define _GUARD_NOS_NULL_r12 830 -#define _GUARD_NOS_NULL_r22 831 -#define _GUARD_NOS_NULL_r33 832 -#define _GUARD_NOS_OVERFLOWED_r02 833 -#define _GUARD_NOS_OVERFLOWED_r12 834 -#define _GUARD_NOS_OVERFLOWED_r22 835 -#define _GUARD_NOS_OVERFLOWED_r33 836 -#define _GUARD_NOS_TUPLE_r02 837 -#define _GUARD_NOS_TUPLE_r12 838 -#define _GUARD_NOS_TUPLE_r22 839 -#define _GUARD_NOS_TUPLE_r33 840 -#define _GUARD_NOS_UNICODE_r02 841 -#define _GUARD_NOS_UNICODE_r12 842 -#define _GUARD_NOS_UNICODE_r22 843 -#define _GUARD_NOS_UNICODE_r33 844 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 845 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 846 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 847 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 848 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 849 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 850 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 851 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 852 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 853 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 854 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 855 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 856 -#define _GUARD_THIRD_NULL_r03 857 -#define _GUARD_THIRD_NULL_r13 858 -#define _GUARD_THIRD_NULL_r23 859 -#define _GUARD_THIRD_NULL_r33 860 -#define _GUARD_TOS_ANY_SET_r01 861 -#define _GUARD_TOS_ANY_SET_r11 862 -#define _GUARD_TOS_ANY_SET_r22 863 -#define _GUARD_TOS_ANY_SET_r33 864 -#define _GUARD_TOS_DICT_r01 865 -#define _GUARD_TOS_DICT_r11 866 -#define _GUARD_TOS_DICT_r22 867 -#define _GUARD_TOS_DICT_r33 868 -#define _GUARD_TOS_FLOAT_r01 869 -#define _GUARD_TOS_FLOAT_r11 870 -#define _GUARD_TOS_FLOAT_r22 871 -#define _GUARD_TOS_FLOAT_r33 872 -#define _GUARD_TOS_INT_r01 873 -#define _GUARD_TOS_INT_r11 874 -#define _GUARD_TOS_INT_r22 875 -#define _GUARD_TOS_INT_r33 876 -#define _GUARD_TOS_LIST_r01 877 -#define _GUARD_TOS_LIST_r11 878 -#define _GUARD_TOS_LIST_r22 879 -#define _GUARD_TOS_LIST_r33 880 -#define _GUARD_TOS_OVERFLOWED_r01 881 -#define _GUARD_TOS_OVERFLOWED_r11 882 -#define _GUARD_TOS_OVERFLOWED_r22 883 -#define _GUARD_TOS_OVERFLOWED_r33 884 -#define _GUARD_TOS_SLICE_r01 885 -#define _GUARD_TOS_SLICE_r11 886 -#define _GUARD_TOS_SLICE_r22 887 -#define _GUARD_TOS_SLICE_r33 888 -#define _GUARD_TOS_TUPLE_r01 889 -#define _GUARD_TOS_TUPLE_r11 890 -#define _GUARD_TOS_TUPLE_r22 891 -#define _GUARD_TOS_TUPLE_r33 892 -#define _GUARD_TOS_UNICODE_r01 893 -#define _GUARD_TOS_UNICODE_r11 894 -#define _GUARD_TOS_UNICODE_r22 895 -#define _GUARD_TOS_UNICODE_r33 896 -#define _GUARD_TYPE_VERSION_r01 897 -#define _GUARD_TYPE_VERSION_r11 898 -#define _GUARD_TYPE_VERSION_r22 899 -#define _GUARD_TYPE_VERSION_r33 900 -#define _GUARD_TYPE_VERSION_AND_LOCK_r01 901 -#define _GUARD_TYPE_VERSION_AND_LOCK_r11 902 -#define _GUARD_TYPE_VERSION_AND_LOCK_r22 903 -#define _GUARD_TYPE_VERSION_AND_LOCK_r33 904 -#define _HANDLE_PENDING_AND_DEOPT_r00 905 -#define _HANDLE_PENDING_AND_DEOPT_r10 906 -#define _HANDLE_PENDING_AND_DEOPT_r20 907 -#define _HANDLE_PENDING_AND_DEOPT_r30 908 -#define _IMPORT_FROM_r12 909 -#define _IMPORT_NAME_r21 910 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 911 -#define _INIT_CALL_PY_EXACT_ARGS_r01 912 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 913 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 914 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 915 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 916 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 917 -#define _INSERT_NULL_r10 918 -#define _INSTRUMENTED_FOR_ITER_r23 919 -#define _INSTRUMENTED_INSTRUCTION_r00 920 -#define _INSTRUMENTED_JUMP_FORWARD_r00 921 -#define _INSTRUMENTED_JUMP_FORWARD_r11 922 -#define _INSTRUMENTED_JUMP_FORWARD_r22 923 -#define _INSTRUMENTED_JUMP_FORWARD_r33 924 -#define _INSTRUMENTED_LINE_r00 925 -#define _INSTRUMENTED_NOT_TAKEN_r00 926 -#define _INSTRUMENTED_NOT_TAKEN_r11 927 -#define _INSTRUMENTED_NOT_TAKEN_r22 928 -#define _INSTRUMENTED_NOT_TAKEN_r33 929 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 930 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 931 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 932 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 933 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 934 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 935 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 936 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 937 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 938 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 939 -#define _IS_NONE_r11 940 -#define _IS_OP_r21 941 -#define _ITER_CHECK_LIST_r02 942 -#define _ITER_CHECK_LIST_r12 943 -#define _ITER_CHECK_LIST_r22 944 -#define _ITER_CHECK_LIST_r33 945 -#define _ITER_CHECK_RANGE_r02 946 -#define _ITER_CHECK_RANGE_r12 947 -#define _ITER_CHECK_RANGE_r22 948 -#define _ITER_CHECK_RANGE_r33 949 -#define _ITER_CHECK_TUPLE_r02 950 -#define _ITER_CHECK_TUPLE_r12 951 -#define _ITER_CHECK_TUPLE_r22 952 -#define _ITER_CHECK_TUPLE_r33 953 -#define _ITER_JUMP_LIST_r02 954 -#define _ITER_JUMP_LIST_r12 955 -#define _ITER_JUMP_LIST_r22 956 -#define _ITER_JUMP_LIST_r33 957 -#define _ITER_JUMP_RANGE_r02 958 -#define _ITER_JUMP_RANGE_r12 959 -#define _ITER_JUMP_RANGE_r22 960 -#define _ITER_JUMP_RANGE_r33 961 -#define _ITER_JUMP_TUPLE_r02 962 -#define _ITER_JUMP_TUPLE_r12 963 -#define _ITER_JUMP_TUPLE_r22 964 -#define _ITER_JUMP_TUPLE_r33 965 -#define _ITER_NEXT_LIST_r23 966 -#define _ITER_NEXT_LIST_TIER_TWO_r23 967 -#define _ITER_NEXT_RANGE_r03 968 -#define _ITER_NEXT_RANGE_r13 969 -#define _ITER_NEXT_RANGE_r23 970 -#define _ITER_NEXT_TUPLE_r03 971 -#define _ITER_NEXT_TUPLE_r13 972 -#define _ITER_NEXT_TUPLE_r23 973 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 974 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 975 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 976 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 977 -#define _JUMP_TO_TOP_r00 978 -#define _LIST_APPEND_r10 979 -#define _LIST_EXTEND_r10 980 -#define _LOAD_ATTR_r10 981 -#define _LOAD_ATTR_CLASS_r11 982 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 983 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 984 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 985 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 986 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 987 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 988 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 989 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 990 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 991 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 992 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 993 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 994 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 995 -#define _LOAD_ATTR_MODULE_r11 996 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 997 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 998 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 999 -#define _LOAD_ATTR_SLOT_r11 1000 -#define _LOAD_ATTR_WITH_HINT_r11 1001 -#define _LOAD_BUILD_CLASS_r01 1002 -#define _LOAD_BYTECODE_r00 1003 -#define _LOAD_COMMON_CONSTANT_r01 1004 -#define _LOAD_COMMON_CONSTANT_r12 1005 -#define _LOAD_COMMON_CONSTANT_r23 1006 -#define _LOAD_CONST_r01 1007 -#define _LOAD_CONST_r12 1008 -#define _LOAD_CONST_r23 1009 -#define _LOAD_CONST_INLINE_r01 1010 -#define _LOAD_CONST_INLINE_r12 1011 -#define _LOAD_CONST_INLINE_r23 1012 -#define _LOAD_CONST_INLINE_BORROW_r01 1013 -#define _LOAD_CONST_INLINE_BORROW_r12 1014 -#define _LOAD_CONST_INLINE_BORROW_r23 1015 -#define _LOAD_CONST_UNDER_INLINE_r02 1016 -#define _LOAD_CONST_UNDER_INLINE_r12 1017 -#define _LOAD_CONST_UNDER_INLINE_r23 1018 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1019 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1020 -#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1021 -#define _LOAD_DEREF_r01 1022 -#define _LOAD_FAST_r01 1023 -#define _LOAD_FAST_r12 1024 -#define _LOAD_FAST_r23 1025 -#define _LOAD_FAST_0_r01 1026 -#define _LOAD_FAST_0_r12 1027 -#define _LOAD_FAST_0_r23 1028 -#define _LOAD_FAST_1_r01 1029 -#define _LOAD_FAST_1_r12 1030 -#define _LOAD_FAST_1_r23 1031 -#define _LOAD_FAST_2_r01 1032 -#define _LOAD_FAST_2_r12 1033 -#define _LOAD_FAST_2_r23 1034 -#define _LOAD_FAST_3_r01 1035 -#define _LOAD_FAST_3_r12 1036 -#define _LOAD_FAST_3_r23 1037 -#define _LOAD_FAST_4_r01 1038 -#define _LOAD_FAST_4_r12 1039 -#define _LOAD_FAST_4_r23 1040 -#define _LOAD_FAST_5_r01 1041 -#define _LOAD_FAST_5_r12 1042 -#define _LOAD_FAST_5_r23 1043 -#define _LOAD_FAST_6_r01 1044 -#define _LOAD_FAST_6_r12 1045 -#define _LOAD_FAST_6_r23 1046 -#define _LOAD_FAST_7_r01 1047 -#define _LOAD_FAST_7_r12 1048 -#define _LOAD_FAST_7_r23 1049 -#define _LOAD_FAST_AND_CLEAR_r01 1050 -#define _LOAD_FAST_AND_CLEAR_r12 1051 -#define _LOAD_FAST_AND_CLEAR_r23 1052 -#define _LOAD_FAST_BORROW_r01 1053 -#define _LOAD_FAST_BORROW_r12 1054 -#define _LOAD_FAST_BORROW_r23 1055 -#define _LOAD_FAST_BORROW_0_r01 1056 -#define _LOAD_FAST_BORROW_0_r12 1057 -#define _LOAD_FAST_BORROW_0_r23 1058 -#define _LOAD_FAST_BORROW_1_r01 1059 -#define _LOAD_FAST_BORROW_1_r12 1060 -#define _LOAD_FAST_BORROW_1_r23 1061 -#define _LOAD_FAST_BORROW_2_r01 1062 -#define _LOAD_FAST_BORROW_2_r12 1063 -#define _LOAD_FAST_BORROW_2_r23 1064 -#define _LOAD_FAST_BORROW_3_r01 1065 -#define _LOAD_FAST_BORROW_3_r12 1066 -#define _LOAD_FAST_BORROW_3_r23 1067 -#define _LOAD_FAST_BORROW_4_r01 1068 -#define _LOAD_FAST_BORROW_4_r12 1069 -#define _LOAD_FAST_BORROW_4_r23 1070 -#define _LOAD_FAST_BORROW_5_r01 1071 -#define _LOAD_FAST_BORROW_5_r12 1072 -#define _LOAD_FAST_BORROW_5_r23 1073 -#define _LOAD_FAST_BORROW_6_r01 1074 -#define _LOAD_FAST_BORROW_6_r12 1075 -#define _LOAD_FAST_BORROW_6_r23 1076 -#define _LOAD_FAST_BORROW_7_r01 1077 -#define _LOAD_FAST_BORROW_7_r12 1078 -#define _LOAD_FAST_BORROW_7_r23 1079 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1080 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1081 -#define _LOAD_FAST_CHECK_r01 1082 -#define _LOAD_FAST_CHECK_r12 1083 -#define _LOAD_FAST_CHECK_r23 1084 -#define _LOAD_FAST_LOAD_FAST_r02 1085 -#define _LOAD_FAST_LOAD_FAST_r13 1086 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1087 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1088 -#define _LOAD_GLOBAL_r00 1089 -#define _LOAD_GLOBAL_BUILTINS_r01 1090 -#define _LOAD_GLOBAL_MODULE_r01 1091 -#define _LOAD_LOCALS_r01 1092 -#define _LOAD_LOCALS_r12 1093 -#define _LOAD_LOCALS_r23 1094 -#define _LOAD_NAME_r01 1095 -#define _LOAD_SMALL_INT_r01 1096 -#define _LOAD_SMALL_INT_r12 1097 -#define _LOAD_SMALL_INT_r23 1098 -#define _LOAD_SMALL_INT_0_r01 1099 -#define _LOAD_SMALL_INT_0_r12 1100 -#define _LOAD_SMALL_INT_0_r23 1101 -#define _LOAD_SMALL_INT_1_r01 1102 -#define _LOAD_SMALL_INT_1_r12 1103 -#define _LOAD_SMALL_INT_1_r23 1104 -#define _LOAD_SMALL_INT_2_r01 1105 -#define _LOAD_SMALL_INT_2_r12 1106 -#define _LOAD_SMALL_INT_2_r23 1107 -#define _LOAD_SMALL_INT_3_r01 1108 -#define _LOAD_SMALL_INT_3_r12 1109 -#define _LOAD_SMALL_INT_3_r23 1110 -#define _LOAD_SPECIAL_r00 1111 -#define _LOAD_SUPER_ATTR_ATTR_r31 1112 -#define _LOAD_SUPER_ATTR_METHOD_r32 1113 -#define _MAKE_CALLARGS_A_TUPLE_r33 1114 -#define _MAKE_CELL_r00 1115 -#define _MAKE_FUNCTION_r11 1116 -#define _MAKE_WARM_r00 1117 -#define _MAKE_WARM_r11 1118 -#define _MAKE_WARM_r22 1119 -#define _MAKE_WARM_r33 1120 -#define _MAP_ADD_r20 1121 -#define _MATCH_CLASS_r31 1122 -#define _MATCH_KEYS_r23 1123 -#define _MATCH_MAPPING_r02 1124 -#define _MATCH_MAPPING_r12 1125 -#define _MATCH_MAPPING_r23 1126 -#define _MATCH_SEQUENCE_r02 1127 -#define _MATCH_SEQUENCE_r12 1128 -#define _MATCH_SEQUENCE_r23 1129 -#define _MAYBE_EXPAND_METHOD_r00 1130 -#define _MAYBE_EXPAND_METHOD_KW_r11 1131 -#define _MONITOR_CALL_r00 1132 -#define _MONITOR_CALL_KW_r11 1133 -#define _MONITOR_JUMP_BACKWARD_r00 1134 -#define _MONITOR_JUMP_BACKWARD_r11 1135 -#define _MONITOR_JUMP_BACKWARD_r22 1136 -#define _MONITOR_JUMP_BACKWARD_r33 1137 -#define _MONITOR_RESUME_r00 1138 -#define _NOP_r00 1139 -#define _NOP_r11 1140 -#define _NOP_r22 1141 -#define _NOP_r33 1142 -#define _POP_CALL_r20 1143 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1144 -#define _POP_CALL_ONE_r30 1145 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1146 -#define _POP_CALL_TWO_r30 1147 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1148 -#define _POP_EXCEPT_r10 1149 -#define _POP_ITER_r20 1150 -#define _POP_JUMP_IF_FALSE_r00 1151 -#define _POP_JUMP_IF_FALSE_r10 1152 -#define _POP_JUMP_IF_FALSE_r21 1153 -#define _POP_JUMP_IF_FALSE_r32 1154 -#define _POP_JUMP_IF_TRUE_r00 1155 -#define _POP_JUMP_IF_TRUE_r10 1156 -#define _POP_JUMP_IF_TRUE_r21 1157 -#define _POP_JUMP_IF_TRUE_r32 1158 -#define _POP_TOP_r10 1159 -#define _POP_TOP_FLOAT_r00 1160 -#define _POP_TOP_FLOAT_r10 1161 -#define _POP_TOP_FLOAT_r21 1162 -#define _POP_TOP_FLOAT_r32 1163 -#define _POP_TOP_INT_r00 1164 -#define _POP_TOP_INT_r10 1165 -#define _POP_TOP_INT_r21 1166 -#define _POP_TOP_INT_r32 1167 -#define _POP_TOP_LOAD_CONST_INLINE_r11 1168 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1169 -#define _POP_TOP_NOP_r00 1170 -#define _POP_TOP_NOP_r10 1171 -#define _POP_TOP_NOP_r21 1172 -#define _POP_TOP_NOP_r32 1173 -#define _POP_TOP_UNICODE_r00 1174 -#define _POP_TOP_UNICODE_r10 1175 -#define _POP_TOP_UNICODE_r21 1176 -#define _POP_TOP_UNICODE_r32 1177 -#define _POP_TWO_r20 1178 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1179 -#define _PUSH_EXC_INFO_r02 1180 -#define _PUSH_EXC_INFO_r12 1181 -#define _PUSH_EXC_INFO_r23 1182 -#define _PUSH_FRAME_r10 1183 -#define _PUSH_NULL_r01 1184 -#define _PUSH_NULL_r12 1185 -#define _PUSH_NULL_r23 1186 -#define _PUSH_NULL_CONDITIONAL_r00 1187 -#define _PY_FRAME_GENERAL_r01 1188 -#define _PY_FRAME_KW_r11 1189 -#define _QUICKEN_RESUME_r00 1190 -#define _QUICKEN_RESUME_r11 1191 -#define _QUICKEN_RESUME_r22 1192 -#define _QUICKEN_RESUME_r33 1193 -#define _REPLACE_WITH_TRUE_r11 1194 -#define _RESUME_CHECK_r00 1195 -#define _RESUME_CHECK_r11 1196 -#define _RESUME_CHECK_r22 1197 -#define _RESUME_CHECK_r33 1198 -#define _RETURN_GENERATOR_r01 1199 -#define _RETURN_VALUE_r11 1200 -#define _SAVE_RETURN_OFFSET_r00 1201 -#define _SAVE_RETURN_OFFSET_r11 1202 -#define _SAVE_RETURN_OFFSET_r22 1203 -#define _SAVE_RETURN_OFFSET_r33 1204 -#define _SEND_r22 1205 -#define _SEND_GEN_FRAME_r22 1206 -#define _SETUP_ANNOTATIONS_r00 1207 -#define _SET_ADD_r10 1208 -#define _SET_FUNCTION_ATTRIBUTE_r01 1209 -#define _SET_FUNCTION_ATTRIBUTE_r11 1210 -#define _SET_FUNCTION_ATTRIBUTE_r21 1211 -#define _SET_FUNCTION_ATTRIBUTE_r32 1212 -#define _SET_IP_r00 1213 -#define _SET_IP_r11 1214 -#define _SET_IP_r22 1215 -#define _SET_IP_r33 1216 -#define _SET_UPDATE_r10 1217 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1218 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1219 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1220 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1221 -#define _SPILL_OR_RELOAD_r01 1222 -#define _SPILL_OR_RELOAD_r02 1223 -#define _SPILL_OR_RELOAD_r03 1224 -#define _SPILL_OR_RELOAD_r10 1225 -#define _SPILL_OR_RELOAD_r12 1226 -#define _SPILL_OR_RELOAD_r13 1227 -#define _SPILL_OR_RELOAD_r20 1228 -#define _SPILL_OR_RELOAD_r21 1229 -#define _SPILL_OR_RELOAD_r23 1230 -#define _SPILL_OR_RELOAD_r30 1231 -#define _SPILL_OR_RELOAD_r31 1232 -#define _SPILL_OR_RELOAD_r32 1233 -#define _START_EXECUTOR_r00 1234 -#define _STORE_ATTR_r20 1235 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1236 -#define _STORE_ATTR_SLOT_r21 1237 -#define _STORE_ATTR_WITH_HINT_r21 1238 -#define _STORE_DEREF_r10 1239 -#define _STORE_FAST_r10 1240 -#define _STORE_FAST_0_r10 1241 -#define _STORE_FAST_1_r10 1242 -#define _STORE_FAST_2_r10 1243 -#define _STORE_FAST_3_r10 1244 -#define _STORE_FAST_4_r10 1245 -#define _STORE_FAST_5_r10 1246 -#define _STORE_FAST_6_r10 1247 -#define _STORE_FAST_7_r10 1248 -#define _STORE_FAST_LOAD_FAST_r11 1249 -#define _STORE_FAST_STORE_FAST_r20 1250 -#define _STORE_GLOBAL_r10 1251 -#define _STORE_NAME_r10 1252 -#define _STORE_SLICE_r30 1253 -#define _STORE_SUBSCR_r30 1254 -#define _STORE_SUBSCR_DICT_r31 1255 -#define _STORE_SUBSCR_LIST_INT_r32 1256 -#define _SWAP_r11 1257 -#define _SWAP_2_r02 1258 -#define _SWAP_2_r12 1259 -#define _SWAP_2_r22 1260 -#define _SWAP_2_r33 1261 -#define _SWAP_3_r03 1262 -#define _SWAP_3_r13 1263 -#define _SWAP_3_r23 1264 -#define _SWAP_3_r33 1265 -#define _TIER2_RESUME_CHECK_r00 1266 -#define _TIER2_RESUME_CHECK_r11 1267 -#define _TIER2_RESUME_CHECK_r22 1268 -#define _TIER2_RESUME_CHECK_r33 1269 -#define _TO_BOOL_r11 1270 -#define _TO_BOOL_BOOL_r01 1271 -#define _TO_BOOL_BOOL_r11 1272 -#define _TO_BOOL_BOOL_r22 1273 -#define _TO_BOOL_BOOL_r33 1274 -#define _TO_BOOL_INT_r11 1275 -#define _TO_BOOL_LIST_r11 1276 -#define _TO_BOOL_NONE_r01 1277 -#define _TO_BOOL_NONE_r11 1278 -#define _TO_BOOL_NONE_r22 1279 -#define _TO_BOOL_NONE_r33 1280 -#define _TO_BOOL_STR_r11 1281 -#define _TRACE_RECORD_r00 1282 -#define _UNARY_INVERT_r11 1283 -#define _UNARY_NEGATIVE_r11 1284 -#define _UNARY_NOT_r01 1285 -#define _UNARY_NOT_r11 1286 -#define _UNARY_NOT_r22 1287 -#define _UNARY_NOT_r33 1288 -#define _UNPACK_EX_r10 1289 -#define _UNPACK_SEQUENCE_r10 1290 -#define _UNPACK_SEQUENCE_LIST_r10 1291 -#define _UNPACK_SEQUENCE_TUPLE_r10 1292 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1293 -#define _WITH_EXCEPT_START_r33 1294 -#define _YIELD_VALUE_r11 1295 -#define MAX_UOP_REGS_ID 1295 +#define _FOR_ITER_GEN_FRAME_r03 731 +#define _FOR_ITER_GEN_FRAME_r13 732 +#define _FOR_ITER_GEN_FRAME_r23 733 +#define _FOR_ITER_TIER_TWO_r23 734 +#define _GET_AITER_r11 735 +#define _GET_ANEXT_r12 736 +#define _GET_AWAITABLE_r11 737 +#define _GET_ITER_r12 738 +#define _GET_LEN_r12 739 +#define _GET_YIELD_FROM_ITER_r11 740 +#define _GUARD_BINARY_OP_EXTEND_r22 741 +#define _GUARD_CALLABLE_ISINSTANCE_r03 742 +#define _GUARD_CALLABLE_ISINSTANCE_r13 743 +#define _GUARD_CALLABLE_ISINSTANCE_r23 744 +#define _GUARD_CALLABLE_ISINSTANCE_r33 745 +#define _GUARD_CALLABLE_LEN_r03 746 +#define _GUARD_CALLABLE_LEN_r13 747 +#define _GUARD_CALLABLE_LEN_r23 748 +#define _GUARD_CALLABLE_LEN_r33 749 +#define _GUARD_CALLABLE_LIST_APPEND_r03 750 +#define _GUARD_CALLABLE_LIST_APPEND_r13 751 +#define _GUARD_CALLABLE_LIST_APPEND_r23 752 +#define _GUARD_CALLABLE_LIST_APPEND_r33 753 +#define _GUARD_CALLABLE_STR_1_r03 754 +#define _GUARD_CALLABLE_STR_1_r13 755 +#define _GUARD_CALLABLE_STR_1_r23 756 +#define _GUARD_CALLABLE_STR_1_r33 757 +#define _GUARD_CALLABLE_TUPLE_1_r03 758 +#define _GUARD_CALLABLE_TUPLE_1_r13 759 +#define _GUARD_CALLABLE_TUPLE_1_r23 760 +#define _GUARD_CALLABLE_TUPLE_1_r33 761 +#define _GUARD_CALLABLE_TYPE_1_r03 762 +#define _GUARD_CALLABLE_TYPE_1_r13 763 +#define _GUARD_CALLABLE_TYPE_1_r23 764 +#define _GUARD_CALLABLE_TYPE_1_r33 765 +#define _GUARD_DORV_NO_DICT_r01 766 +#define _GUARD_DORV_NO_DICT_r11 767 +#define _GUARD_DORV_NO_DICT_r22 768 +#define _GUARD_DORV_NO_DICT_r33 769 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 770 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 771 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 772 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 773 +#define _GUARD_GLOBALS_VERSION_r00 774 +#define _GUARD_GLOBALS_VERSION_r11 775 +#define _GUARD_GLOBALS_VERSION_r22 776 +#define _GUARD_GLOBALS_VERSION_r33 777 +#define _GUARD_IP_RETURN_GENERATOR_r00 778 +#define _GUARD_IP_RETURN_GENERATOR_r11 779 +#define _GUARD_IP_RETURN_GENERATOR_r22 780 +#define _GUARD_IP_RETURN_GENERATOR_r33 781 +#define _GUARD_IP_RETURN_VALUE_r00 782 +#define _GUARD_IP_RETURN_VALUE_r11 783 +#define _GUARD_IP_RETURN_VALUE_r22 784 +#define _GUARD_IP_RETURN_VALUE_r33 785 +#define _GUARD_IP_YIELD_VALUE_r00 786 +#define _GUARD_IP_YIELD_VALUE_r11 787 +#define _GUARD_IP_YIELD_VALUE_r22 788 +#define _GUARD_IP_YIELD_VALUE_r33 789 +#define _GUARD_IP__PUSH_FRAME_r00 790 +#define _GUARD_IP__PUSH_FRAME_r11 791 +#define _GUARD_IP__PUSH_FRAME_r22 792 +#define _GUARD_IP__PUSH_FRAME_r33 793 +#define _GUARD_IS_FALSE_POP_r00 794 +#define _GUARD_IS_FALSE_POP_r10 795 +#define _GUARD_IS_FALSE_POP_r21 796 +#define _GUARD_IS_FALSE_POP_r32 797 +#define _GUARD_IS_NONE_POP_r00 798 +#define _GUARD_IS_NONE_POP_r10 799 +#define _GUARD_IS_NONE_POP_r21 800 +#define _GUARD_IS_NONE_POP_r32 801 +#define _GUARD_IS_NOT_NONE_POP_r10 802 +#define _GUARD_IS_TRUE_POP_r00 803 +#define _GUARD_IS_TRUE_POP_r10 804 +#define _GUARD_IS_TRUE_POP_r21 805 +#define _GUARD_IS_TRUE_POP_r32 806 +#define _GUARD_KEYS_VERSION_r01 807 +#define _GUARD_KEYS_VERSION_r11 808 +#define _GUARD_KEYS_VERSION_r22 809 +#define _GUARD_KEYS_VERSION_r33 810 +#define _GUARD_NOS_DICT_r02 811 +#define _GUARD_NOS_DICT_r12 812 +#define _GUARD_NOS_DICT_r22 813 +#define _GUARD_NOS_DICT_r33 814 +#define _GUARD_NOS_FLOAT_r02 815 +#define _GUARD_NOS_FLOAT_r12 816 +#define _GUARD_NOS_FLOAT_r22 817 +#define _GUARD_NOS_FLOAT_r33 818 +#define _GUARD_NOS_INT_r02 819 +#define _GUARD_NOS_INT_r12 820 +#define _GUARD_NOS_INT_r22 821 +#define _GUARD_NOS_INT_r33 822 +#define _GUARD_NOS_LIST_r02 823 +#define _GUARD_NOS_LIST_r12 824 +#define _GUARD_NOS_LIST_r22 825 +#define _GUARD_NOS_LIST_r33 826 +#define _GUARD_NOS_NOT_NULL_r02 827 +#define _GUARD_NOS_NOT_NULL_r12 828 +#define _GUARD_NOS_NOT_NULL_r22 829 +#define _GUARD_NOS_NOT_NULL_r33 830 +#define _GUARD_NOS_NULL_r02 831 +#define _GUARD_NOS_NULL_r12 832 +#define _GUARD_NOS_NULL_r22 833 +#define _GUARD_NOS_NULL_r33 834 +#define _GUARD_NOS_OVERFLOWED_r02 835 +#define _GUARD_NOS_OVERFLOWED_r12 836 +#define _GUARD_NOS_OVERFLOWED_r22 837 +#define _GUARD_NOS_OVERFLOWED_r33 838 +#define _GUARD_NOS_TUPLE_r02 839 +#define _GUARD_NOS_TUPLE_r12 840 +#define _GUARD_NOS_TUPLE_r22 841 +#define _GUARD_NOS_TUPLE_r33 842 +#define _GUARD_NOS_UNICODE_r02 843 +#define _GUARD_NOS_UNICODE_r12 844 +#define _GUARD_NOS_UNICODE_r22 845 +#define _GUARD_NOS_UNICODE_r33 846 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 847 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 848 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 849 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 850 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 851 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 852 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 853 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 854 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 855 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 856 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 857 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 858 +#define _GUARD_THIRD_NULL_r03 859 +#define _GUARD_THIRD_NULL_r13 860 +#define _GUARD_THIRD_NULL_r23 861 +#define _GUARD_THIRD_NULL_r33 862 +#define _GUARD_TOS_ANY_SET_r01 863 +#define _GUARD_TOS_ANY_SET_r11 864 +#define _GUARD_TOS_ANY_SET_r22 865 +#define _GUARD_TOS_ANY_SET_r33 866 +#define _GUARD_TOS_DICT_r01 867 +#define _GUARD_TOS_DICT_r11 868 +#define _GUARD_TOS_DICT_r22 869 +#define _GUARD_TOS_DICT_r33 870 +#define _GUARD_TOS_FLOAT_r01 871 +#define _GUARD_TOS_FLOAT_r11 872 +#define _GUARD_TOS_FLOAT_r22 873 +#define _GUARD_TOS_FLOAT_r33 874 +#define _GUARD_TOS_INT_r01 875 +#define _GUARD_TOS_INT_r11 876 +#define _GUARD_TOS_INT_r22 877 +#define _GUARD_TOS_INT_r33 878 +#define _GUARD_TOS_LIST_r01 879 +#define _GUARD_TOS_LIST_r11 880 +#define _GUARD_TOS_LIST_r22 881 +#define _GUARD_TOS_LIST_r33 882 +#define _GUARD_TOS_OVERFLOWED_r01 883 +#define _GUARD_TOS_OVERFLOWED_r11 884 +#define _GUARD_TOS_OVERFLOWED_r22 885 +#define _GUARD_TOS_OVERFLOWED_r33 886 +#define _GUARD_TOS_SLICE_r01 887 +#define _GUARD_TOS_SLICE_r11 888 +#define _GUARD_TOS_SLICE_r22 889 +#define _GUARD_TOS_SLICE_r33 890 +#define _GUARD_TOS_TUPLE_r01 891 +#define _GUARD_TOS_TUPLE_r11 892 +#define _GUARD_TOS_TUPLE_r22 893 +#define _GUARD_TOS_TUPLE_r33 894 +#define _GUARD_TOS_UNICODE_r01 895 +#define _GUARD_TOS_UNICODE_r11 896 +#define _GUARD_TOS_UNICODE_r22 897 +#define _GUARD_TOS_UNICODE_r33 898 +#define _GUARD_TYPE_VERSION_r01 899 +#define _GUARD_TYPE_VERSION_r11 900 +#define _GUARD_TYPE_VERSION_r22 901 +#define _GUARD_TYPE_VERSION_r33 902 +#define _GUARD_TYPE_VERSION_AND_LOCK_r01 903 +#define _GUARD_TYPE_VERSION_AND_LOCK_r11 904 +#define _GUARD_TYPE_VERSION_AND_LOCK_r22 905 +#define _GUARD_TYPE_VERSION_AND_LOCK_r33 906 +#define _HANDLE_PENDING_AND_DEOPT_r00 907 +#define _HANDLE_PENDING_AND_DEOPT_r10 908 +#define _HANDLE_PENDING_AND_DEOPT_r20 909 +#define _HANDLE_PENDING_AND_DEOPT_r30 910 +#define _IMPORT_FROM_r12 911 +#define _IMPORT_NAME_r21 912 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 913 +#define _INIT_CALL_PY_EXACT_ARGS_r01 914 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 915 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 916 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 917 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 918 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 919 +#define _INSERT_NULL_r10 920 +#define _INSTRUMENTED_FOR_ITER_r23 921 +#define _INSTRUMENTED_INSTRUCTION_r00 922 +#define _INSTRUMENTED_JUMP_FORWARD_r00 923 +#define _INSTRUMENTED_JUMP_FORWARD_r11 924 +#define _INSTRUMENTED_JUMP_FORWARD_r22 925 +#define _INSTRUMENTED_JUMP_FORWARD_r33 926 +#define _INSTRUMENTED_LINE_r00 927 +#define _INSTRUMENTED_NOT_TAKEN_r00 928 +#define _INSTRUMENTED_NOT_TAKEN_r11 929 +#define _INSTRUMENTED_NOT_TAKEN_r22 930 +#define _INSTRUMENTED_NOT_TAKEN_r33 931 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 932 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 933 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 934 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 935 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 936 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 937 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 938 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 939 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 940 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 941 +#define _IS_NONE_r11 942 +#define _IS_OP_r21 943 +#define _ITER_CHECK_LIST_r02 944 +#define _ITER_CHECK_LIST_r12 945 +#define _ITER_CHECK_LIST_r22 946 +#define _ITER_CHECK_LIST_r33 947 +#define _ITER_CHECK_RANGE_r02 948 +#define _ITER_CHECK_RANGE_r12 949 +#define _ITER_CHECK_RANGE_r22 950 +#define _ITER_CHECK_RANGE_r33 951 +#define _ITER_CHECK_TUPLE_r02 952 +#define _ITER_CHECK_TUPLE_r12 953 +#define _ITER_CHECK_TUPLE_r22 954 +#define _ITER_CHECK_TUPLE_r33 955 +#define _ITER_JUMP_LIST_r02 956 +#define _ITER_JUMP_LIST_r12 957 +#define _ITER_JUMP_LIST_r22 958 +#define _ITER_JUMP_LIST_r33 959 +#define _ITER_JUMP_RANGE_r02 960 +#define _ITER_JUMP_RANGE_r12 961 +#define _ITER_JUMP_RANGE_r22 962 +#define _ITER_JUMP_RANGE_r33 963 +#define _ITER_JUMP_TUPLE_r02 964 +#define _ITER_JUMP_TUPLE_r12 965 +#define _ITER_JUMP_TUPLE_r22 966 +#define _ITER_JUMP_TUPLE_r33 967 +#define _ITER_NEXT_LIST_r23 968 +#define _ITER_NEXT_LIST_TIER_TWO_r23 969 +#define _ITER_NEXT_RANGE_r03 970 +#define _ITER_NEXT_RANGE_r13 971 +#define _ITER_NEXT_RANGE_r23 972 +#define _ITER_NEXT_TUPLE_r03 973 +#define _ITER_NEXT_TUPLE_r13 974 +#define _ITER_NEXT_TUPLE_r23 975 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 976 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 977 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 978 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 979 +#define _JUMP_TO_TOP_r00 980 +#define _LIST_APPEND_r10 981 +#define _LIST_EXTEND_r10 982 +#define _LOAD_ATTR_r10 983 +#define _LOAD_ATTR_CLASS_r11 984 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 985 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 986 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 987 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 988 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 989 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 990 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 991 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 992 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 993 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 994 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 995 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 996 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 997 +#define _LOAD_ATTR_MODULE_r11 998 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 999 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1000 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1001 +#define _LOAD_ATTR_SLOT_r11 1002 +#define _LOAD_ATTR_WITH_HINT_r11 1003 +#define _LOAD_BUILD_CLASS_r01 1004 +#define _LOAD_BYTECODE_r00 1005 +#define _LOAD_COMMON_CONSTANT_r01 1006 +#define _LOAD_COMMON_CONSTANT_r12 1007 +#define _LOAD_COMMON_CONSTANT_r23 1008 +#define _LOAD_CONST_r01 1009 +#define _LOAD_CONST_r12 1010 +#define _LOAD_CONST_r23 1011 +#define _LOAD_CONST_INLINE_r01 1012 +#define _LOAD_CONST_INLINE_r12 1013 +#define _LOAD_CONST_INLINE_r23 1014 +#define _LOAD_CONST_INLINE_BORROW_r01 1015 +#define _LOAD_CONST_INLINE_BORROW_r12 1016 +#define _LOAD_CONST_INLINE_BORROW_r23 1017 +#define _LOAD_CONST_UNDER_INLINE_r02 1018 +#define _LOAD_CONST_UNDER_INLINE_r12 1019 +#define _LOAD_CONST_UNDER_INLINE_r23 1020 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r02 1021 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r12 1022 +#define _LOAD_CONST_UNDER_INLINE_BORROW_r23 1023 +#define _LOAD_DEREF_r01 1024 +#define _LOAD_FAST_r01 1025 +#define _LOAD_FAST_r12 1026 +#define _LOAD_FAST_r23 1027 +#define _LOAD_FAST_0_r01 1028 +#define _LOAD_FAST_0_r12 1029 +#define _LOAD_FAST_0_r23 1030 +#define _LOAD_FAST_1_r01 1031 +#define _LOAD_FAST_1_r12 1032 +#define _LOAD_FAST_1_r23 1033 +#define _LOAD_FAST_2_r01 1034 +#define _LOAD_FAST_2_r12 1035 +#define _LOAD_FAST_2_r23 1036 +#define _LOAD_FAST_3_r01 1037 +#define _LOAD_FAST_3_r12 1038 +#define _LOAD_FAST_3_r23 1039 +#define _LOAD_FAST_4_r01 1040 +#define _LOAD_FAST_4_r12 1041 +#define _LOAD_FAST_4_r23 1042 +#define _LOAD_FAST_5_r01 1043 +#define _LOAD_FAST_5_r12 1044 +#define _LOAD_FAST_5_r23 1045 +#define _LOAD_FAST_6_r01 1046 +#define _LOAD_FAST_6_r12 1047 +#define _LOAD_FAST_6_r23 1048 +#define _LOAD_FAST_7_r01 1049 +#define _LOAD_FAST_7_r12 1050 +#define _LOAD_FAST_7_r23 1051 +#define _LOAD_FAST_AND_CLEAR_r01 1052 +#define _LOAD_FAST_AND_CLEAR_r12 1053 +#define _LOAD_FAST_AND_CLEAR_r23 1054 +#define _LOAD_FAST_BORROW_r01 1055 +#define _LOAD_FAST_BORROW_r12 1056 +#define _LOAD_FAST_BORROW_r23 1057 +#define _LOAD_FAST_BORROW_0_r01 1058 +#define _LOAD_FAST_BORROW_0_r12 1059 +#define _LOAD_FAST_BORROW_0_r23 1060 +#define _LOAD_FAST_BORROW_1_r01 1061 +#define _LOAD_FAST_BORROW_1_r12 1062 +#define _LOAD_FAST_BORROW_1_r23 1063 +#define _LOAD_FAST_BORROW_2_r01 1064 +#define _LOAD_FAST_BORROW_2_r12 1065 +#define _LOAD_FAST_BORROW_2_r23 1066 +#define _LOAD_FAST_BORROW_3_r01 1067 +#define _LOAD_FAST_BORROW_3_r12 1068 +#define _LOAD_FAST_BORROW_3_r23 1069 +#define _LOAD_FAST_BORROW_4_r01 1070 +#define _LOAD_FAST_BORROW_4_r12 1071 +#define _LOAD_FAST_BORROW_4_r23 1072 +#define _LOAD_FAST_BORROW_5_r01 1073 +#define _LOAD_FAST_BORROW_5_r12 1074 +#define _LOAD_FAST_BORROW_5_r23 1075 +#define _LOAD_FAST_BORROW_6_r01 1076 +#define _LOAD_FAST_BORROW_6_r12 1077 +#define _LOAD_FAST_BORROW_6_r23 1078 +#define _LOAD_FAST_BORROW_7_r01 1079 +#define _LOAD_FAST_BORROW_7_r12 1080 +#define _LOAD_FAST_BORROW_7_r23 1081 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1082 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1083 +#define _LOAD_FAST_CHECK_r01 1084 +#define _LOAD_FAST_CHECK_r12 1085 +#define _LOAD_FAST_CHECK_r23 1086 +#define _LOAD_FAST_LOAD_FAST_r02 1087 +#define _LOAD_FAST_LOAD_FAST_r13 1088 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1089 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1090 +#define _LOAD_GLOBAL_r00 1091 +#define _LOAD_GLOBAL_BUILTINS_r01 1092 +#define _LOAD_GLOBAL_MODULE_r01 1093 +#define _LOAD_LOCALS_r01 1094 +#define _LOAD_LOCALS_r12 1095 +#define _LOAD_LOCALS_r23 1096 +#define _LOAD_NAME_r01 1097 +#define _LOAD_SMALL_INT_r01 1098 +#define _LOAD_SMALL_INT_r12 1099 +#define _LOAD_SMALL_INT_r23 1100 +#define _LOAD_SMALL_INT_0_r01 1101 +#define _LOAD_SMALL_INT_0_r12 1102 +#define _LOAD_SMALL_INT_0_r23 1103 +#define _LOAD_SMALL_INT_1_r01 1104 +#define _LOAD_SMALL_INT_1_r12 1105 +#define _LOAD_SMALL_INT_1_r23 1106 +#define _LOAD_SMALL_INT_2_r01 1107 +#define _LOAD_SMALL_INT_2_r12 1108 +#define _LOAD_SMALL_INT_2_r23 1109 +#define _LOAD_SMALL_INT_3_r01 1110 +#define _LOAD_SMALL_INT_3_r12 1111 +#define _LOAD_SMALL_INT_3_r23 1112 +#define _LOAD_SPECIAL_r00 1113 +#define _LOAD_SUPER_ATTR_ATTR_r31 1114 +#define _LOAD_SUPER_ATTR_METHOD_r32 1115 +#define _MAKE_CALLARGS_A_TUPLE_r33 1116 +#define _MAKE_CELL_r00 1117 +#define _MAKE_FUNCTION_r11 1118 +#define _MAKE_WARM_r00 1119 +#define _MAKE_WARM_r11 1120 +#define _MAKE_WARM_r22 1121 +#define _MAKE_WARM_r33 1122 +#define _MAP_ADD_r20 1123 +#define _MATCH_CLASS_r31 1124 +#define _MATCH_KEYS_r23 1125 +#define _MATCH_MAPPING_r02 1126 +#define _MATCH_MAPPING_r12 1127 +#define _MATCH_MAPPING_r23 1128 +#define _MATCH_SEQUENCE_r02 1129 +#define _MATCH_SEQUENCE_r12 1130 +#define _MATCH_SEQUENCE_r23 1131 +#define _MAYBE_EXPAND_METHOD_r00 1132 +#define _MAYBE_EXPAND_METHOD_KW_r11 1133 +#define _MONITOR_CALL_r00 1134 +#define _MONITOR_CALL_KW_r11 1135 +#define _MONITOR_JUMP_BACKWARD_r00 1136 +#define _MONITOR_JUMP_BACKWARD_r11 1137 +#define _MONITOR_JUMP_BACKWARD_r22 1138 +#define _MONITOR_JUMP_BACKWARD_r33 1139 +#define _MONITOR_RESUME_r00 1140 +#define _NOP_r00 1141 +#define _NOP_r11 1142 +#define _NOP_r22 1143 +#define _NOP_r33 1144 +#define _POP_CALL_r20 1145 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW_r21 1146 +#define _POP_CALL_ONE_r30 1147 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW_r31 1148 +#define _POP_CALL_TWO_r30 1149 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW_r31 1150 +#define _POP_EXCEPT_r10 1151 +#define _POP_ITER_r20 1152 +#define _POP_JUMP_IF_FALSE_r00 1153 +#define _POP_JUMP_IF_FALSE_r10 1154 +#define _POP_JUMP_IF_FALSE_r21 1155 +#define _POP_JUMP_IF_FALSE_r32 1156 +#define _POP_JUMP_IF_TRUE_r00 1157 +#define _POP_JUMP_IF_TRUE_r10 1158 +#define _POP_JUMP_IF_TRUE_r21 1159 +#define _POP_JUMP_IF_TRUE_r32 1160 +#define _POP_TOP_r10 1161 +#define _POP_TOP_FLOAT_r00 1162 +#define _POP_TOP_FLOAT_r10 1163 +#define _POP_TOP_FLOAT_r21 1164 +#define _POP_TOP_FLOAT_r32 1165 +#define _POP_TOP_INT_r00 1166 +#define _POP_TOP_INT_r10 1167 +#define _POP_TOP_INT_r21 1168 +#define _POP_TOP_INT_r32 1169 +#define _POP_TOP_LOAD_CONST_INLINE_r11 1170 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW_r11 1171 +#define _POP_TOP_NOP_r00 1172 +#define _POP_TOP_NOP_r10 1173 +#define _POP_TOP_NOP_r21 1174 +#define _POP_TOP_NOP_r32 1175 +#define _POP_TOP_UNICODE_r00 1176 +#define _POP_TOP_UNICODE_r10 1177 +#define _POP_TOP_UNICODE_r21 1178 +#define _POP_TOP_UNICODE_r32 1179 +#define _POP_TWO_r20 1180 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW_r21 1181 +#define _PUSH_EXC_INFO_r02 1182 +#define _PUSH_EXC_INFO_r12 1183 +#define _PUSH_EXC_INFO_r23 1184 +#define _PUSH_FRAME_r10 1185 +#define _PUSH_NULL_r01 1186 +#define _PUSH_NULL_r12 1187 +#define _PUSH_NULL_r23 1188 +#define _PUSH_NULL_CONDITIONAL_r00 1189 +#define _PY_FRAME_GENERAL_r01 1190 +#define _PY_FRAME_KW_r11 1191 +#define _QUICKEN_RESUME_r00 1192 +#define _QUICKEN_RESUME_r11 1193 +#define _QUICKEN_RESUME_r22 1194 +#define _QUICKEN_RESUME_r33 1195 +#define _REPLACE_WITH_TRUE_r11 1196 +#define _RESUME_CHECK_r00 1197 +#define _RESUME_CHECK_r11 1198 +#define _RESUME_CHECK_r22 1199 +#define _RESUME_CHECK_r33 1200 +#define _RETURN_GENERATOR_r01 1201 +#define _RETURN_VALUE_r11 1202 +#define _SAVE_RETURN_OFFSET_r00 1203 +#define _SAVE_RETURN_OFFSET_r11 1204 +#define _SAVE_RETURN_OFFSET_r22 1205 +#define _SAVE_RETURN_OFFSET_r33 1206 +#define _SEND_r22 1207 +#define _SEND_GEN_FRAME_r22 1208 +#define _SETUP_ANNOTATIONS_r00 1209 +#define _SET_ADD_r10 1210 +#define _SET_FUNCTION_ATTRIBUTE_r01 1211 +#define _SET_FUNCTION_ATTRIBUTE_r11 1212 +#define _SET_FUNCTION_ATTRIBUTE_r21 1213 +#define _SET_FUNCTION_ATTRIBUTE_r32 1214 +#define _SET_IP_r00 1215 +#define _SET_IP_r11 1216 +#define _SET_IP_r22 1217 +#define _SET_IP_r33 1218 +#define _SET_UPDATE_r10 1219 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1220 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1221 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1222 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1223 +#define _SPILL_OR_RELOAD_r01 1224 +#define _SPILL_OR_RELOAD_r02 1225 +#define _SPILL_OR_RELOAD_r03 1226 +#define _SPILL_OR_RELOAD_r10 1227 +#define _SPILL_OR_RELOAD_r12 1228 +#define _SPILL_OR_RELOAD_r13 1229 +#define _SPILL_OR_RELOAD_r20 1230 +#define _SPILL_OR_RELOAD_r21 1231 +#define _SPILL_OR_RELOAD_r23 1232 +#define _SPILL_OR_RELOAD_r30 1233 +#define _SPILL_OR_RELOAD_r31 1234 +#define _SPILL_OR_RELOAD_r32 1235 +#define _START_EXECUTOR_r00 1236 +#define _STORE_ATTR_r20 1237 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1238 +#define _STORE_ATTR_SLOT_r21 1239 +#define _STORE_ATTR_WITH_HINT_r21 1240 +#define _STORE_DEREF_r10 1241 +#define _STORE_FAST_r10 1242 +#define _STORE_FAST_0_r10 1243 +#define _STORE_FAST_1_r10 1244 +#define _STORE_FAST_2_r10 1245 +#define _STORE_FAST_3_r10 1246 +#define _STORE_FAST_4_r10 1247 +#define _STORE_FAST_5_r10 1248 +#define _STORE_FAST_6_r10 1249 +#define _STORE_FAST_7_r10 1250 +#define _STORE_FAST_LOAD_FAST_r11 1251 +#define _STORE_FAST_STORE_FAST_r20 1252 +#define _STORE_GLOBAL_r10 1253 +#define _STORE_NAME_r10 1254 +#define _STORE_SLICE_r30 1255 +#define _STORE_SUBSCR_r30 1256 +#define _STORE_SUBSCR_DICT_r31 1257 +#define _STORE_SUBSCR_LIST_INT_r32 1258 +#define _SWAP_r11 1259 +#define _SWAP_2_r02 1260 +#define _SWAP_2_r12 1261 +#define _SWAP_2_r22 1262 +#define _SWAP_2_r33 1263 +#define _SWAP_3_r03 1264 +#define _SWAP_3_r13 1265 +#define _SWAP_3_r23 1266 +#define _SWAP_3_r33 1267 +#define _TIER2_RESUME_CHECK_r00 1268 +#define _TIER2_RESUME_CHECK_r11 1269 +#define _TIER2_RESUME_CHECK_r22 1270 +#define _TIER2_RESUME_CHECK_r33 1271 +#define _TO_BOOL_r11 1272 +#define _TO_BOOL_BOOL_r01 1273 +#define _TO_BOOL_BOOL_r11 1274 +#define _TO_BOOL_BOOL_r22 1275 +#define _TO_BOOL_BOOL_r33 1276 +#define _TO_BOOL_INT_r11 1277 +#define _TO_BOOL_LIST_r11 1278 +#define _TO_BOOL_NONE_r01 1279 +#define _TO_BOOL_NONE_r11 1280 +#define _TO_BOOL_NONE_r22 1281 +#define _TO_BOOL_NONE_r33 1282 +#define _TO_BOOL_STR_r11 1283 +#define _TRACE_RECORD_r00 1284 +#define _UNARY_INVERT_r11 1285 +#define _UNARY_NEGATIVE_r11 1286 +#define _UNARY_NOT_r01 1287 +#define _UNARY_NOT_r11 1288 +#define _UNARY_NOT_r22 1289 +#define _UNARY_NOT_r33 1290 +#define _UNPACK_EX_r10 1291 +#define _UNPACK_SEQUENCE_r10 1292 +#define _UNPACK_SEQUENCE_LIST_r10 1293 +#define _UNPACK_SEQUENCE_TUPLE_r10 1294 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1295 +#define _WITH_EXCEPT_START_r33 1296 +#define _YIELD_VALUE_r11 1297 +#define MAX_UOP_REGS_ID 1297 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 1281eeb041daab..ec374dd5818432 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -2131,10 +2131,10 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { }, }, [_FOR_ITER_GEN_FRAME] = { - .best = { 2, 2, 2, 2 }, + .best = { 0, 1, 2, 2 }, .entries = { - { -1, -1, -1 }, - { -1, -1, -1 }, + { 3, 0, _FOR_ITER_GEN_FRAME_r03 }, + { 3, 1, _FOR_ITER_GEN_FRAME_r13 }, { 3, 2, _FOR_ITER_GEN_FRAME_r23 }, { -1, -1, -1 }, }, @@ -3620,6 +3620,8 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_ITER_NEXT_RANGE_r03] = _ITER_NEXT_RANGE, [_ITER_NEXT_RANGE_r13] = _ITER_NEXT_RANGE, [_ITER_NEXT_RANGE_r23] = _ITER_NEXT_RANGE, + [_FOR_ITER_GEN_FRAME_r03] = _FOR_ITER_GEN_FRAME, + [_FOR_ITER_GEN_FRAME_r13] = _FOR_ITER_GEN_FRAME, [_FOR_ITER_GEN_FRAME_r23] = _FOR_ITER_GEN_FRAME, [_INSERT_NULL_r10] = _INSERT_NULL, [_LOAD_SPECIAL_r00] = _LOAD_SPECIAL, @@ -4182,6 +4184,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_FORMAT_WITH_SPEC] = "_FORMAT_WITH_SPEC", [_FORMAT_WITH_SPEC_r21] = "_FORMAT_WITH_SPEC_r21", [_FOR_ITER_GEN_FRAME] = "_FOR_ITER_GEN_FRAME", + [_FOR_ITER_GEN_FRAME_r03] = "_FOR_ITER_GEN_FRAME_r03", + [_FOR_ITER_GEN_FRAME_r13] = "_FOR_ITER_GEN_FRAME_r13", [_FOR_ITER_GEN_FRAME_r23] = "_FOR_ITER_GEN_FRAME_r23", [_FOR_ITER_TIER_TWO] = "_FOR_ITER_TIER_TWO", [_FOR_ITER_TIER_TWO_r23] = "_FOR_ITER_TIER_TWO_r23", diff --git a/Lib/test/test_free_threading/test_generators.py b/Lib/test/test_free_threading/test_generators.py index d01675eb38b370..11f59301bcd51d 100644 --- a/Lib/test/test_free_threading/test_generators.py +++ b/Lib/test/test_free_threading/test_generators.py @@ -49,3 +49,74 @@ def test_concurrent_write(self): self.concurrent_write_with_func(func=set_gen_name) with self.subTest(func=set_gen_qualname): self.concurrent_write_with_func(func=set_gen_qualname) + + def test_concurrent_send(self): + def gen(): + yield 1 + yield 2 + yield 3 + yield 4 + yield 5 + + def run_test(drive_generator): + g = gen() + values = [] + threading_helper.run_concurrently(drive_generator, self.NUM_THREADS, args=(g, values,)) + self.assertEqual(sorted(values), [1, 2, 3, 4, 5]) + + def call_next(g, values): + while True: + try: + values.append(next(g)) + except ValueError: + continue + except StopIteration: + break + + with self.subTest(method='next'): + run_test(call_next) + + def call_send(g, values): + while True: + try: + values.append(g.send(None)) + except ValueError: + continue + except StopIteration: + break + + with self.subTest(method='send'): + run_test(call_send) + + def for_iter_gen(g, values): + while True: + try: + for value in g: + values.append(value) + else: + break + except ValueError: + continue + + with self.subTest(method='for'): + run_test(for_iter_gen) + + def test_concurrent_close(self): + def gen(): + for i in range(10): + yield i + time.sleep(0.001) + + def drive_generator(g): + while True: + try: + for value in g: + if value == 5: + g.close() + else: + return + except ValueError as e: + self.assertEqual(e.args[0], "generator already executing") + + g = gen() + threading_helper.run_concurrently(drive_generator, self.NUM_THREADS, args=(g,)) diff --git a/Objects/genobject.c b/Objects/genobject.c index 3694198289de8c..508d215a0cfe64 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -36,6 +36,14 @@ static PyObject* async_gen_athrow_new(PyAsyncGenObject *, PyObject *); #define _PyAsyncGenObject_CAST(op) \ _Py_CAST(PyAsyncGenObject*, (op)) +#ifdef Py_GIL_DISABLED +# define _Py_GEN_TRY_SET_FRAME_STATE(gen, expected, state) \ + _Py_atomic_compare_exchange_int8(&(gen)->gi_frame_state, &expected, (state)) +#else +# define _Py_GEN_TRY_SET_FRAME_STATE(gen, expected, state) \ + ((gen)->gi_frame_state = (state), true) +#endif + static const char *NON_INIT_CORO_MSG = "can't send non-None value to a " "just-started coroutine"; @@ -145,10 +153,7 @@ _PyGen_Finalize(PyObject *self) static void gen_clear_frame(PyGenObject *gen) { - if (gen->gi_frame_state == FRAME_CLEARED) - return; - - gen->gi_frame_state = FRAME_CLEARED; + assert(gen->gi_frame_state == FRAME_CLEARED); _PyInterpreterFrame *frame = &gen->gi_iframe; frame->previous = NULL; _PyFrame_ClearExceptCode(frame); @@ -179,7 +184,10 @@ gen_dealloc(PyObject *self) if (PyCoro_CheckExact(gen)) { Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer); } - gen_clear_frame(gen); + if (gen->gi_frame_state != FRAME_CLEARED) { + gen->gi_frame_state = FRAME_CLEARED; + gen_clear_frame(gen); + } assert(gen->gi_exc_state.exc_value == NULL); PyStackRef_CLEAR(gen->gi_iframe.f_executable); Py_CLEAR(gen->gi_name); @@ -188,58 +196,31 @@ gen_dealloc(PyObject *self) PyObject_GC_Del(gen); } -static PySendResult -gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, - int exc, int closing) +static void +gen_raise_already_executing_error(PyGenObject *gen) { - PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *frame = &gen->gi_iframe; - - *presult = NULL; - if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) { - const char *msg = "can't send non-None value to a " - "just-started generator"; - if (PyCoro_CheckExact(gen)) { - msg = NON_INIT_CORO_MSG; - } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "can't send non-None value to a " - "just-started async generator"; - } - PyErr_SetString(PyExc_TypeError, msg); - return PYGEN_ERROR; - } - if (gen->gi_frame_state == FRAME_EXECUTING) { - const char *msg = "generator already executing"; - if (PyCoro_CheckExact(gen)) { - msg = "coroutine already executing"; - } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "async generator already executing"; - } - PyErr_SetString(PyExc_ValueError, msg); - return PYGEN_ERROR; + const char *msg = "generator already executing"; + if (PyCoro_CheckExact(gen)) { + msg = "coroutine already executing"; } - if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { - if (PyCoro_CheckExact(gen) && !closing) { - /* `gen` is an exhausted coroutine: raise an error, - except when called from gen_close(), which should - always be a silent method. */ - PyErr_SetString( - PyExc_RuntimeError, - "cannot reuse already awaited coroutine"); - } - else if (arg && !exc) { - /* `gen` is an exhausted generator: - only return value if called from send(). */ - *presult = Py_NewRef(Py_None); - return PYGEN_RETURN; - } - return PYGEN_ERROR; + else if (PyAsyncGen_CheckExact(gen)) { + msg = "async generator already executing"; } + PyErr_SetString(PyExc_ValueError, msg); +} + +// Send 'arg' into 'gen'. On success, return PYGEN_NEXT or PYGEN_RETURN. +// Returns PYGEN_ERROR on failure. 'presult' is set to the yielded or +// returned value. +// The generator must be in the FRAME_EXECUTING state when this function +// is called. +static PySendResult +gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, int exc) +{ + assert(FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state) == FRAME_EXECUTING); - assert((gen->gi_frame_state == FRAME_CREATED) || - FRAME_STATE_SUSPENDED(gen->gi_frame_state)); + PyThreadState *tstate = _PyThreadState_GET(); + _PyInterpreterFrame *frame = &gen->gi_iframe; /* Push arg onto the frame's value stack */ PyObject *arg_obj = arg ? arg : Py_None; @@ -254,21 +235,34 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, _PyErr_ChainStackItem(); } - gen->gi_frame_state = FRAME_EXECUTING; EVAL_CALL_STAT_INC(EVAL_CALL_GENERATOR); PyObject *result = _PyEval_EvalFrame(tstate, frame, exc); assert(tstate->exc_info == prev_exc_info); +#ifndef Py_GIL_DISABLED assert(gen->gi_exc_state.previous_item == NULL); - assert(gen->gi_frame_state != FRAME_EXECUTING); assert(frame->previous == NULL); + assert(gen->gi_frame_state != FRAME_EXECUTING); +#endif + + // The generator_return_kind field is used to distinguish between a + // yield and a return from within _PyEval_EvalFrame(). Earlier versions + // of CPython (prior to 3.15) used gi_frame_state for this purpose, but + // that requires the GIL for thread-safety. + int return_kind = ((_PyThreadStateImpl *)tstate)->generator_return_kind; + + if (return_kind == GENERATOR_YIELD) { + assert(result != NULL && !_PyErr_Occurred(tstate)); + *presult = result; + return PYGEN_NEXT; + } + + assert(return_kind == GENERATOR_RETURN); + assert(gen->gi_exc_state.exc_value == NULL); + assert(FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state) == FRAME_CLEARED); /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ if (result) { - if (FRAME_STATE_SUSPENDED(gen->gi_frame_state)) { - *presult = result; - return PYGEN_NEXT; - } assert(result == Py_None || !PyAsyncGen_CheckExact(gen)); if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) { /* Return NULL if called by gen_iternext() */ @@ -281,37 +275,82 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, !PyErr_ExceptionMatches(PyExc_StopAsyncIteration)); } - assert(gen->gi_exc_state.exc_value == NULL); - assert(gen->gi_frame_state == FRAME_CLEARED); *presult = result; return result ? PYGEN_RETURN : PYGEN_ERROR; } +// Set the generator 'gen' to the executing state and send 'arg' into it. +// See gen_send_ex2() for details. +static PySendResult +gen_send_ex(PyGenObject *gen, PyObject *arg, PyObject **presult) +{ + *presult = NULL; + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + do { + if (frame_state == FRAME_CREATED && arg && arg != Py_None) { + const char *msg = "can't send non-None value to a " + "just-started generator"; + if (PyCoro_CheckExact(gen)) { + msg = NON_INIT_CORO_MSG; + } + else if (PyAsyncGen_CheckExact(gen)) { + msg = "can't send non-None value to a " + "just-started async generator"; + } + PyErr_SetString(PyExc_TypeError, msg); + return PYGEN_ERROR; + } + if (frame_state == FRAME_EXECUTING) { + gen_raise_already_executing_error(gen); + return PYGEN_ERROR; + } + if (FRAME_STATE_FINISHED(frame_state)) { + if (PyCoro_CheckExact(gen)) { + /* `gen` is an exhausted coroutine: raise an error, + except when called from gen_close(), which should + always be a silent method. */ + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited coroutine"); + } + else if (arg) { + /* `gen` is an exhausted generator: + only return value if called from send(). */ + *presult = Py_None; + return PYGEN_RETURN; + } + return PYGEN_ERROR; + } + + assert((frame_state == FRAME_CREATED) || + FRAME_STATE_SUSPENDED(frame_state)); + } while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING)); + + return gen_send_ex2(gen, arg, presult, 0); +} + static PySendResult PyGen_am_send(PyObject *self, PyObject *arg, PyObject **result) { PyGenObject *gen = _PyGen_CAST(self); - return gen_send_ex2(gen, arg, result, 0, 0); + return gen_send_ex(gen, arg, result); } static PyObject * -gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing) +gen_set_stop_iteration(PyGenObject *gen, PyObject *result) { - PyObject *result; - if (gen_send_ex2(gen, arg, &result, exc, closing) == PYGEN_RETURN) { - if (PyAsyncGen_CheckExact(gen)) { - assert(result == Py_None); - PyErr_SetNone(PyExc_StopAsyncIteration); - } - else if (result == Py_None) { - PyErr_SetNone(PyExc_StopIteration); - } - else { - _PyGen_SetStopIterationValue(result); - } - Py_CLEAR(result); + if (PyAsyncGen_CheckExact(gen)) { + assert(result == Py_None); + PyErr_SetNone(PyExc_StopAsyncIteration); } - return result; + else if (result == Py_None) { + PyErr_SetNone(PyExc_StopIteration); + } + else { + _PyGen_SetStopIterationValue(result); + } + Py_DECREF(result); + return NULL; } PyDoc_STRVAR(send_doc, @@ -319,9 +358,14 @@ PyDoc_STRVAR(send_doc, return next yielded value or raise StopIteration."); static PyObject * -gen_send(PyObject *gen, PyObject *arg) +gen_send(PyObject *op, PyObject *arg) { - return gen_send_ex((PyGenObject*)gen, arg, 0, 0); + PyObject *result; + PyGenObject *gen = _PyGen_CAST(op); + if (gen_send_ex(gen, arg, &result) == PYGEN_RETURN) { + return gen_set_stop_iteration(gen, result); + } + return result; } PyDoc_STRVAR(close_doc, @@ -370,43 +414,43 @@ is_resume(_Py_CODEUNIT *instr) ); } -PyObject * -_PyGen_yf(PyGenObject *gen) -{ - if (gen->gi_frame_state == FRAME_SUSPENDED_YIELD_FROM) { - _PyInterpreterFrame *frame = &gen->gi_iframe; - // GH-122390: These asserts are wrong in the presence of ENTER_EXECUTOR! - // assert(is_resume(frame->instr_ptr)); - // assert((frame->instr_ptr->op.arg & RESUME_OPARG_LOCATION_MASK) >= RESUME_AFTER_YIELD_FROM); - return PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame)); - } - return NULL; -} - static PyObject * gen_close(PyObject *self, PyObject *args) { PyGenObject *gen = _PyGen_CAST(self); - if (gen->gi_frame_state == FRAME_CREATED) { - gen->gi_frame_state = FRAME_COMPLETED; - gen_clear_frame(gen); - Py_RETURN_NONE; - } - if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { - Py_RETURN_NONE; - } + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + do { + if (frame_state == FRAME_CREATED) { + if (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_CLEARED)) { + continue; + } + gen_clear_frame(gen); + Py_RETURN_NONE; + } + + if (FRAME_STATE_FINISHED(frame_state)) { + Py_RETURN_NONE; + } + + if (frame_state == FRAME_EXECUTING) { + gen_raise_already_executing_error(gen); + return NULL; + } + + assert(frame_state == FRAME_SUSPENDED_YIELD_FROM || + frame_state == FRAME_SUSPENDED); + + } while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING)); - PyObject *yf = _PyGen_yf(gen); int err = 0; - if (yf) { - PyFrameState state = gen->gi_frame_state; - gen->gi_frame_state = FRAME_EXECUTING; + _PyInterpreterFrame *frame = &gen->gi_iframe; + if (frame_state == FRAME_SUSPENDED_YIELD_FROM) { + PyObject *yf = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame)); err = gen_close_iter(yf); - gen->gi_frame_state = state; Py_DECREF(yf); } - _PyInterpreterFrame *frame = &gen->gi_iframe; + if (is_resume(frame->instr_ptr)) { bool no_unwind_tools = _PyEval_NoToolsForUnwind(_PyThreadState_GET()); /* We can safely ignore the outermost try block @@ -416,7 +460,7 @@ gen_close(PyObject *self, PyObject *args) if (oparg & RESUME_OPARG_DEPTH1_MASK && no_unwind_tools) { // RESUME after YIELD_VALUE and exception depth is 1 assert((oparg & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START); - gen->gi_frame_state = FRAME_COMPLETED; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_CLEARED); gen_clear_frame(gen); Py_RETURN_NONE; } @@ -425,8 +469,13 @@ gen_close(PyObject *self, PyObject *args) PyErr_SetNone(PyExc_GeneratorExit); } - PyObject *retval = gen_send_ex(gen, Py_None, 1, 1); - if (retval) { + PyObject *retval; + if (gen_send_ex2(gen, Py_None, &retval, 1) == PYGEN_RETURN) { + // the generator returned a value while closing, return the value here + assert(!PyErr_Occurred()); + return retval; + } + else if (retval) { const char *msg = "generator ignored GeneratorExit"; if (PyCoro_CheckExact(gen)) { msg = "coroutine ignored GeneratorExit"; @@ -443,15 +492,80 @@ gen_close(PyObject *self, PyObject *args) PyErr_Clear(); /* ignore this error */ Py_RETURN_NONE; } + return NULL; +} - /* if the generator returned a value while closing, StopIteration was - * raised in gen_send_ex() above; retrieve and return the value here */ - if (_PyGen_FetchStopIterationValue(&retval) == 0) { - return retval; +// Set an exception for a gen.throw() call. +// Return 0 on success, -1 on failure. +static int +gen_set_exception(PyObject *typ, PyObject *val, PyObject *tb) +{ + /* First, check the traceback argument, replacing None with + NULL. */ + if (tb == Py_None) { + tb = NULL; } - return NULL; + else if (tb != NULL && !PyTraceBack_Check(tb)) { + PyErr_SetString(PyExc_TypeError, + "throw() third argument must be a traceback object"); + return -1; + } + + Py_INCREF(typ); + Py_XINCREF(val); + Py_XINCREF(tb); + + if (PyExceptionClass_Check(typ)) { + PyErr_NormalizeException(&typ, &val, &tb); + } + else if (PyExceptionInstance_Check(typ)) { + /* Raising an instance. The value should be a dummy. */ + if (val && val != Py_None) { + PyErr_SetString(PyExc_TypeError, + "instance exception may not have a separate value"); + goto failed_throw; + } + else { + /* Normalize to raise , */ + Py_XSETREF(val, typ); + typ = Py_NewRef(PyExceptionInstance_Class(typ)); + + if (tb == NULL) + /* Returns NULL if there's no traceback */ + tb = PyException_GetTraceback(val); + } + } + else { + /* Not something you can raise. throw() fails. */ + PyErr_Format(PyExc_TypeError, + "exceptions must be classes or instances " + "deriving from BaseException, not %s", + Py_TYPE(typ)->tp_name); + goto failed_throw; + } + + PyErr_Restore(typ, val, tb); + return 0; + +failed_throw: + /* Didn't use our arguments, so restore their original refcounts */ + Py_DECREF(typ); + Py_XDECREF(val); + Py_XDECREF(tb); + return -1; } +static PyObject * +gen_throw_current_exception(PyGenObject *gen) +{ + assert(gen->gi_frame_state == FRAME_EXECUTING); + + PyObject *result; + if (gen_send_ex2(gen, Py_None, &result, 1) == PYGEN_RETURN) { + return gen_set_stop_iteration(gen, result); + } + return result; +} PyDoc_STRVAR(throw_doc, "throw(value)\n\ @@ -466,10 +580,32 @@ static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, PyObject *typ, PyObject *val, PyObject *tb) { - PyObject *yf = _PyGen_yf(gen); + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + do { + if (frame_state == FRAME_EXECUTING) { + gen_raise_already_executing_error(gen); + return NULL; + } - if (yf) { + if (FRAME_STATE_FINISHED(frame_state)) { + if (PyCoro_CheckExact(gen)) { + /* `gen` is an exhausted coroutine: raise an error */ + PyErr_SetString( + PyExc_RuntimeError, + "cannot reuse already awaited coroutine"); + return NULL; + } + gen_set_exception(typ, val, tb); + return NULL; + } + + assert((frame_state == FRAME_CREATED) || + FRAME_STATE_SUSPENDED(frame_state)); + } while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING)); + + if (frame_state == FRAME_SUSPENDED_YIELD_FROM) { _PyInterpreterFrame *frame = &gen->gi_iframe; + PyObject *yf = PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame)); PyObject *ret; int err; if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) && @@ -479,13 +615,11 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, We have to allow some awaits to work it through, hence the `close_on_genexit` parameter here. */ - PyFrameState state = gen->gi_frame_state; - gen->gi_frame_state = FRAME_EXECUTING; err = gen_close_iter(yf); - gen->gi_frame_state = state; Py_DECREF(yf); - if (err < 0) - return gen_send_ex(gen, Py_None, 1, 0); + if (err < 0) { + return gen_throw_current_exception(gen); + } goto throw_here; } PyThreadState *tstate = _PyThreadState_GET(); @@ -501,18 +635,17 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, tstate->current_frame = frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ - PyFrameState state = gen->gi_frame_state; - gen->gi_frame_state = FRAME_EXECUTING; ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); - gen->gi_frame_state = state; tstate->current_frame = prev; frame->previous = NULL; - } else { + } + else { /* `yf` is an iterator or a coroutine-like object. */ PyObject *meth; if (PyObject_GetOptionalAttr(yf, &_Py_ID(throw), &meth) < 0) { Py_DECREF(yf); + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, frame_state); return NULL; } if (meth == NULL) { @@ -523,75 +656,26 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, _PyInterpreterFrame *prev = tstate->current_frame; frame->previous = prev; tstate->current_frame = frame; - PyFrameState state = gen->gi_frame_state; - gen->gi_frame_state = FRAME_EXECUTING; ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL); - gen->gi_frame_state = state; tstate->current_frame = prev; frame->previous = NULL; Py_DECREF(meth); } Py_DECREF(yf); if (!ret) { - ret = gen_send_ex(gen, Py_None, 1, 0); + return gen_throw_current_exception(gen); } + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, frame_state); return ret; } throw_here: - /* First, check the traceback argument, replacing None with - NULL. */ - if (tb == Py_None) { - tb = NULL; - } - else if (tb != NULL && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "throw() third argument must be a traceback object"); + assert(FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state) == FRAME_EXECUTING); + if (gen_set_exception(typ, val, tb) < 0) { + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, frame_state); return NULL; } - - Py_INCREF(typ); - Py_XINCREF(val); - Py_XINCREF(tb); - - if (PyExceptionClass_Check(typ)) - PyErr_NormalizeException(&typ, &val, &tb); - - else if (PyExceptionInstance_Check(typ)) { - /* Raising an instance. The value should be a dummy. */ - if (val && val != Py_None) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto failed_throw; - } - else { - /* Normalize to raise , */ - Py_XSETREF(val, typ); - typ = Py_NewRef(PyExceptionInstance_Class(typ)); - - if (tb == NULL) - /* Returns NULL if there's no traceback */ - tb = PyException_GetTraceback(val); - } - } - else { - /* Not something you can raise. throw() fails. */ - PyErr_Format(PyExc_TypeError, - "exceptions must be classes or instances " - "deriving from BaseException, not %s", - Py_TYPE(typ)->tp_name); - goto failed_throw; - } - - PyErr_Restore(typ, val, tb); - return gen_send_ex(gen, Py_None, 1, 0); - -failed_throw: - /* Didn't use our arguments, so restore their original refcounts */ - Py_DECREF(typ); - Py_XDECREF(val); - Py_XDECREF(tb); - return NULL; + return gen_throw_current_exception(gen); } @@ -633,7 +717,7 @@ gen_iternext(PyObject *self) PyGenObject *gen = _PyGen_CAST(self); PyObject *result; - if (gen_send_ex2(gen, NULL, &result, 0, 0) == PYGEN_RETURN) { + if (gen_send_ex(gen, NULL, &result) == PYGEN_RETURN) { if (result != Py_None) { _PyGen_SetStopIterationValue(result); } @@ -757,13 +841,15 @@ gen_set_qualname(PyObject *self, PyObject *value, void *Py_UNUSED(ignored)) } static PyObject * -gen_getyieldfrom(PyObject *gen, void *Py_UNUSED(ignored)) +gen_getyieldfrom(PyObject *self, void *Py_UNUSED(ignored)) { - PyObject *yf = _PyGen_yf(_PyGen_CAST(gen)); - if (yf == NULL) { + PyGenObject *gen = _PyGen_CAST(self); + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + if (frame_state != FRAME_SUSPENDED_YIELD_FROM) { Py_RETURN_NONE; } - return yf; + // TODO: still not thread-safe with free threading + return PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(&gen->gi_iframe)); } @@ -771,17 +857,16 @@ static PyObject * gen_getrunning(PyObject *self, void *Py_UNUSED(ignored)) { PyGenObject *gen = _PyGen_CAST(self); - if (gen->gi_frame_state == FRAME_EXECUTING) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + return frame_state == FRAME_EXECUTING ? Py_True : Py_False; } static PyObject * gen_getsuspended(PyObject *self, void *Py_UNUSED(ignored)) { PyGenObject *gen = _PyGen_CAST(self); - return PyBool_FromLong(FRAME_STATE_SUSPENDED(gen->gi_frame_state)); + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + return FRAME_STATE_SUSPENDED(frame_state) ? Py_True : Py_False; } static PyObject * @@ -790,9 +875,11 @@ _gen_getframe(PyGenObject *gen, const char *const name) if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { return NULL; } - if (FRAME_STATE_FINISHED(gen->gi_frame_state)) { + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state); + if (FRAME_STATE_FINISHED(frame_state)) { Py_RETURN_NONE; } + // TODO: still not thread-safe with free threading return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(&gen->gi_iframe)); } @@ -1135,35 +1222,6 @@ coro_await(PyObject *coro) return (PyObject *)cw; } -static PyObject * -coro_get_cr_await(PyObject *coro, void *Py_UNUSED(ignored)) -{ - PyObject *yf = _PyGen_yf((PyGenObject *) coro); - if (yf == NULL) - Py_RETURN_NONE; - return yf; -} - -static PyObject * -cr_getsuspended(PyObject *self, void *Py_UNUSED(ignored)) -{ - PyCoroObject *coro = _PyCoroObject_CAST(self); - if (FRAME_STATE_SUSPENDED(coro->cr_frame_state)) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; -} - -static PyObject * -cr_getrunning(PyObject *self, void *Py_UNUSED(ignored)) -{ - PyCoroObject *coro = _PyCoroObject_CAST(self); - if (coro->cr_frame_state == FRAME_EXECUTING) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; -} - static PyObject * cr_getframe(PyObject *coro, void *Py_UNUSED(ignored)) { @@ -1181,12 +1239,12 @@ static PyGetSetDef coro_getsetlist[] = { PyDoc_STR("name of the coroutine")}, {"__qualname__", gen_get_qualname, gen_set_qualname, PyDoc_STR("qualified name of the coroutine")}, - {"cr_await", coro_get_cr_await, NULL, + {"cr_await", gen_getyieldfrom, NULL, PyDoc_STR("object being awaited on, or None")}, - {"cr_running", cr_getrunning, NULL, NULL}, + {"cr_running", gen_getrunning, NULL, NULL}, {"cr_frame", cr_getframe, NULL, NULL}, {"cr_code", cr_getcode, NULL, NULL}, - {"cr_suspended", cr_getsuspended, NULL, NULL}, + {"cr_suspended", gen_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; @@ -1602,26 +1660,16 @@ ag_getcode(PyObject *gen, void *Py_UNUSED(ignored)) return _gen_getcode((PyGenObject*)gen, "ag_code"); } -static PyObject * -ag_getsuspended(PyObject *self, void *Py_UNUSED(ignored)) -{ - PyAsyncGenObject *ag = _PyAsyncGenObject_CAST(self); - if (FRAME_STATE_SUSPENDED(ag->ag_frame_state)) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; -} - static PyGetSetDef async_gen_getsetlist[] = { {"__name__", gen_get_name, gen_set_name, PyDoc_STR("name of the async generator")}, {"__qualname__", gen_get_qualname, gen_set_qualname, PyDoc_STR("qualified name of the async generator")}, - {"ag_await", coro_get_cr_await, NULL, + {"ag_await", gen_getyieldfrom, NULL, PyDoc_STR("object being awaited on, or None")}, {"ag_frame", ag_getframe, NULL, NULL}, {"ag_code", ag_getcode, NULL, NULL}, - {"ag_suspended", ag_getsuspended, NULL, NULL}, + {"ag_suspended", gen_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 1291fe56a59d5b..f7eb006e686800 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1312,14 +1312,13 @@ dummy_func( assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); if ((tstate->interp->eval_frame == NULL) && (Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) == &PyCoro_Type) && - ((PyGenObject *)receiver_o)->gi_frame_state < FRAME_EXECUTING) + gen_try_set_executing((PyGenObject *)receiver_o)) { PyGenObject *gen = (PyGenObject *)receiver_o; _PyInterpreterFrame *gen_frame = &gen->gi_iframe; _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); DEAD(v); SYNC_SP(); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX); @@ -1360,12 +1359,11 @@ dummy_func( op(_SEND_GEN_FRAME, (receiver, v -- receiver, gen_frame)) { PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(receiver); DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type); - DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); + DEOPT_IF(!gen_try_set_executing((PyGenObject *)gen)); STAT_INC(SEND, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); DEAD(v); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; assert(INSTRUCTION_SIZE + oparg <= UINT16_MAX); @@ -1389,7 +1387,6 @@ dummy_func( PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); assert(oparg == 0 || oparg == 1); - gen->gi_frame_state = FRAME_SUSPENDED + oparg; _PyStackRef temp = retval; DEAD(retval); SAVE_STACK(); @@ -1399,6 +1396,8 @@ dummy_func( _PyInterpreterFrame *gen_frame = frame; frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); /* We don't know which of these is relevant here, so keep them equal */ assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); #if TIER_ONE @@ -3405,18 +3404,10 @@ dummy_func( op(_FOR_ITER_GEN_FRAME, (iter, null -- iter, null, gen_frame)) { PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); DEOPT_IF(Py_TYPE(gen) != &PyGen_Type); -#ifdef Py_GIL_DISABLED - // Since generators can't be used by multiple threads anyway we - // don't need to deopt here, but this lets us work on making - // generators thread-safe without necessarily having to - // specialize them thread-safely as well. - DEOPT_IF(!_PyObject_IsUniquelyReferenced((PyObject *)gen)); -#endif - DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING); + DEOPT_IF(!gen_try_set_executing((PyGenObject *)gen)); STAT_INC(FOR_ITER, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_None); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; pushed_frame->previous = frame; diff --git a/Python/ceval.c b/Python/ceval.c index cf86d5484f0d6e..ec21d6bc2b852c 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2304,7 +2304,8 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) { assert(frame->owner == FRAME_OWNED_BY_GENERATOR); PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); - gen->gi_frame_state = FRAME_CLEARED; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_CLEARED); + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_RETURN; assert(tstate->exc_info == &gen->gi_exc_state); tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; @@ -3979,15 +3980,13 @@ _PyEval_GetAwaitable(PyObject *iterable, int oparg) Py_TYPE(iterable), oparg); } else if (PyCoro_CheckExact(iter)) { - PyObject *yf = _PyGen_yf((PyGenObject*)iter); - if (yf != NULL) { - /* `iter` is a coroutine object that is being - awaited, `yf` is a pointer to the current awaitable - being awaited on. */ - Py_DECREF(yf); + PyCoroObject *coro = (PyCoroObject *)iter; + int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(coro->cr_frame_state); + if (frame_state == FRAME_SUSPENDED_YIELD_FROM) { + /* `iter` is a coroutine object that is being awaited. */ Py_CLEAR(iter); _PyErr_SetString(PyThreadState_GET(), PyExc_RuntimeError, - "coroutine is being awaited already"); + "coroutine is being awaited already"); } } return iter; diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index a526a453dd918a..c9472ec16d423e 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -496,3 +496,28 @@ check_periodics(PyThreadState *tstate) { return 0; } +// Mark the generator as executing. Returns true if the state was changed, +// false if it was already executing or finished. +static inline bool +gen_try_set_executing(PyGenObject *gen) +{ +#ifdef Py_GIL_DISABLED + if (!_PyObject_IsUniquelyReferenced((PyObject *)gen)) { + int8_t frame_state = _Py_atomic_load_int8_relaxed(&gen->gi_frame_state); + while (frame_state < FRAME_EXECUTING) { + if (_Py_atomic_compare_exchange_int8(&gen->gi_frame_state, + &frame_state, + FRAME_EXECUTING)) { + return true; + } + } + } +#endif + // Use faster non-atomic modifications in the GIL-enabled build and when + // the object is uniquely referenced in the free-threaded build. + if (gen->gi_frame_state < FRAME_EXECUTING) { + gen->gi_frame_state = FRAME_EXECUTING; + return true; + } + return false; +} diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 2305df6ad5aaf1..b3eff63b30ab55 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -5823,7 +5823,7 @@ SET_CURRENT_CACHED_VALUES(2); JUMP_TO_JUMP_TARGET(); } - if (gen->gi_frame_state >= FRAME_EXECUTING) { + if (!gen_try_set_executing((PyGenObject *)gen)) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = v; _tos_cache0 = receiver; @@ -5833,7 +5833,6 @@ STAT_INC(SEND, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; assert( 2u + oparg <= UINT16_MAX); @@ -5861,7 +5860,6 @@ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); assert(oparg == 0 || oparg == 1); - gen->gi_frame_state = FRAME_SUSPENDED + oparg; _PyStackRef temp = retval; _PyFrame_SetStackPointer(frame, stack_pointer); tstate->exc_info = gen->gi_exc_state.previous_item; @@ -5870,6 +5868,8 @@ _PyInterpreterFrame *gen_frame = frame; frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); #if TIER_ONE assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || @@ -10859,34 +10859,99 @@ break; } - case _FOR_ITER_GEN_FRAME_r23: { - CHECK_CURRENT_CACHED_VALUES(2); + case _FOR_ITER_GEN_FRAME_r03: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef iter; + _PyStackRef gen_frame; + oparg = CURRENT_OPARG(); + iter = stack_pointer[-2]; + PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); + if (Py_TYPE(gen) != &PyGen_Type) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + if (!gen_try_set_executing((PyGenObject *)gen)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + STAT_INC(FOR_ITER, hit); + _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; + _PyFrame_StackPush(pushed_frame, PyStackRef_None); + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + pushed_frame->previous = frame; + frame->return_offset = (uint16_t)( 2u + oparg); + gen_frame = PyStackRef_Wrap(pushed_frame); + _tos_cache2 = gen_frame; + _tos_cache1 = stack_pointer[-1]; + _tos_cache0 = iter; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -2; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _FOR_ITER_GEN_FRAME_r13: { + CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); _PyStackRef iter; _PyStackRef gen_frame; _PyStackRef _stack_item_0 = _tos_cache0; - _PyStackRef _stack_item_1 = _tos_cache1; oparg = CURRENT_OPARG(); - iter = _stack_item_0; + iter = stack_pointer[-1]; PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); if (Py_TYPE(gen) != &PyGen_Type) { UOP_STAT_INC(uopcode, miss); - _tos_cache1 = _stack_item_1; - _tos_cache0 = iter; - SET_CURRENT_CACHED_VALUES(2); + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(1); JUMP_TO_JUMP_TARGET(); } - #ifdef Py_GIL_DISABLED + if (!gen_try_set_executing((PyGenObject *)gen)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + STAT_INC(FOR_ITER, hit); + _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; + _PyFrame_StackPush(pushed_frame, PyStackRef_None); + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + pushed_frame->previous = frame; + frame->return_offset = (uint16_t)( 2u + oparg); + gen_frame = PyStackRef_Wrap(pushed_frame); + _tos_cache2 = gen_frame; + _tos_cache1 = _stack_item_0; + _tos_cache0 = iter; + SET_CURRENT_CACHED_VALUES(3); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } - if (!_PyObject_IsUniquelyReferenced((PyObject *)gen)) { + case _FOR_ITER_GEN_FRAME_r23: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef iter; + _PyStackRef gen_frame; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + oparg = CURRENT_OPARG(); + iter = _stack_item_0; + PyGenObject *gen = (PyGenObject *)PyStackRef_AsPyObjectBorrow(iter); + if (Py_TYPE(gen) != &PyGen_Type) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; _tos_cache0 = iter; SET_CURRENT_CACHED_VALUES(2); JUMP_TO_JUMP_TARGET(); } - #endif - if (gen->gi_frame_state >= FRAME_EXECUTING) { + if (!gen_try_set_executing((PyGenObject *)gen)) { UOP_STAT_INC(uopcode, miss); _tos_cache1 = _stack_item_1; _tos_cache0 = iter; @@ -10896,7 +10961,6 @@ STAT_INC(FOR_ITER, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_None); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; pushed_frame->previous = frame; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 4482bb08a132f9..eaaa5f3bb96abc 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5548,14 +5548,7 @@ assert(_PyOpcode_Deopt[opcode] == (FOR_ITER)); JUMP_TO_PREDICTED(FOR_ITER); } - #ifdef Py_GIL_DISABLED - if (!_PyObject_IsUniquelyReferenced((PyObject *)gen)) { - UPDATE_MISS_STATS(FOR_ITER); - assert(_PyOpcode_Deopt[opcode] == (FOR_ITER)); - JUMP_TO_PREDICTED(FOR_ITER); - } - #endif - if (gen->gi_frame_state >= FRAME_EXECUTING) { + if (!gen_try_set_executing((PyGenObject *)gen)) { UPDATE_MISS_STATS(FOR_ITER); assert(_PyOpcode_Deopt[opcode] == (FOR_ITER)); JUMP_TO_PREDICTED(FOR_ITER); @@ -5563,7 +5556,6 @@ STAT_INC(FOR_ITER, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_None); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; pushed_frame->previous = frame; @@ -7327,7 +7319,6 @@ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); assert(oparg == 0 || oparg == 1); - gen->gi_frame_state = FRAME_SUSPENDED + oparg; _PyStackRef temp = retval; stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -7338,6 +7329,8 @@ _PyInterpreterFrame *gen_frame = frame; frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); #if TIER_ONE assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || @@ -10301,14 +10294,13 @@ assert(frame->owner != FRAME_OWNED_BY_INTERPRETER); if ((tstate->interp->eval_frame == NULL) && (Py_TYPE(receiver_o) == &PyGen_Type || Py_TYPE(receiver_o) == &PyCoro_Type) && - ((PyGenObject *)receiver_o)->gi_frame_state < FRAME_EXECUTING) + gen_try_set_executing((PyGenObject *)receiver_o)) { PyGenObject *gen = (PyGenObject *)receiver_o; _PyInterpreterFrame *gen_frame = &gen->gi_iframe; _PyFrame_StackPush(gen_frame, PyStackRef_MakeHeapSafe(v)); stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; assert( 2u + oparg <= UINT16_MAX); @@ -10401,7 +10393,7 @@ assert(_PyOpcode_Deopt[opcode] == (SEND)); JUMP_TO_PREDICTED(SEND); } - if (gen->gi_frame_state >= FRAME_EXECUTING) { + if (!gen_try_set_executing((PyGenObject *)gen)) { UPDATE_MISS_STATS(SEND); assert(_PyOpcode_Deopt[opcode] == (SEND)); JUMP_TO_PREDICTED(SEND); @@ -10409,7 +10401,6 @@ STAT_INC(SEND, hit); _PyInterpreterFrame *pushed_frame = &gen->gi_iframe; _PyFrame_StackPush(pushed_frame, PyStackRef_MakeHeapSafe(v)); - gen->gi_frame_state = FRAME_EXECUTING; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; assert( 2u + oparg <= UINT16_MAX); @@ -12045,7 +12036,6 @@ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame); assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1); assert(oparg == 0 || oparg == 1); - gen->gi_frame_state = FRAME_SUSPENDED + oparg; _PyStackRef temp = retval; stack_pointer += -1; ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); @@ -12056,6 +12046,8 @@ _PyInterpreterFrame *gen_frame = frame; frame = tstate->current_frame = frame->previous; gen_frame->previous = NULL; + ((_PyThreadStateImpl *)tstate)->generator_return_kind = GENERATOR_YIELD; + FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_SUSPENDED + oparg); assert(INLINE_CACHE_ENTRIES_SEND == INLINE_CACHE_ENTRIES_FOR_ITER); #if TIER_ONE assert(frame->instr_ptr->op.code == INSTRUMENTED_LINE || diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index fcd0dcf12acb2b..659befe312afaf 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -642,6 +642,7 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: "_PyFrame_StackPush", "_PyFunction_SetVersion", "_PyGen_GetGeneratorFromFrame", + "gen_try_set_executing", "_PyInterpreterState_GET", "_PyList_AppendTakeRef", "_PyList_ITEMS", From 4ea3c1a04747978361b497798428423cbb6a7146 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 19 Dec 2025 17:33:49 -0500 Subject: [PATCH 6/7] gh-120321: Fix TSan reported race in gen_clear_frame (gh-142995) TSan treats compare-exchanges that fail as if they are writes so there is a false positive with the read of gi_frame_state in gen_close. --- Objects/genobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/genobject.c b/Objects/genobject.c index 508d215a0cfe64..1e59d89f5ce85f 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -153,7 +153,7 @@ _PyGen_Finalize(PyObject *self) static void gen_clear_frame(PyGenObject *gen) { - assert(gen->gi_frame_state == FRAME_CLEARED); + assert(FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state) == FRAME_CLEARED); _PyInterpreterFrame *frame = &gen->gi_iframe; frame->previous = NULL; _PyFrame_ClearExceptCode(frame); From e46f28c6afce9c85e4bc4a113d1c7efc472e7d8f Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 19 Dec 2025 18:06:47 -0500 Subject: [PATCH 7/7] gh-129069: Fix listobject.c data races due to memmove (gh-142957) The use of memmove and _Py_memory_repeat were not thread-safe in the free threading build in some cases. In theory, memmove and _Py_memory_repeat can copy byte-by-byte instead of pointer-by-pointer, so concurrent readers could see uninitialized data or tearing. Additionally, we should be using "release" (or stronger) ordering to be compliant with the C11 memory model when copying objects within a list. --- Objects/listobject.c | 103 +++++++++++++-------- Tools/tsan/suppressions_free_threading.txt | 6 -- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 1722ea60cdc68f..f67d1a45a494cb 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -96,11 +96,7 @@ ensure_shared_on_resize(PyListObject *self) * of the new slots at exit is undefined heap trash; it's the caller's * responsibility to overwrite them with sane values. * The number of allocated elements may grow, shrink, or stay the same. - * Failure is impossible if newsize <= self.allocated on entry, although - * that partly relies on an assumption that the system realloc() never - * fails when passed a number of bytes <= the number of bytes last - * allocated (the C standard doesn't guarantee this, but it's hard to - * imagine a realloc implementation where it wouldn't be true). + * Failure is impossible if newsize <= self.allocated on entry. * Note that self->ob_item may change, and even if newsize is less * than ob_size on entry. */ @@ -145,6 +141,11 @@ list_resize(PyListObject *self, Py_ssize_t newsize) #ifdef Py_GIL_DISABLED _PyListArray *array = list_allocate_array(new_allocated); if (array == NULL) { + if (newsize < allocated) { + // Never fail when shrinking allocations + Py_SET_SIZE(self, newsize); + return 0; + } PyErr_NoMemory(); return -1; } @@ -178,6 +179,11 @@ list_resize(PyListObject *self, Py_ssize_t newsize) items = NULL; } if (items == NULL) { + if (newsize < allocated) { + // Never fail when shrinking allocations + Py_SET_SIZE(self, newsize); + return 0; + } PyErr_NoMemory(); return -1; } @@ -818,8 +824,8 @@ list_repeat_lock_held(PyListObject *a, Py_ssize_t n) _Py_RefcntAdd(*src, n); *dest++ = *src++; } - // TODO: _Py_memory_repeat calls are not safe for shared lists in - // GIL_DISABLED builds. (See issue #129069) + // This list is not yet visible to other threads, so atomic repeat + // is not necessary even in Py_GIL_DISABLED builds. _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, sizeof(PyObject *)*input_size); } @@ -882,6 +888,34 @@ list_clear_slot(PyObject *self) return 0; } +// Pointer-by-pointer memmove for PyObject** arrays that is safe +// for shared lists in Py_GIL_DISABLED builds. +static void +ptr_wise_atomic_memmove(PyListObject *a, PyObject **dest, PyObject **src, Py_ssize_t n) +{ +#ifndef Py_GIL_DISABLED + memmove(dest, src, n * sizeof(PyObject *)); +#else + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(a); + if (_Py_IsOwnedByCurrentThread((PyObject *)a) && !_PyObject_GC_IS_SHARED(a)) { + // No other threads can read this list concurrently + memmove(dest, src, n * sizeof(PyObject *)); + return; + } + if (dest < src) { + for (Py_ssize_t i = 0; i != n; i++) { + _Py_atomic_store_ptr_release(&dest[i], src[i]); + } + } + else { + // copy backwards to avoid overwriting src before it's read + for (Py_ssize_t i = n; i != 0; i--) { + _Py_atomic_store_ptr_release(&dest[i - 1], src[i - 1]); + } + } +#endif +} + /* a[ilow:ihigh] = v if v != NULL. * del a[ilow:ihigh] if v == NULL. * @@ -952,16 +986,9 @@ list_ass_slice_lock_held(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyO } if (d < 0) { /* Delete -d items */ - Py_ssize_t tail; - tail = (Py_SIZE(a) - ihigh) * sizeof(PyObject *); - // TODO: these memmove/memcpy calls are not safe for shared lists in - // GIL_DISABLED builds. (See issue #129069) - memmove(&item[ihigh+d], &item[ihigh], tail); - if (list_resize(a, Py_SIZE(a) + d) < 0) { - memmove(&item[ihigh], &item[ihigh+d], tail); - memcpy(&item[ilow], recycle, s); - goto Error; - } + Py_ssize_t tail = Py_SIZE(a) - ihigh; + ptr_wise_atomic_memmove(a, &item[ihigh+d], &item[ihigh], tail); + (void)list_resize(a, Py_SIZE(a) + d); // NB: shrinking a list can't fail item = a->ob_item; } else if (d > 0) { /* Insert d items */ @@ -969,10 +996,7 @@ list_ass_slice_lock_held(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyO if (list_resize(a, k+d) < 0) goto Error; item = a->ob_item; - // TODO: these memmove/memcpy calls are not safe for shared lists in - // GIL_DISABLED builds. (See issue #129069) - memmove(&item[ihigh+d], &item[ihigh], - (k - ihigh)*sizeof(PyObject *)); + ptr_wise_atomic_memmove(a, &item[ihigh+d], &item[ihigh], k - ihigh); } for (k = 0; k < n; k++, ilow++) { PyObject *w = vitem[k]; @@ -1056,10 +1080,17 @@ list_inplace_repeat_lock_held(PyListObject *self, Py_ssize_t n) for (Py_ssize_t j = 0; j < input_size; j++) { _Py_RefcntAdd(items[j], n-1); } - // TODO: _Py_memory_repeat calls are not safe for shared lists in - // GIL_DISABLED builds. (See issue #129069) +#ifndef Py_GIL_DISABLED _Py_memory_repeat((char *)items, sizeof(PyObject *)*output_size, sizeof(PyObject *)*input_size); +#else + Py_ssize_t copied = input_size; + while (copied < output_size) { + Py_ssize_t items_to_copy = Py_MIN(copied, output_size - copied); + ptr_wise_atomic_memmove(self, items + copied, items, items_to_copy); + copied += items_to_copy; + } +#endif return 0; } @@ -1532,7 +1563,6 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) /*[clinic end generated code: output=6bd69dcb3f17eca8 input=c269141068ae4b8f]*/ { PyObject *v; - int status; if (Py_SIZE(self) == 0) { /* Special-case most common failure cause */ @@ -1548,27 +1578,18 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) PyObject **items = self->ob_item; v = items[index]; - const Py_ssize_t size_after_pop = Py_SIZE(self) - 1; - if (size_after_pop == 0) { + if (Py_SIZE(self) == 1) { Py_INCREF(v); list_clear(self); - status = 0; - } - else { - if ((size_after_pop - index) > 0) { - memmove(&items[index], &items[index+1], (size_after_pop - index) * sizeof(PyObject *)); - } - status = list_resize(self, size_after_pop); + return v; } - if (status >= 0) { - return v; // and v now owns the reference the list had - } - else { - // list resize failed, need to restore - memmove(&items[index+1], &items[index], (size_after_pop - index)* sizeof(PyObject *)); - items[index] = v; - return NULL; + Py_ssize_t size_after_pop = Py_SIZE(self) - 1; + if (index < size_after_pop) { + ptr_wise_atomic_memmove(self, &items[index], &items[index+1], + size_after_pop - index); } + list_resize(self, size_after_pop); // NB: shrinking a list can't fail + return v; } /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ diff --git a/Tools/tsan/suppressions_free_threading.txt b/Tools/tsan/suppressions_free_threading.txt index adc85d631db7c6..e8b1501c34bfc1 100644 --- a/Tools/tsan/suppressions_free_threading.txt +++ b/Tools/tsan/suppressions_free_threading.txt @@ -23,12 +23,6 @@ race_top:write_thread_id # https://gist.github.com/mpage/6962e8870606cfc960e159b407a0cb40 thread:pthread_create -# List resizing happens through different paths ending in memcpy or memmove -# (for efficiency), which will probably need to rewritten as explicit loops -# of ptr-sized copies to be thread-safe. (Issue #129069) -race:list_ass_slice_lock_held -race:list_inplace_repeat_lock_held - # PyObject_Realloc internally does memcpy which isn't atomic so can race # with non-locking reads. See #132070 race:PyObject_Realloc