diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 9f626cecd13630..7f468bbb932184 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1028,10 +1028,9 @@ enum InstructionFormat { #define HAS_ESCAPES_FLAG (512) #define HAS_EXIT_FLAG (1024) #define HAS_PURE_FLAG (2048) -#define HAS_PASSTHROUGH_FLAG (4096) -#define HAS_OPARG_AND_1_FLAG (8192) -#define HAS_ERROR_NO_POP_FLAG (16384) -#define HAS_NO_SAVE_IP_FLAG (32768) +#define HAS_ERROR_NO_POP_FLAG (4096) +#define HAS_NO_SAVE_IP_FLAG (8192) +#define HAS_PERIODIC_FLAG (16384) #define OPCODE_HAS_ARG(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ARG_FLAG)) #define OPCODE_HAS_CONST(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_CONST_FLAG)) #define OPCODE_HAS_NAME(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NAME_FLAG)) @@ -1044,10 +1043,9 @@ enum InstructionFormat { #define OPCODE_HAS_ESCAPES(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ESCAPES_FLAG)) #define OPCODE_HAS_EXIT(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_EXIT_FLAG)) #define OPCODE_HAS_PURE(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PURE_FLAG)) -#define OPCODE_HAS_PASSTHROUGH(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PASSTHROUGH_FLAG)) -#define OPCODE_HAS_OPARG_AND_1(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_OPARG_AND_1_FLAG)) #define OPCODE_HAS_ERROR_NO_POP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_ERROR_NO_POP_FLAG)) #define OPCODE_HAS_NO_SAVE_IP(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_NO_SAVE_IP_FLAG)) +#define OPCODE_HAS_PERIODIC(OP) (_PyOpcode_opcode_metadata[OP].flags & (HAS_PERIODIC_FLAG)) #define OPARG_SIMPLE 0 #define OPARG_CACHE_1 1 @@ -1347,27 +1345,27 @@ _PyOpcode_macro_expansion[256] = { [CALL_ALLOC_AND_ENTER_INIT] = { .nuops = 4, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_AND_ALLOCATE_OBJECT, 2, 1 }, { _CREATE_INIT_FRAME, OPARG_SIMPLE, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 10, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_BOUND_METHOD_GENERAL] = { .nuops = 7, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, - [CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_BUILTIN_O] = { .nuops = 2, .uops = { { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, + [CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_BUILTIN_O] = { .nuops = 2, .uops = { { _CALL_BUILTIN_O, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, [CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_1, OPARG_SIMPLE, 0 } } }, [CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { _CALL_INTRINSIC_2, OPARG_SIMPLE, 0 } } }, [CALL_ISINSTANCE] = { .nuops = 3, .uops = { { _GUARD_THIRD_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_ISINSTANCE, OPARG_SIMPLE, 3 }, { _CALL_ISINSTANCE, OPARG_SIMPLE, 3 } } }, [CALL_KW_BOUND_METHOD] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_METHOD_VERSION_KW, 2, 1 }, { _EXPAND_METHOD_KW, OPARG_SIMPLE, 3 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, - [CALL_KW_NON_PY] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_KW, OPARG_SIMPLE, 3 }, { _CALL_KW_NON_PY, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, + [CALL_KW_NON_PY] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE_KW, OPARG_SIMPLE, 3 }, { _CALL_KW_NON_PY, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, [CALL_KW_PY] = { .nuops = 5, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION_KW, 2, 1 }, { _PY_FRAME_KW, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_LEN] = { .nuops = 3, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_LEN, OPARG_SIMPLE, 3 }, { _CALL_LEN, OPARG_SIMPLE, 3 } } }, [CALL_LIST_APPEND] = { .nuops = 4, .uops = { { _GUARD_CALLABLE_LIST_APPEND, OPARG_SIMPLE, 3 }, { _GUARD_NOS_NOT_NULL, OPARG_SIMPLE, 3 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 3 }, { _CALL_LIST_APPEND, OPARG_SIMPLE, 3 } } }, - [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_O, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_NON_PY_GENERAL] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE, OPARG_SIMPLE, 3 }, { _CALL_NON_PY_GENERAL, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, + [CALL_METHOD_DESCRIPTOR_FAST] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_METHOD_DESCRIPTOR_O] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_O, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_NON_PY_GENERAL] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE, OPARG_SIMPLE, 3 }, { _CALL_NON_PY_GENERAL, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, [CALL_PY_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _CHECK_STACK_SPACE, OPARG_SIMPLE, 3 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _INIT_CALL_PY_EXACT_ARGS, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, [CALL_PY_GENERAL] = { .nuops = 6, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 1 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_RECURSION_REMAINING, OPARG_SIMPLE, 3 }, { _PY_FRAME_GENERAL, OPARG_SIMPLE, 3 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 3 }, { _PUSH_FRAME, OPARG_SIMPLE, 3 } } }, - [CALL_STR_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_STR_1, OPARG_SIMPLE, 3 }, { _CALL_STR_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, - [CALL_TUPLE_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TUPLE_1, OPARG_SIMPLE, 3 }, { _CALL_TUPLE_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC, OPARG_SIMPLE, 3 } } }, + [CALL_STR_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_STR_1, OPARG_SIMPLE, 3 }, { _CALL_STR_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, + [CALL_TUPLE_1] = { .nuops = 4, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TUPLE_1, OPARG_SIMPLE, 3 }, { _CALL_TUPLE_1, OPARG_SIMPLE, 3 }, { _CHECK_PERIODIC_AT_END, OPARG_REPLACED, 3 } } }, [CALL_TYPE_1] = { .nuops = 3, .uops = { { _GUARD_NOS_NULL, OPARG_SIMPLE, 3 }, { _GUARD_CALLABLE_TYPE_1, OPARG_SIMPLE, 3 }, { _CALL_TYPE_1, OPARG_SIMPLE, 3 } } }, [CHECK_EG_MATCH] = { .nuops = 1, .uops = { { _CHECK_EG_MATCH, OPARG_SIMPLE, 0 } } }, [CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 684969a23c4d22..0dadb50de97a22 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -76,105 +76,106 @@ extern "C" { #define _CHECK_METHOD_VERSION_KW 352 #define _CHECK_PEP_523 353 #define _CHECK_PERIODIC 354 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 355 -#define _CHECK_RECURSION_REMAINING 356 -#define _CHECK_STACK_SPACE 357 -#define _CHECK_STACK_SPACE_OPERAND 358 -#define _CHECK_VALIDITY 359 -#define _COLD_EXIT 360 -#define _COMPARE_OP 361 -#define _COMPARE_OP_FLOAT 362 -#define _COMPARE_OP_INT 363 -#define _COMPARE_OP_STR 364 -#define _CONTAINS_OP 365 -#define _CONTAINS_OP_DICT 366 -#define _CONTAINS_OP_SET 367 +#define _CHECK_PERIODIC_AT_END 355 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 356 +#define _CHECK_RECURSION_REMAINING 357 +#define _CHECK_STACK_SPACE 358 +#define _CHECK_STACK_SPACE_OPERAND 359 +#define _CHECK_VALIDITY 360 +#define _COLD_EXIT 361 +#define _COMPARE_OP 362 +#define _COMPARE_OP_FLOAT 363 +#define _COMPARE_OP_INT 364 +#define _COMPARE_OP_STR 365 +#define _CONTAINS_OP 366 +#define _CONTAINS_OP_DICT 367 +#define _CONTAINS_OP_SET 368 #define _CONVERT_VALUE CONVERT_VALUE -#define _COPY 368 -#define _COPY_1 369 -#define _COPY_2 370 -#define _COPY_3 371 +#define _COPY 369 +#define _COPY_1 370 +#define _COPY_2 371 +#define _COPY_3 372 #define _COPY_FREE_VARS COPY_FREE_VARS -#define _CREATE_INIT_FRAME 372 +#define _CREATE_INIT_FRAME 373 #define _DELETE_ATTR DELETE_ATTR #define _DELETE_DEREF DELETE_DEREF #define _DELETE_FAST DELETE_FAST #define _DELETE_GLOBAL DELETE_GLOBAL #define _DELETE_NAME DELETE_NAME #define _DELETE_SUBSCR DELETE_SUBSCR -#define _DEOPT 373 +#define _DEOPT 374 #define _DICT_MERGE DICT_MERGE #define _DICT_UPDATE DICT_UPDATE -#define _DO_CALL 374 -#define _DO_CALL_FUNCTION_EX 375 -#define _DO_CALL_KW 376 +#define _DO_CALL 375 +#define _DO_CALL_FUNCTION_EX 376 +#define _DO_CALL_KW 377 #define _END_FOR END_FOR #define _END_SEND END_SEND -#define _ERROR_POP_N 377 +#define _ERROR_POP_N 378 #define _EXIT_INIT_CHECK EXIT_INIT_CHECK -#define _EXPAND_METHOD 378 -#define _EXPAND_METHOD_KW 379 -#define _FATAL_ERROR 380 +#define _EXPAND_METHOD 379 +#define _EXPAND_METHOD_KW 380 +#define _FATAL_ERROR 381 #define _FORMAT_SIMPLE FORMAT_SIMPLE #define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC -#define _FOR_ITER 381 -#define _FOR_ITER_GEN_FRAME 382 -#define _FOR_ITER_TIER_TWO 383 +#define _FOR_ITER 382 +#define _FOR_ITER_GEN_FRAME 383 +#define _FOR_ITER_TIER_TWO 384 #define _GET_AITER GET_AITER #define _GET_ANEXT GET_ANEXT #define _GET_AWAITABLE GET_AWAITABLE #define _GET_ITER GET_ITER #define _GET_LEN GET_LEN #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER -#define _GUARD_BINARY_OP_EXTEND 384 -#define _GUARD_CALLABLE_ISINSTANCE 385 -#define _GUARD_CALLABLE_LEN 386 -#define _GUARD_CALLABLE_LIST_APPEND 387 -#define _GUARD_CALLABLE_STR_1 388 -#define _GUARD_CALLABLE_TUPLE_1 389 -#define _GUARD_CALLABLE_TYPE_1 390 -#define _GUARD_DORV_NO_DICT 391 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 392 -#define _GUARD_GLOBALS_VERSION 393 -#define _GUARD_IS_FALSE_POP 394 -#define _GUARD_IS_NONE_POP 395 -#define _GUARD_IS_NOT_NONE_POP 396 -#define _GUARD_IS_TRUE_POP 397 -#define _GUARD_KEYS_VERSION 398 -#define _GUARD_NOS_DICT 399 -#define _GUARD_NOS_FLOAT 400 -#define _GUARD_NOS_INT 401 -#define _GUARD_NOS_LIST 402 -#define _GUARD_NOS_NOT_NULL 403 -#define _GUARD_NOS_NULL 404 -#define _GUARD_NOS_OVERFLOWED 405 -#define _GUARD_NOS_TUPLE 406 -#define _GUARD_NOS_UNICODE 407 -#define _GUARD_NOT_EXHAUSTED_LIST 408 -#define _GUARD_NOT_EXHAUSTED_RANGE 409 -#define _GUARD_NOT_EXHAUSTED_TUPLE 410 -#define _GUARD_THIRD_NULL 411 -#define _GUARD_TOS_ANY_SET 412 -#define _GUARD_TOS_DICT 413 -#define _GUARD_TOS_FLOAT 414 -#define _GUARD_TOS_INT 415 -#define _GUARD_TOS_LIST 416 -#define _GUARD_TOS_OVERFLOWED 417 -#define _GUARD_TOS_SLICE 418 -#define _GUARD_TOS_TUPLE 419 -#define _GUARD_TOS_UNICODE 420 -#define _GUARD_TYPE_VERSION 421 -#define _GUARD_TYPE_VERSION_AND_LOCK 422 +#define _GUARD_BINARY_OP_EXTEND 385 +#define _GUARD_CALLABLE_ISINSTANCE 386 +#define _GUARD_CALLABLE_LEN 387 +#define _GUARD_CALLABLE_LIST_APPEND 388 +#define _GUARD_CALLABLE_STR_1 389 +#define _GUARD_CALLABLE_TUPLE_1 390 +#define _GUARD_CALLABLE_TYPE_1 391 +#define _GUARD_DORV_NO_DICT 392 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 393 +#define _GUARD_GLOBALS_VERSION 394 +#define _GUARD_IS_FALSE_POP 395 +#define _GUARD_IS_NONE_POP 396 +#define _GUARD_IS_NOT_NONE_POP 397 +#define _GUARD_IS_TRUE_POP 398 +#define _GUARD_KEYS_VERSION 399 +#define _GUARD_NOS_DICT 400 +#define _GUARD_NOS_FLOAT 401 +#define _GUARD_NOS_INT 402 +#define _GUARD_NOS_LIST 403 +#define _GUARD_NOS_NOT_NULL 404 +#define _GUARD_NOS_NULL 405 +#define _GUARD_NOS_OVERFLOWED 406 +#define _GUARD_NOS_TUPLE 407 +#define _GUARD_NOS_UNICODE 408 +#define _GUARD_NOT_EXHAUSTED_LIST 409 +#define _GUARD_NOT_EXHAUSTED_RANGE 410 +#define _GUARD_NOT_EXHAUSTED_TUPLE 411 +#define _GUARD_THIRD_NULL 412 +#define _GUARD_TOS_ANY_SET 413 +#define _GUARD_TOS_DICT 414 +#define _GUARD_TOS_FLOAT 415 +#define _GUARD_TOS_INT 416 +#define _GUARD_TOS_LIST 417 +#define _GUARD_TOS_OVERFLOWED 418 +#define _GUARD_TOS_SLICE 419 +#define _GUARD_TOS_TUPLE 420 +#define _GUARD_TOS_UNICODE 421 +#define _GUARD_TYPE_VERSION 422 +#define _GUARD_TYPE_VERSION_AND_LOCK 423 #define _IMPORT_FROM IMPORT_FROM #define _IMPORT_NAME IMPORT_NAME -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 423 -#define _INIT_CALL_PY_EXACT_ARGS 424 -#define _INIT_CALL_PY_EXACT_ARGS_0 425 -#define _INIT_CALL_PY_EXACT_ARGS_1 426 -#define _INIT_CALL_PY_EXACT_ARGS_2 427 -#define _INIT_CALL_PY_EXACT_ARGS_3 428 -#define _INIT_CALL_PY_EXACT_ARGS_4 429 -#define _INSERT_NULL 430 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 424 +#define _INIT_CALL_PY_EXACT_ARGS 425 +#define _INIT_CALL_PY_EXACT_ARGS_0 426 +#define _INIT_CALL_PY_EXACT_ARGS_1 427 +#define _INIT_CALL_PY_EXACT_ARGS_2 428 +#define _INIT_CALL_PY_EXACT_ARGS_3 429 +#define _INIT_CALL_PY_EXACT_ARGS_4 430 +#define _INSERT_NULL 431 #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION #define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD @@ -184,177 +185,178 @@ extern "C" { #define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE -#define _IS_NONE 431 +#define _IS_NONE 432 #define _IS_OP IS_OP -#define _ITER_CHECK_LIST 432 -#define _ITER_CHECK_RANGE 433 -#define _ITER_CHECK_TUPLE 434 -#define _ITER_JUMP_LIST 435 -#define _ITER_JUMP_RANGE 436 -#define _ITER_JUMP_TUPLE 437 -#define _ITER_NEXT_LIST 438 -#define _ITER_NEXT_LIST_TIER_TWO 439 -#define _ITER_NEXT_RANGE 440 -#define _ITER_NEXT_TUPLE 441 -#define _JUMP_TO_TOP 442 +#define _ITER_CHECK_LIST 433 +#define _ITER_CHECK_RANGE 434 +#define _ITER_CHECK_TUPLE 435 +#define _ITER_JUMP_LIST 436 +#define _ITER_JUMP_RANGE 437 +#define _ITER_JUMP_TUPLE 438 +#define _ITER_NEXT_LIST 439 +#define _ITER_NEXT_LIST_TIER_TWO 440 +#define _ITER_NEXT_RANGE 441 +#define _ITER_NEXT_TUPLE 442 +#define _JUMP_TO_TOP 443 #define _LIST_APPEND LIST_APPEND #define _LIST_EXTEND LIST_EXTEND -#define _LOAD_ATTR 443 -#define _LOAD_ATTR_CLASS 444 +#define _LOAD_ATTR 444 +#define _LOAD_ATTR_CLASS 445 #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 445 -#define _LOAD_ATTR_METHOD_LAZY_DICT 446 -#define _LOAD_ATTR_METHOD_NO_DICT 447 -#define _LOAD_ATTR_METHOD_WITH_VALUES 448 -#define _LOAD_ATTR_MODULE 449 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 450 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 451 -#define _LOAD_ATTR_PROPERTY_FRAME 452 -#define _LOAD_ATTR_SLOT 453 -#define _LOAD_ATTR_WITH_HINT 454 +#define _LOAD_ATTR_INSTANCE_VALUE 446 +#define _LOAD_ATTR_METHOD_LAZY_DICT 447 +#define _LOAD_ATTR_METHOD_NO_DICT 448 +#define _LOAD_ATTR_METHOD_WITH_VALUES 449 +#define _LOAD_ATTR_MODULE 450 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 451 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 452 +#define _LOAD_ATTR_PROPERTY_FRAME 453 +#define _LOAD_ATTR_SLOT 454 +#define _LOAD_ATTR_WITH_HINT 455 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 455 +#define _LOAD_BYTECODE 456 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 456 -#define _LOAD_CONST_INLINE_BORROW 457 -#define _LOAD_CONST_UNDER_INLINE 458 -#define _LOAD_CONST_UNDER_INLINE_BORROW 459 +#define _LOAD_CONST_INLINE 457 +#define _LOAD_CONST_INLINE_BORROW 458 +#define _LOAD_CONST_UNDER_INLINE 459 +#define _LOAD_CONST_UNDER_INLINE_BORROW 460 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 460 -#define _LOAD_FAST_0 461 -#define _LOAD_FAST_1 462 -#define _LOAD_FAST_2 463 -#define _LOAD_FAST_3 464 -#define _LOAD_FAST_4 465 -#define _LOAD_FAST_5 466 -#define _LOAD_FAST_6 467 -#define _LOAD_FAST_7 468 +#define _LOAD_FAST 461 +#define _LOAD_FAST_0 462 +#define _LOAD_FAST_1 463 +#define _LOAD_FAST_2 464 +#define _LOAD_FAST_3 465 +#define _LOAD_FAST_4 466 +#define _LOAD_FAST_5 467 +#define _LOAD_FAST_6 468 +#define _LOAD_FAST_7 469 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 469 -#define _LOAD_FAST_BORROW_0 470 -#define _LOAD_FAST_BORROW_1 471 -#define _LOAD_FAST_BORROW_2 472 -#define _LOAD_FAST_BORROW_3 473 -#define _LOAD_FAST_BORROW_4 474 -#define _LOAD_FAST_BORROW_5 475 -#define _LOAD_FAST_BORROW_6 476 -#define _LOAD_FAST_BORROW_7 477 +#define _LOAD_FAST_BORROW 470 +#define _LOAD_FAST_BORROW_0 471 +#define _LOAD_FAST_BORROW_1 472 +#define _LOAD_FAST_BORROW_2 473 +#define _LOAD_FAST_BORROW_3 474 +#define _LOAD_FAST_BORROW_4 475 +#define _LOAD_FAST_BORROW_5 476 +#define _LOAD_FAST_BORROW_6 477 +#define _LOAD_FAST_BORROW_7 478 #define _LOAD_FAST_BORROW_LOAD_FAST_BORROW LOAD_FAST_BORROW_LOAD_FAST_BORROW #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 478 -#define _LOAD_GLOBAL_BUILTINS 479 -#define _LOAD_GLOBAL_MODULE 480 +#define _LOAD_GLOBAL 479 +#define _LOAD_GLOBAL_BUILTINS 480 +#define _LOAD_GLOBAL_MODULE 481 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 481 -#define _LOAD_SMALL_INT_0 482 -#define _LOAD_SMALL_INT_1 483 -#define _LOAD_SMALL_INT_2 484 -#define _LOAD_SMALL_INT_3 485 -#define _LOAD_SPECIAL 486 +#define _LOAD_SMALL_INT 482 +#define _LOAD_SMALL_INT_0 483 +#define _LOAD_SMALL_INT_1 484 +#define _LOAD_SMALL_INT_2 485 +#define _LOAD_SMALL_INT_3 486 +#define _LOAD_SPECIAL 487 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD -#define _MAKE_CALLARGS_A_TUPLE 487 +#define _MAKE_CALLARGS_A_TUPLE 488 #define _MAKE_CELL MAKE_CELL #define _MAKE_FUNCTION MAKE_FUNCTION -#define _MAKE_WARM 488 +#define _MAKE_WARM 489 #define _MAP_ADD MAP_ADD #define _MATCH_CLASS MATCH_CLASS #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 489 -#define _MAYBE_EXPAND_METHOD_KW 490 -#define _MONITOR_CALL 491 -#define _MONITOR_CALL_KW 492 -#define _MONITOR_JUMP_BACKWARD 493 -#define _MONITOR_RESUME 494 +#define _MAYBE_EXPAND_METHOD 490 +#define _MAYBE_EXPAND_METHOD_KW 491 +#define _MONITOR_CALL 492 +#define _MONITOR_CALL_KW 493 +#define _MONITOR_JUMP_BACKWARD 494 +#define _MONITOR_RESUME 495 #define _NOP NOP -#define _POP_CALL 495 -#define _POP_CALL_LOAD_CONST_INLINE_BORROW 496 -#define _POP_CALL_ONE 497 -#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 498 -#define _POP_CALL_TWO 499 -#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 500 +#define _PERIODIC 496 +#define _POP_CALL 497 +#define _POP_CALL_LOAD_CONST_INLINE_BORROW 498 +#define _POP_CALL_ONE 499 +#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 500 +#define _POP_CALL_TWO 501 +#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 502 #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 501 -#define _POP_JUMP_IF_TRUE 502 +#define _POP_JUMP_IF_FALSE 503 +#define _POP_JUMP_IF_TRUE 504 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 503 -#define _POP_TOP_INT 504 -#define _POP_TOP_LOAD_CONST_INLINE 505 -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 506 -#define _POP_TOP_NOP 507 -#define _POP_TOP_UNICODE 508 -#define _POP_TWO 509 -#define _POP_TWO_LOAD_CONST_INLINE_BORROW 510 +#define _POP_TOP_FLOAT 505 +#define _POP_TOP_INT 506 +#define _POP_TOP_LOAD_CONST_INLINE 507 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 508 +#define _POP_TOP_NOP 509 +#define _POP_TOP_UNICODE 510 +#define _POP_TWO 511 +#define _POP_TWO_LOAD_CONST_INLINE_BORROW 512 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 511 +#define _PUSH_FRAME 513 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 512 -#define _PY_FRAME_GENERAL 513 -#define _PY_FRAME_KW 514 -#define _QUICKEN_RESUME 515 -#define _REPLACE_WITH_TRUE 516 +#define _PUSH_NULL_CONDITIONAL 514 +#define _PY_FRAME_GENERAL 515 +#define _PY_FRAME_KW 516 +#define _QUICKEN_RESUME 517 +#define _REPLACE_WITH_TRUE 518 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 517 -#define _SEND 518 -#define _SEND_GEN_FRAME 519 +#define _SAVE_RETURN_OFFSET 519 +#define _SEND 520 +#define _SEND_GEN_FRAME 521 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _START_EXECUTOR 520 -#define _STORE_ATTR 521 -#define _STORE_ATTR_INSTANCE_VALUE 522 -#define _STORE_ATTR_SLOT 523 -#define _STORE_ATTR_WITH_HINT 524 +#define _START_EXECUTOR 522 +#define _STORE_ATTR 523 +#define _STORE_ATTR_INSTANCE_VALUE 524 +#define _STORE_ATTR_SLOT 525 +#define _STORE_ATTR_WITH_HINT 526 #define _STORE_DEREF STORE_DEREF -#define _STORE_FAST 525 -#define _STORE_FAST_0 526 -#define _STORE_FAST_1 527 -#define _STORE_FAST_2 528 -#define _STORE_FAST_3 529 -#define _STORE_FAST_4 530 -#define _STORE_FAST_5 531 -#define _STORE_FAST_6 532 -#define _STORE_FAST_7 533 +#define _STORE_FAST 527 +#define _STORE_FAST_0 528 +#define _STORE_FAST_1 529 +#define _STORE_FAST_2 530 +#define _STORE_FAST_3 531 +#define _STORE_FAST_4 532 +#define _STORE_FAST_5 533 +#define _STORE_FAST_6 534 +#define _STORE_FAST_7 535 #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 534 -#define _STORE_SUBSCR 535 -#define _STORE_SUBSCR_DICT 536 -#define _STORE_SUBSCR_LIST_INT 537 -#define _SWAP 538 -#define _SWAP_2 539 -#define _SWAP_3 540 -#define _TIER2_RESUME_CHECK 541 -#define _TO_BOOL 542 +#define _STORE_SLICE 536 +#define _STORE_SUBSCR 537 +#define _STORE_SUBSCR_DICT 538 +#define _STORE_SUBSCR_LIST_INT 539 +#define _SWAP 540 +#define _SWAP_2 541 +#define _SWAP_3 542 +#define _TIER2_RESUME_CHECK 543 +#define _TO_BOOL 544 #define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_INT TO_BOOL_INT -#define _TO_BOOL_LIST 543 +#define _TO_BOOL_LIST 545 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 544 +#define _TO_BOOL_STR 546 #define _UNARY_INVERT UNARY_INVERT #define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 545 -#define _UNPACK_SEQUENCE_LIST 546 -#define _UNPACK_SEQUENCE_TUPLE 547 -#define _UNPACK_SEQUENCE_TWO_TUPLE 548 +#define _UNPACK_SEQUENCE 547 +#define _UNPACK_SEQUENCE_LIST 548 +#define _UNPACK_SEQUENCE_TUPLE 549 +#define _UNPACK_SEQUENCE_TWO_TUPLE 550 #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE -#define MAX_UOP_ID 548 +#define MAX_UOP_ID 550 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index d6afdb0b4b5805..2a3c03f02cb09c 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -334,8 +334,9 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_MAKE_WARM] = 0, [_FATAL_ERROR] = 0, [_DEOPT] = 0, + [_PERIODIC] = HAS_ESCAPES_FLAG, [_ERROR_POP_N] = HAS_ARG_FLAG, - [_TIER2_RESUME_CHECK] = HAS_DEOPT_FLAG, + [_TIER2_RESUME_CHECK] = HAS_PERIODIC_FLAG, [_COLD_EXIT] = HAS_ESCAPES_FLAG, }; @@ -590,6 +591,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_MAYBE_EXPAND_METHOD] = "_MAYBE_EXPAND_METHOD", [_MAYBE_EXPAND_METHOD_KW] = "_MAYBE_EXPAND_METHOD_KW", [_NOP] = "_NOP", + [_PERIODIC] = "_PERIODIC", [_POP_CALL] = "_POP_CALL", [_POP_CALL_LOAD_CONST_INLINE_BORROW] = "_POP_CALL_LOAD_CONST_INLINE_BORROW", [_POP_CALL_ONE] = "_POP_CALL_ONE", @@ -1299,6 +1301,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _DEOPT: return 0; + case _PERIODIC: + return 0; case _ERROR_POP_N: return 0; case _TIER2_RESUME_CHECK: diff --git a/Python/bytecodes.c b/Python/bytecodes.c index cdc0a785c6d72e..12d1d6d63dc190 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -161,6 +161,15 @@ dummy_func( } } + replaced op(_CHECK_PERIODIC_AT_END, (--)) { + _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); + QSBR_QUIESCENT_STATE(tstate); + if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { + int err = _Py_HandlePending(tstate); + ERROR_IF(err != 0); + } + } + op(_CHECK_PERIODIC_IF_NOT_YIELD_FROM, (--)) { if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); @@ -3794,8 +3803,8 @@ dummy_func( ERROR_IF(err); } - macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC; - macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC; + macro(CALL) = _SPECIALIZE_CALL + unused/2 + _MAYBE_EXPAND_METHOD + _DO_CALL + _CHECK_PERIODIC_AT_END; + macro(INSTRUMENTED_CALL) = unused/3 + _MAYBE_EXPAND_METHOD + _MONITOR_CALL + _DO_CALL + _CHECK_PERIODIC_AT_END; op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -3916,7 +3925,7 @@ dummy_func( unused/2 + _CHECK_IS_NOT_PY_CALLABLE + _CALL_NON_PY_GENERAL + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) { EXIT_IF(!PyStackRef_IsNull(null)); @@ -4073,7 +4082,7 @@ dummy_func( _GUARD_NOS_NULL + _GUARD_CALLABLE_STR_1 + _CALL_STR_1 + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_GUARD_CALLABLE_TUPLE_1, (callable, unused, unused -- callable, unused, unused)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -4101,7 +4110,7 @@ dummy_func( _GUARD_NOS_NULL + _GUARD_CALLABLE_TUPLE_1 + _CALL_TUPLE_1 + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -4197,7 +4206,7 @@ dummy_func( unused/1 + unused/2 + _CALL_BUILTIN_CLASS + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CALL_BUILTIN_O, (callable, self_or_null, args[oparg] -- res)) { /* Builtin METH_O functions */ @@ -4232,7 +4241,7 @@ dummy_func( unused/1 + unused/2 + _CALL_BUILTIN_O + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CALL_BUILTIN_FAST, (callable, self_or_null, args[oparg] -- res)) { /* Builtin METH_FASTCALL functions, without keywords */ @@ -4269,7 +4278,7 @@ dummy_func( unused/1 + unused/2 + _CALL_BUILTIN_FAST + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CALL_BUILTIN_FAST_WITH_KEYWORDS, (callable, self_or_null, args[oparg] -- res)) { /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ @@ -4305,7 +4314,7 @@ dummy_func( unused/1 + unused/2 + _CALL_BUILTIN_FAST_WITH_KEYWORDS + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; macro(CALL_LEN) = unused/1 + @@ -4443,7 +4452,7 @@ dummy_func( unused/1 + unused/2 + _CALL_METHOD_DESCRIPTOR_O + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (callable, self_or_null, args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -4485,7 +4494,7 @@ dummy_func( unused/1 + unused/2 + _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CALL_METHOD_DESCRIPTOR_NOARGS, (callable, self_or_null, args[oparg] -- res)) { assert(oparg == 0 || oparg == 1); @@ -4523,7 +4532,7 @@ dummy_func( unused/1 + unused/2 + _CALL_METHOD_DESCRIPTOR_NOARGS + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_CALL_METHOD_DESCRIPTOR_FAST, (callable, self_or_null, args[oparg] -- res)) { PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable); @@ -4564,7 +4573,7 @@ dummy_func( unused/1 + unused/2 + _CALL_METHOD_DESCRIPTOR_FAST + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; // Cache layout: counter/1, func_version/2 family(CALL_KW, INLINE_CACHE_ENTRIES_CALL_KW) = { @@ -4820,7 +4829,7 @@ dummy_func( unused/2 + _CHECK_IS_NOT_PY_CALLABLE_KW + _CALL_KW_NON_PY + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs -- func, unused, callargs, kwargs)) { PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs); @@ -4921,12 +4930,12 @@ dummy_func( macro(CALL_FUNCTION_EX) = _MAKE_CALLARGS_A_TUPLE + _DO_CALL_FUNCTION_EX + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; macro(INSTRUMENTED_CALL_FUNCTION_EX) = _MAKE_CALLARGS_A_TUPLE + _DO_CALL_FUNCTION_EX + - _CHECK_PERIODIC; + _CHECK_PERIODIC_AT_END; inst(MAKE_FUNCTION, (codeobj_st -- func)) { PyObject *codeobj = PyStackRef_AsPyObjectBorrow(codeobj_st); @@ -5189,23 +5198,20 @@ dummy_func( op (_GUARD_IS_TRUE_POP, (flag -- )) { int is_true = PyStackRef_IsTrue(flag); DEAD(flag); - SYNC_SP(); - EXIT_IF(!is_true); + EXIT_IF_AFTER(!is_true); } op (_GUARD_IS_FALSE_POP, (flag -- )) { int is_false = PyStackRef_IsFalse(flag); DEAD(flag); - SYNC_SP(); - EXIT_IF(!is_false); + EXIT_IF_AFTER(!is_false); } op (_GUARD_IS_NONE_POP, (val -- )) { int is_none = PyStackRef_IsNone(val); if (!is_none) { PyStackRef_CLOSE(val); - SYNC_SP(); - EXIT_IF(1); + EXIT_IF_AFTER(1); } DEAD(val); } @@ -5213,8 +5219,7 @@ dummy_func( op (_GUARD_IS_NOT_NONE_POP, (val -- )) { int is_none = PyStackRef_IsNone(val); PyStackRef_CLOSE(val); - SYNC_SP(); - EXIT_IF(is_none); + EXIT_IF_AFTER(is_none); } op(_JUMP_TO_TOP, (--)) { @@ -5380,6 +5385,11 @@ dummy_func( GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET()); } + tier2 op(_PERIODIC, (--)) { + int err = _Py_HandlePending(tstate); + GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET()); + } + tier2 op(_ERROR_POP_N, (target/2 --)) { assert(oparg == 0); frame->instr_ptr = _PyFrame_GetBytecode(frame) + target; @@ -5391,11 +5401,11 @@ dummy_func( * ENTER_EXECUTOR will not re-enter tier 2 with the eval breaker set. */ tier2 op(_TIER2_RESUME_CHECK, (--)) { #if defined(__EMSCRIPTEN__) - DEOPT_IF(_Py_emscripten_signal_clock == 0); + PERIODIC_IF(_Py_emscripten_signal_clock == 0); _Py_emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING; #endif uintptr_t eval_breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker); - DEOPT_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); + PERIODIC_IF(eval_breaker & _PY_EVAL_EVENTS_MASK); assert(tstate->tracing || eval_breaker == FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version)); } diff --git a/Python/ceval.c b/Python/ceval.c index e1045808af93d8..94c24187f6b25f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1211,6 +1211,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int printf(" @ %d -> %s]\n", (int)(next_uop - current_executor->trace - 1), _PyOpcode_OpName[frame->instr_ptr->op.code]); + fflush(stdout); } #endif assert(next_uop[-1].format == UOP_FORMAT_JUMP); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index c10797e3d8b1b2..900a0fe390468d 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -26,6 +26,8 @@ break; } + /* _CHECK_PERIODIC_AT_END is not a viable micro-op for tier 2 because it is replaced */ + case _CHECK_PERIODIC_IF_NOT_YIELD_FROM: { oparg = CURRENT_OPARG(); if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) { @@ -7443,6 +7445,14 @@ break; } + case _PERIODIC: { + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = _Py_HandlePending(tstate); + stack_pointer = _PyFrame_GetStackPointer(frame); + GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET()); + break; + } + case _ERROR_POP_N: { oparg = CURRENT_OPARG(); uint32_t target = (uint32_t)CURRENT_OPERAND0(); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index b83ab941ed2b70..cb867e51ae743c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1670,7 +1670,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -2175,7 +2175,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -2292,7 +2292,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -2409,7 +2409,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -2501,7 +2501,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -2676,7 +2676,7 @@ } result = PyStackRef_FromPyObjectSteal(result_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -3268,7 +3268,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -3659,7 +3659,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -3790,7 +3790,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -3891,7 +3891,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -4005,7 +4005,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -4128,7 +4128,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -4421,7 +4421,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -4501,7 +4501,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -6517,7 +6517,7 @@ } res = PyStackRef_FromPyObjectSteal(res_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); @@ -6692,7 +6692,7 @@ } result = PyStackRef_FromPyObjectSteal(result_o); } - // _CHECK_PERIODIC + // _CHECK_PERIODIC_AT_END { _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); QSBR_QUIESCENT_STATE(tstate); diff --git a/Python/optimizer.c b/Python/optimizer.c index 6a9b6824a531ac..4a4a4b8cb497af 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -432,6 +432,7 @@ _PyUOp_Replacements[MAX_UOP_ID + 1] = { [_ITER_JUMP_TUPLE] = _GUARD_NOT_EXHAUSTED_TUPLE, [_FOR_ITER] = _FOR_ITER_TIER_TWO, [_ITER_NEXT_LIST] = _ITER_NEXT_LIST_TIER_TWO, + [_CHECK_PERIODIC_AT_END] = _TIER2_RESUME_CHECK, }; static const uint8_t @@ -776,9 +777,12 @@ translate_bytecode_to_trace( case OPARG_REPLACED: uop = _PyUOp_Replacements[uop]; assert(uop != 0); + uint32_t next_inst = target + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + (oparg > 255); + if (uop == _TIER2_RESUME_CHECK) { + target = next_inst; + } #ifdef Py_DEBUG - { - uint32_t next_inst = target + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + (oparg > 255); + else { uint32_t jump_target = next_inst + oparg; assert(_Py_GetBaseCodeUnit(code, jump_target).op.code == END_FOR); assert(_Py_GetBaseCodeUnit(code, jump_target+1).op.code == POP_ITER); @@ -1043,9 +1047,15 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length) _PyUOpInstruction *inst = &buffer[i]; int opcode = inst->opcode; int32_t target = (int32_t)uop_get_target(inst); - if (_PyUop_Flags[opcode] & (HAS_EXIT_FLAG | HAS_DEOPT_FLAG)) { - uint16_t exit_op = (_PyUop_Flags[opcode] & HAS_EXIT_FLAG) ? - _EXIT_TRACE : _DEOPT; + uint16_t exit_flags = _PyUop_Flags[opcode] & (HAS_EXIT_FLAG | HAS_DEOPT_FLAG | HAS_PERIODIC_FLAG); + if (exit_flags) { + uint16_t exit_op = _EXIT_TRACE; + if (exit_flags & HAS_DEOPT_FLAG) { + exit_op = _DEOPT; + } + else if (exit_flags & HAS_PERIODIC_FLAG) { + exit_op = _PERIODIC; + } int32_t jump_target = target; if (is_for_iter_test[opcode]) { /* Target the POP_TOP immediately after the END_FOR, @@ -1159,6 +1169,7 @@ sanity_check(_PyExecutorObject *executor) uint16_t opcode = inst->opcode; CHECK( opcode == _DEOPT || + opcode == _PERIODIC || opcode == _EXIT_TRACE || opcode == _ERROR_POP_N); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 6ec85a93f46b3e..37da3970660b43 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -11,6 +11,8 @@ break; } + /* _CHECK_PERIODIC_AT_END is not a viable micro-op for tier 2 */ + case _CHECK_PERIODIC_IF_NOT_YIELD_FROM: { break; } @@ -3198,6 +3200,10 @@ break; } + case _PERIODIC: { + break; + } + case _ERROR_POP_N: { break; } diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index a3c38ecdea3e1f..fc89b39dc69b19 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -20,6 +20,7 @@ class Properties: error_with_pop: bool error_without_pop: bool deopts: bool + deopts_periodic: bool oparg: bool jumps: bool eval_breaker: bool @@ -58,6 +59,7 @@ def from_list(properties: list["Properties"]) -> "Properties": error_with_pop=any(p.error_with_pop for p in properties), error_without_pop=any(p.error_without_pop for p in properties), deopts=any(p.deopts for p in properties), + deopts_periodic=any(p.deopts_periodic for p in properties), oparg=any(p.oparg for p in properties), jumps=any(p.jumps for p in properties), eval_breaker=any(p.eval_breaker for p in properties), @@ -85,6 +87,7 @@ def infallible(self) -> bool: error_with_pop=False, error_without_pop=False, deopts=False, + deopts_periodic=False, oparg=False, jumps=False, eval_breaker=False, @@ -706,7 +709,7 @@ def visit(stmt: Stmt) -> None: in_if = 0 tkn_iter = iter(stmt.contents) for tkn in tkn_iter: - if tkn.kind == "IDENTIFIER" and tkn.text in ("DEOPT_IF", "ERROR_IF", "EXIT_IF"): + if tkn.kind == "IDENTIFIER" and tkn.text in ("DEOPT_IF", "ERROR_IF", "EXIT_IF", "PERIODIC_IF", "EXIT_IF_AFTER"): in_if = 1 next(tkn_iter) elif tkn.kind == "LPAREN": @@ -833,7 +836,7 @@ def stmt_is_simple_exit(stmt: Stmt) -> bool: if len(tokens) < 4: return False return ( - tokens[0].text in ("ERROR_IF", "DEOPT_IF", "EXIT_IF") + tokens[0].text in ("ERROR_IF", "DEOPT_IF", "EXIT_IF", "EXIT_IF_AFTER") and tokens[1].text == "(" and @@ -889,11 +892,13 @@ def compute_properties(op: parser.CodeDef) -> Properties: or variable_used(op, "PyCell_SwapTakeRef") ) deopts_if = variable_used(op, "DEOPT_IF") - exits_if = variable_used(op, "EXIT_IF") - if deopts_if and exits_if: + exits_if = variable_used(op, "EXIT_IF") or variable_used(op, "EXIT_IF_AFTER") + deopts_periodic = variable_used(op, "PERIODIC_IF") + exits_and_deopts = sum((deopts_if, exits_if, deopts_periodic)) + if exits_and_deopts > 1: tkn = op.tokens[0] raise lexer.make_syntax_error( - "Op cannot contain both EXIT_IF and DEOPT_IF", + "Op cannot contain more than one of EXIT_IF, DEOPT_IF and PERIODIC_IF", tkn.filename, tkn.line, tkn.column, @@ -910,6 +915,7 @@ def compute_properties(op: parser.CodeDef) -> Properties: error_with_pop=error_with_pop, error_without_pop=error_without_pop, deopts=deopts_if, + deopts_periodic=deopts_periodic, side_exit=exits_if, oparg=oparg_used(op), jumps=variable_used(op, "JUMPBY"), diff --git a/Tools/cases_generator/generators_common.py b/Tools/cases_generator/generators_common.py index 4c210fbf8d28e9..2352755638c4b2 100644 --- a/Tools/cases_generator/generators_common.py +++ b/Tools/cases_generator/generators_common.py @@ -111,7 +111,9 @@ class Emitter: def __init__(self, out: CWriter, labels: dict[str, Label], cannot_escape: bool = False): self._replacers = { "EXIT_IF": self.exit_if, + "EXIT_IF_AFTER": self.exit_if_after, "DEOPT_IF": self.deopt_if, + "PERIODIC_IF": self.periodic_if, "ERROR_IF": self.error_if, "ERROR_NO_POP": self.error_no_pop, "DECREF_INPUTS": self.decref_inputs, @@ -171,6 +173,29 @@ def deopt_if( exit_if = deopt_if + def periodic_if( + self, + tkn: Token, + tkn_iter: TokenIterator, + uop: CodeSection, + storage: Storage, + inst: Instruction | None, + ) -> bool: + raise NotImplementedError("PERIODIC_IF not support in tier 1") + + def exit_if_after( + self, + tkn: Token, + tkn_iter: TokenIterator, + uop: CodeSection, + storage: Storage, + inst: Instruction | None, + ) -> bool: + storage.clear_inputs("in EXIT_IF_AFTER") + storage.flush(self.out) + storage.stack.clear(self.out) + return self.exit_if(tkn, tkn_iter, uop, storage, inst) + def goto_error(self, offset: int, storage: Storage) -> str: if offset > 0: return f"JUMP_TO_LABEL(pop_{offset}_error);" @@ -692,6 +717,8 @@ def cflags(p: Properties) -> str: flags.append("HAS_EVAL_BREAK_FLAG") if p.deopts: flags.append("HAS_DEOPT_FLAG") + if p.deopts_periodic: + flags.append("HAS_PERIODIC_FLAG") if p.side_exit: flags.append("HAS_EXIT_FLAG") if not p.infallible: diff --git a/Tools/cases_generator/opcode_metadata_generator.py b/Tools/cases_generator/opcode_metadata_generator.py index 0bcdc5395dcd8e..b649b38123388d 100644 --- a/Tools/cases_generator/opcode_metadata_generator.py +++ b/Tools/cases_generator/opcode_metadata_generator.py @@ -53,10 +53,9 @@ "ESCAPES", "EXIT", "PURE", - "PASSTHROUGH", - "OPARG_AND_1", "ERROR_NO_POP", "NO_SAVE_IP", + "PERIODIC", ] diff --git a/Tools/cases_generator/tier1_generator.py b/Tools/cases_generator/tier1_generator.py index 32dc346d5e891a..5cb35a44fb6be6 100644 --- a/Tools/cases_generator/tier1_generator.py +++ b/Tools/cases_generator/tier1_generator.py @@ -132,7 +132,7 @@ def uses_this(inst: Instruction) -> bool: continue for tkn in uop.body.tokens(): if (tkn.kind == "IDENTIFIER" - and (tkn.text in {"DEOPT_IF", "EXIT_IF"})): + and (tkn.text in {"DEOPT_IF", "EXIT_IF", "EXIT_IF_AFTER"})): return True return False diff --git a/Tools/cases_generator/tier2_generator.py b/Tools/cases_generator/tier2_generator.py index fc3bc47286f7f6..1bb5f48658ddfc 100644 --- a/Tools/cases_generator/tier2_generator.py +++ b/Tools/cases_generator/tier2_generator.py @@ -111,6 +111,8 @@ def exit_if( self.emit("}\n") return not always_true(first_tkn) + periodic_if = deopt_if + def oparg( self, tkn: Token, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy