gh-120619: Strength reduce function guards, support 2-operand uop forms (GH-124846)

Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
This commit is contained in:
Ken Jin 2024-11-09 11:35:33 +08:00 committed by GitHub
parent f8276bf5f3
commit 6293d00e72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 379 additions and 270 deletions

View file

@ -58,7 +58,8 @@ typedef struct {
uint16_t error_target; uint16_t error_target;
}; };
}; };
uint64_t operand; // A cache entry uint64_t operand0; // A cache entry
uint64_t operand1;
} _PyUOpInstruction; } _PyUOpInstruction;
typedef struct { typedef struct {

View file

@ -63,90 +63,91 @@ extern "C" {
#define _CHECK_FUNCTION 333 #define _CHECK_FUNCTION 333
#define _CHECK_FUNCTION_EXACT_ARGS 334 #define _CHECK_FUNCTION_EXACT_ARGS 334
#define _CHECK_FUNCTION_VERSION 335 #define _CHECK_FUNCTION_VERSION 335
#define _CHECK_FUNCTION_VERSION_KW 336 #define _CHECK_FUNCTION_VERSION_INLINE 336
#define _CHECK_IS_NOT_PY_CALLABLE 337 #define _CHECK_FUNCTION_VERSION_KW 337
#define _CHECK_IS_NOT_PY_CALLABLE_KW 338 #define _CHECK_IS_NOT_PY_CALLABLE 338
#define _CHECK_MANAGED_OBJECT_HAS_VALUES 339 #define _CHECK_IS_NOT_PY_CALLABLE_KW 339
#define _CHECK_METHOD_VERSION 340 #define _CHECK_MANAGED_OBJECT_HAS_VALUES 340
#define _CHECK_METHOD_VERSION_KW 341 #define _CHECK_METHOD_VERSION 341
#define _CHECK_PEP_523 342 #define _CHECK_METHOD_VERSION_KW 342
#define _CHECK_PERIODIC 343 #define _CHECK_PEP_523 343
#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 344 #define _CHECK_PERIODIC 344
#define _CHECK_STACK_SPACE 345 #define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 345
#define _CHECK_STACK_SPACE_OPERAND 346 #define _CHECK_STACK_SPACE 346
#define _CHECK_VALIDITY 347 #define _CHECK_STACK_SPACE_OPERAND 347
#define _CHECK_VALIDITY_AND_SET_IP 348 #define _CHECK_VALIDITY 348
#define _COMPARE_OP 349 #define _CHECK_VALIDITY_AND_SET_IP 349
#define _COMPARE_OP_FLOAT 350 #define _COMPARE_OP 350
#define _COMPARE_OP_INT 351 #define _COMPARE_OP_FLOAT 351
#define _COMPARE_OP_STR 352 #define _COMPARE_OP_INT 352
#define _CONTAINS_OP 353 #define _COMPARE_OP_STR 353
#define _CONTAINS_OP 354
#define _CONTAINS_OP_DICT CONTAINS_OP_DICT #define _CONTAINS_OP_DICT CONTAINS_OP_DICT
#define _CONTAINS_OP_SET CONTAINS_OP_SET #define _CONTAINS_OP_SET CONTAINS_OP_SET
#define _CONVERT_VALUE CONVERT_VALUE #define _CONVERT_VALUE CONVERT_VALUE
#define _COPY COPY #define _COPY COPY
#define _COPY_FREE_VARS COPY_FREE_VARS #define _COPY_FREE_VARS COPY_FREE_VARS
#define _CREATE_INIT_FRAME 354 #define _CREATE_INIT_FRAME 355
#define _DELETE_ATTR DELETE_ATTR #define _DELETE_ATTR DELETE_ATTR
#define _DELETE_DEREF DELETE_DEREF #define _DELETE_DEREF DELETE_DEREF
#define _DELETE_FAST DELETE_FAST #define _DELETE_FAST DELETE_FAST
#define _DELETE_GLOBAL DELETE_GLOBAL #define _DELETE_GLOBAL DELETE_GLOBAL
#define _DELETE_NAME DELETE_NAME #define _DELETE_NAME DELETE_NAME
#define _DELETE_SUBSCR DELETE_SUBSCR #define _DELETE_SUBSCR DELETE_SUBSCR
#define _DEOPT 355 #define _DEOPT 356
#define _DICT_MERGE DICT_MERGE #define _DICT_MERGE DICT_MERGE
#define _DICT_UPDATE DICT_UPDATE #define _DICT_UPDATE DICT_UPDATE
#define _DO_CALL 356 #define _DO_CALL 357
#define _DO_CALL_FUNCTION_EX 357 #define _DO_CALL_FUNCTION_EX 358
#define _DO_CALL_KW 358 #define _DO_CALL_KW 359
#define _DYNAMIC_EXIT 359 #define _DYNAMIC_EXIT 360
#define _END_SEND END_SEND #define _END_SEND END_SEND
#define _ERROR_POP_N 360 #define _ERROR_POP_N 361
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK #define _EXIT_INIT_CHECK EXIT_INIT_CHECK
#define _EXPAND_METHOD 361 #define _EXPAND_METHOD 362
#define _EXPAND_METHOD_KW 362 #define _EXPAND_METHOD_KW 363
#define _FATAL_ERROR 363 #define _FATAL_ERROR 364
#define _FORMAT_SIMPLE FORMAT_SIMPLE #define _FORMAT_SIMPLE FORMAT_SIMPLE
#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC #define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
#define _FOR_ITER 364 #define _FOR_ITER 365
#define _FOR_ITER_GEN_FRAME 365 #define _FOR_ITER_GEN_FRAME 366
#define _FOR_ITER_TIER_TWO 366 #define _FOR_ITER_TIER_TWO 367
#define _GET_AITER GET_AITER #define _GET_AITER GET_AITER
#define _GET_ANEXT GET_ANEXT #define _GET_ANEXT GET_ANEXT
#define _GET_AWAITABLE GET_AWAITABLE #define _GET_AWAITABLE GET_AWAITABLE
#define _GET_ITER GET_ITER #define _GET_ITER GET_ITER
#define _GET_LEN GET_LEN #define _GET_LEN GET_LEN
#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER #define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
#define _GUARD_BOTH_FLOAT 367 #define _GUARD_BOTH_FLOAT 368
#define _GUARD_BOTH_INT 368 #define _GUARD_BOTH_INT 369
#define _GUARD_BOTH_UNICODE 369 #define _GUARD_BOTH_UNICODE 370
#define _GUARD_BUILTINS_VERSION_PUSH_KEYS 370 #define _GUARD_BUILTINS_VERSION_PUSH_KEYS 371
#define _GUARD_DORV_NO_DICT 371 #define _GUARD_DORV_NO_DICT 372
#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 372 #define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 373
#define _GUARD_GLOBALS_VERSION 373 #define _GUARD_GLOBALS_VERSION 374
#define _GUARD_GLOBALS_VERSION_PUSH_KEYS 374 #define _GUARD_GLOBALS_VERSION_PUSH_KEYS 375
#define _GUARD_IS_FALSE_POP 375 #define _GUARD_IS_FALSE_POP 376
#define _GUARD_IS_NONE_POP 376 #define _GUARD_IS_NONE_POP 377
#define _GUARD_IS_NOT_NONE_POP 377 #define _GUARD_IS_NOT_NONE_POP 378
#define _GUARD_IS_TRUE_POP 378 #define _GUARD_IS_TRUE_POP 379
#define _GUARD_KEYS_VERSION 379 #define _GUARD_KEYS_VERSION 380
#define _GUARD_NOS_FLOAT 380 #define _GUARD_NOS_FLOAT 381
#define _GUARD_NOS_INT 381 #define _GUARD_NOS_INT 382
#define _GUARD_NOT_EXHAUSTED_LIST 382 #define _GUARD_NOT_EXHAUSTED_LIST 383
#define _GUARD_NOT_EXHAUSTED_RANGE 383 #define _GUARD_NOT_EXHAUSTED_RANGE 384
#define _GUARD_NOT_EXHAUSTED_TUPLE 384 #define _GUARD_NOT_EXHAUSTED_TUPLE 385
#define _GUARD_TOS_FLOAT 385 #define _GUARD_TOS_FLOAT 386
#define _GUARD_TOS_INT 386 #define _GUARD_TOS_INT 387
#define _GUARD_TYPE_VERSION 387 #define _GUARD_TYPE_VERSION 388
#define _IMPORT_FROM IMPORT_FROM #define _IMPORT_FROM IMPORT_FROM
#define _IMPORT_NAME IMPORT_NAME #define _IMPORT_NAME IMPORT_NAME
#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 388 #define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 389
#define _INIT_CALL_PY_EXACT_ARGS 389 #define _INIT_CALL_PY_EXACT_ARGS 390
#define _INIT_CALL_PY_EXACT_ARGS_0 390 #define _INIT_CALL_PY_EXACT_ARGS_0 391
#define _INIT_CALL_PY_EXACT_ARGS_1 391 #define _INIT_CALL_PY_EXACT_ARGS_1 392
#define _INIT_CALL_PY_EXACT_ARGS_2 392 #define _INIT_CALL_PY_EXACT_ARGS_2 393
#define _INIT_CALL_PY_EXACT_ARGS_3 393 #define _INIT_CALL_PY_EXACT_ARGS_3 394
#define _INIT_CALL_PY_EXACT_ARGS_4 394 #define _INIT_CALL_PY_EXACT_ARGS_4 395
#define _INSTRUMENTED_CALL_FUNCTION_EX INSTRUMENTED_CALL_FUNCTION_EX #define _INSTRUMENTED_CALL_FUNCTION_EX INSTRUMENTED_CALL_FUNCTION_EX
#define _INSTRUMENTED_CALL_KW INSTRUMENTED_CALL_KW #define _INSTRUMENTED_CALL_KW INSTRUMENTED_CALL_KW
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER #define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
@ -158,142 +159,142 @@ extern "C" {
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE #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_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE #define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
#define _INTERNAL_INCREMENT_OPT_COUNTER 395 #define _INTERNAL_INCREMENT_OPT_COUNTER 396
#define _IS_NONE 396 #define _IS_NONE 397
#define _IS_OP IS_OP #define _IS_OP IS_OP
#define _ITER_CHECK_LIST 397 #define _ITER_CHECK_LIST 398
#define _ITER_CHECK_RANGE 398 #define _ITER_CHECK_RANGE 399
#define _ITER_CHECK_TUPLE 399 #define _ITER_CHECK_TUPLE 400
#define _ITER_JUMP_LIST 400 #define _ITER_JUMP_LIST 401
#define _ITER_JUMP_RANGE 401 #define _ITER_JUMP_RANGE 402
#define _ITER_JUMP_TUPLE 402 #define _ITER_JUMP_TUPLE 403
#define _ITER_NEXT_LIST 403 #define _ITER_NEXT_LIST 404
#define _ITER_NEXT_RANGE 404 #define _ITER_NEXT_RANGE 405
#define _ITER_NEXT_TUPLE 405 #define _ITER_NEXT_TUPLE 406
#define _JUMP_TO_TOP 406 #define _JUMP_TO_TOP 407
#define _LIST_APPEND LIST_APPEND #define _LIST_APPEND LIST_APPEND
#define _LIST_EXTEND LIST_EXTEND #define _LIST_EXTEND LIST_EXTEND
#define _LOAD_ATTR 407 #define _LOAD_ATTR 408
#define _LOAD_ATTR_CLASS 408 #define _LOAD_ATTR_CLASS 409
#define _LOAD_ATTR_CLASS_0 409 #define _LOAD_ATTR_CLASS_0 410
#define _LOAD_ATTR_CLASS_1 410 #define _LOAD_ATTR_CLASS_1 411
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN #define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
#define _LOAD_ATTR_INSTANCE_VALUE 411 #define _LOAD_ATTR_INSTANCE_VALUE 412
#define _LOAD_ATTR_INSTANCE_VALUE_0 412 #define _LOAD_ATTR_INSTANCE_VALUE_0 413
#define _LOAD_ATTR_INSTANCE_VALUE_1 413 #define _LOAD_ATTR_INSTANCE_VALUE_1 414
#define _LOAD_ATTR_METHOD_LAZY_DICT 414 #define _LOAD_ATTR_METHOD_LAZY_DICT 415
#define _LOAD_ATTR_METHOD_NO_DICT 415 #define _LOAD_ATTR_METHOD_NO_DICT 416
#define _LOAD_ATTR_METHOD_WITH_VALUES 416 #define _LOAD_ATTR_METHOD_WITH_VALUES 417
#define _LOAD_ATTR_MODULE 417 #define _LOAD_ATTR_MODULE 418
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 418 #define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 419
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 419 #define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 420
#define _LOAD_ATTR_PROPERTY_FRAME 420 #define _LOAD_ATTR_PROPERTY_FRAME 421
#define _LOAD_ATTR_SLOT 421 #define _LOAD_ATTR_SLOT 422
#define _LOAD_ATTR_SLOT_0 422 #define _LOAD_ATTR_SLOT_0 423
#define _LOAD_ATTR_SLOT_1 423 #define _LOAD_ATTR_SLOT_1 424
#define _LOAD_ATTR_WITH_HINT 424 #define _LOAD_ATTR_WITH_HINT 425
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
#define _LOAD_BYTECODE 425 #define _LOAD_BYTECODE 426
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST #define _LOAD_CONST LOAD_CONST
#define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL #define _LOAD_CONST_IMMORTAL LOAD_CONST_IMMORTAL
#define _LOAD_CONST_INLINE 426 #define _LOAD_CONST_INLINE 427
#define _LOAD_CONST_INLINE_BORROW 427 #define _LOAD_CONST_INLINE_BORROW 428
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 428 #define _LOAD_CONST_INLINE_BORROW_WITH_NULL 429
#define _LOAD_CONST_INLINE_WITH_NULL 429 #define _LOAD_CONST_INLINE_WITH_NULL 430
#define _LOAD_DEREF LOAD_DEREF #define _LOAD_DEREF LOAD_DEREF
#define _LOAD_FAST 430 #define _LOAD_FAST 431
#define _LOAD_FAST_0 431 #define _LOAD_FAST_0 432
#define _LOAD_FAST_1 432 #define _LOAD_FAST_1 433
#define _LOAD_FAST_2 433 #define _LOAD_FAST_2 434
#define _LOAD_FAST_3 434 #define _LOAD_FAST_3 435
#define _LOAD_FAST_4 435 #define _LOAD_FAST_4 436
#define _LOAD_FAST_5 436 #define _LOAD_FAST_5 437
#define _LOAD_FAST_6 437 #define _LOAD_FAST_6 438
#define _LOAD_FAST_7 438 #define _LOAD_FAST_7 439
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST #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_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
#define _LOAD_GLOBAL 439 #define _LOAD_GLOBAL 440
#define _LOAD_GLOBAL_BUILTINS 440 #define _LOAD_GLOBAL_BUILTINS 441
#define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 441 #define _LOAD_GLOBAL_BUILTINS_FROM_KEYS 442
#define _LOAD_GLOBAL_MODULE 442 #define _LOAD_GLOBAL_MODULE 443
#define _LOAD_GLOBAL_MODULE_FROM_KEYS 443 #define _LOAD_GLOBAL_MODULE_FROM_KEYS 444
#define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_NAME LOAD_NAME #define _LOAD_NAME LOAD_NAME
#define _LOAD_SMALL_INT 444 #define _LOAD_SMALL_INT 445
#define _LOAD_SMALL_INT_0 445 #define _LOAD_SMALL_INT_0 446
#define _LOAD_SMALL_INT_1 446 #define _LOAD_SMALL_INT_1 447
#define _LOAD_SMALL_INT_2 447 #define _LOAD_SMALL_INT_2 448
#define _LOAD_SMALL_INT_3 448 #define _LOAD_SMALL_INT_3 449
#define _LOAD_SPECIAL LOAD_SPECIAL #define _LOAD_SPECIAL LOAD_SPECIAL
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD #define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
#define _MAKE_CALLARGS_A_TUPLE 449 #define _MAKE_CALLARGS_A_TUPLE 450
#define _MAKE_CELL MAKE_CELL #define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION #define _MAKE_FUNCTION MAKE_FUNCTION
#define _MAKE_WARM 450 #define _MAKE_WARM 451
#define _MAP_ADD MAP_ADD #define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS #define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS #define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE #define _MATCH_SEQUENCE MATCH_SEQUENCE
#define _MAYBE_EXPAND_METHOD 451 #define _MAYBE_EXPAND_METHOD 452
#define _MAYBE_EXPAND_METHOD_KW 452 #define _MAYBE_EXPAND_METHOD_KW 453
#define _MONITOR_CALL 453 #define _MONITOR_CALL 454
#define _MONITOR_JUMP_BACKWARD 454 #define _MONITOR_JUMP_BACKWARD 455
#define _MONITOR_RESUME 455 #define _MONITOR_RESUME 456
#define _NOP NOP #define _NOP NOP
#define _POP_EXCEPT POP_EXCEPT #define _POP_EXCEPT POP_EXCEPT
#define _POP_JUMP_IF_FALSE 456 #define _POP_JUMP_IF_FALSE 457
#define _POP_JUMP_IF_TRUE 457 #define _POP_JUMP_IF_TRUE 458
#define _POP_TOP POP_TOP #define _POP_TOP POP_TOP
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 458 #define _POP_TOP_LOAD_CONST_INLINE_BORROW 459
#define _PUSH_EXC_INFO PUSH_EXC_INFO #define _PUSH_EXC_INFO PUSH_EXC_INFO
#define _PUSH_FRAME 459 #define _PUSH_FRAME 460
#define _PUSH_NULL PUSH_NULL #define _PUSH_NULL PUSH_NULL
#define _PY_FRAME_GENERAL 460 #define _PY_FRAME_GENERAL 461
#define _PY_FRAME_KW 461 #define _PY_FRAME_KW 462
#define _QUICKEN_RESUME 462 #define _QUICKEN_RESUME 463
#define _REPLACE_WITH_TRUE 463 #define _REPLACE_WITH_TRUE 464
#define _RESUME_CHECK RESUME_CHECK #define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE #define _RETURN_VALUE RETURN_VALUE
#define _SAVE_RETURN_OFFSET 464 #define _SAVE_RETURN_OFFSET 465
#define _SEND 465 #define _SEND 466
#define _SEND_GEN_FRAME 466 #define _SEND_GEN_FRAME 467
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD #define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE #define _SET_UPDATE SET_UPDATE
#define _START_EXECUTOR 467 #define _START_EXECUTOR 468
#define _STORE_ATTR 468 #define _STORE_ATTR 469
#define _STORE_ATTR_INSTANCE_VALUE 469 #define _STORE_ATTR_INSTANCE_VALUE 470
#define _STORE_ATTR_SLOT 470 #define _STORE_ATTR_SLOT 471
#define _STORE_ATTR_WITH_HINT 471 #define _STORE_ATTR_WITH_HINT 472
#define _STORE_DEREF STORE_DEREF #define _STORE_DEREF STORE_DEREF
#define _STORE_FAST 472 #define _STORE_FAST 473
#define _STORE_FAST_0 473 #define _STORE_FAST_0 474
#define _STORE_FAST_1 474 #define _STORE_FAST_1 475
#define _STORE_FAST_2 475 #define _STORE_FAST_2 476
#define _STORE_FAST_3 476 #define _STORE_FAST_3 477
#define _STORE_FAST_4 477 #define _STORE_FAST_4 478
#define _STORE_FAST_5 478 #define _STORE_FAST_5 479
#define _STORE_FAST_6 479 #define _STORE_FAST_6 480
#define _STORE_FAST_7 480 #define _STORE_FAST_7 481
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _STORE_GLOBAL STORE_GLOBAL #define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME #define _STORE_NAME STORE_NAME
#define _STORE_SLICE 481 #define _STORE_SLICE 482
#define _STORE_SUBSCR 482 #define _STORE_SUBSCR 483
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
#define _SWAP SWAP #define _SWAP SWAP
#define _TIER2_RESUME_CHECK 483 #define _TIER2_RESUME_CHECK 484
#define _TO_BOOL 484 #define _TO_BOOL 485
#define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT #define _TO_BOOL_INT TO_BOOL_INT
#define _TO_BOOL_LIST TO_BOOL_LIST #define _TO_BOOL_LIST TO_BOOL_LIST
@ -303,13 +304,13 @@ extern "C" {
#define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT #define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX #define _UNPACK_EX UNPACK_EX
#define _UNPACK_SEQUENCE 485 #define _UNPACK_SEQUENCE 486
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
#define _WITH_EXCEPT_START WITH_EXCEPT_START #define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE #define _YIELD_VALUE YIELD_VALUE
#define MAX_UOP_ID 485 #define MAX_UOP_ID 486
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -213,6 +213,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG, [_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG,
[_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG, [_PY_FRAME_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
[_CHECK_FUNCTION_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_CHECK_FUNCTION_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
[_CHECK_FUNCTION_VERSION_INLINE] = HAS_EXIT_FLAG,
[_CHECK_METHOD_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_CHECK_METHOD_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
[_EXPAND_METHOD] = HAS_ARG_FLAG, [_EXPAND_METHOD] = HAS_ARG_FLAG,
[_CHECK_IS_NOT_PY_CALLABLE] = HAS_ARG_FLAG | HAS_EXIT_FLAG, [_CHECK_IS_NOT_PY_CALLABLE] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
@ -353,6 +354,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_CHECK_FUNCTION] = "_CHECK_FUNCTION", [_CHECK_FUNCTION] = "_CHECK_FUNCTION",
[_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS", [_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
[_CHECK_FUNCTION_VERSION] = "_CHECK_FUNCTION_VERSION", [_CHECK_FUNCTION_VERSION] = "_CHECK_FUNCTION_VERSION",
[_CHECK_FUNCTION_VERSION_INLINE] = "_CHECK_FUNCTION_VERSION_INLINE",
[_CHECK_FUNCTION_VERSION_KW] = "_CHECK_FUNCTION_VERSION_KW", [_CHECK_FUNCTION_VERSION_KW] = "_CHECK_FUNCTION_VERSION_KW",
[_CHECK_IS_NOT_PY_CALLABLE] = "_CHECK_IS_NOT_PY_CALLABLE", [_CHECK_IS_NOT_PY_CALLABLE] = "_CHECK_IS_NOT_PY_CALLABLE",
[_CHECK_IS_NOT_PY_CALLABLE_KW] = "_CHECK_IS_NOT_PY_CALLABLE_KW", [_CHECK_IS_NOT_PY_CALLABLE_KW] = "_CHECK_IS_NOT_PY_CALLABLE_KW",
@ -965,6 +967,8 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2 + oparg; return 2 + oparg;
case _CHECK_FUNCTION_VERSION: case _CHECK_FUNCTION_VERSION:
return 0; return 0;
case _CHECK_FUNCTION_VERSION_INLINE:
return 0;
case _CHECK_METHOD_VERSION: case _CHECK_METHOD_VERSION:
return 0; return 0;
case _EXPAND_METHOD: case _EXPAND_METHOD:

View file

@ -1486,6 +1486,26 @@ class TestUopsOptimization(unittest.TestCase):
fn(A()) fn(A())
def test_func_guards_removed_or_reduced(self):
def testfunc(n):
for i in range(n):
# Only works on functions promoted to constants
global_identity(i)
opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_PUSH_FRAME", uops)
# Strength reduced version
self.assertIn("_CHECK_FUNCTION_VERSION_INLINE", uops)
self.assertNotIn("_CHECK_FUNCTION_VERSION", uops)
# Removed guard
self.assertNotIn("_CHECK_FUNCTION_EXACT_ARGS", uops)
def test_jit_error_pops(self): def test_jit_error_pops(self):
""" """
Tests that the correct number of pops are inserted into the Tests that the correct number of pops are inserted into the
@ -1495,5 +1515,9 @@ class TestUopsOptimization(unittest.TestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
{item for item in items} {item for item in items}
def global_identity(x):
return x
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View file

@ -661,7 +661,7 @@ dummy_func(
assert(next_instr->op.code == STORE_FAST); assert(next_instr->op.code == STORE_FAST);
next_oparg = next_instr->op.arg; next_oparg = next_instr->op.arg;
#else #else
next_oparg = CURRENT_OPERAND(); next_oparg = CURRENT_OPERAND0();
#endif #endif
_PyStackRef *target_local = &GETLOCAL(next_oparg); _PyStackRef *target_local = &GETLOCAL(next_oparg);
DEOPT_IF(!PyStackRef_Is(*target_local, left)); DEOPT_IF(!PyStackRef_Is(*target_local, left));
@ -3463,6 +3463,12 @@ dummy_func(
EXIT_IF(func->func_version != func_version); EXIT_IF(func->func_version != func_version);
} }
tier2 op(_CHECK_FUNCTION_VERSION_INLINE, (func_version/2, callable_o/4 --)) {
assert(PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o;
EXIT_IF(func->func_version != func_version);
}
macro(CALL_PY_GENERAL) = macro(CALL_PY_GENERAL) =
unused/1 + // Skip over the counter unused/1 + // Skip over the counter
_CHECK_PEP_523 + _CHECK_PEP_523 +

View file

@ -413,7 +413,8 @@ do { \
#define CURRENT_OPARG() (next_uop[-1].oparg) #define CURRENT_OPARG() (next_uop[-1].oparg)
#define CURRENT_OPERAND() (next_uop[-1].operand) #define CURRENT_OPERAND0() (next_uop[-1].operand0)
#define CURRENT_OPERAND1() (next_uop[-1].operand1)
#define JUMP_TO_JUMP_TARGET() goto jump_to_jump_target #define JUMP_TO_JUMP_TARGET() goto jump_to_jump_target
#define JUMP_TO_ERROR() goto jump_to_error_target #define JUMP_TO_ERROR() goto jump_to_error_target

View file

@ -831,7 +831,7 @@
assert(next_instr->op.code == STORE_FAST); assert(next_instr->op.code == STORE_FAST);
next_oparg = next_instr->op.arg; next_oparg = next_instr->op.arg;
#else #else
next_oparg = CURRENT_OPERAND(); next_oparg = CURRENT_OPERAND0();
#endif #endif
_PyStackRef *target_local = &GETLOCAL(next_oparg); _PyStackRef *target_local = &GETLOCAL(next_oparg);
if (!PyStackRef_Is(*target_local, left)) { if (!PyStackRef_Is(*target_local, left)) {
@ -1864,7 +1864,7 @@
} }
case _GUARD_GLOBALS_VERSION: { case _GUARD_GLOBALS_VERSION: {
uint16_t version = (uint16_t)CURRENT_OPERAND(); uint16_t version = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictObject *dict = (PyDictObject *)GLOBALS();
if (!PyDict_CheckExact(dict)) { if (!PyDict_CheckExact(dict)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -1880,7 +1880,7 @@
case _GUARD_GLOBALS_VERSION_PUSH_KEYS: { case _GUARD_GLOBALS_VERSION_PUSH_KEYS: {
PyDictKeysObject *globals_keys; PyDictKeysObject *globals_keys;
uint16_t version = (uint16_t)CURRENT_OPERAND(); uint16_t version = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictObject *dict = (PyDictObject *)GLOBALS();
if (!PyDict_CheckExact(dict)) { if (!PyDict_CheckExact(dict)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -1900,7 +1900,7 @@
case _GUARD_BUILTINS_VERSION_PUSH_KEYS: { case _GUARD_BUILTINS_VERSION_PUSH_KEYS: {
PyDictKeysObject *builtins_keys; PyDictKeysObject *builtins_keys;
uint16_t version = (uint16_t)CURRENT_OPERAND(); uint16_t version = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)BUILTINS(); PyDictObject *dict = (PyDictObject *)BUILTINS();
if (!PyDict_CheckExact(dict)) { if (!PyDict_CheckExact(dict)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -1924,7 +1924,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits; globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
PyObject *res_o = entries[index].me_value; PyObject *res_o = entries[index].me_value;
stack_pointer += -1; stack_pointer += -1;
@ -1950,7 +1950,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits; builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
PyObject *res_o = entries[index].me_value; PyObject *res_o = entries[index].me_value;
stack_pointer += -1; stack_pointer += -1;
@ -2523,7 +2523,7 @@
case _GUARD_TYPE_VERSION: { case _GUARD_TYPE_VERSION: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint32_t type_version = (uint32_t)CURRENT_OPERAND(); uint32_t type_version = (uint32_t)CURRENT_OPERAND0();
PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner)); PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
assert(type_version != 0); assert(type_version != 0);
if (tp->tp_version_tag != type_version) { if (tp->tp_version_tag != type_version) {
@ -2552,7 +2552,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
(void)null; (void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t offset = (uint16_t)CURRENT_OPERAND(); uint16_t offset = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset); PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
PyObject *attr_o = *value_ptr; PyObject *attr_o = *value_ptr;
@ -2575,7 +2575,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
(void)null; (void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t offset = (uint16_t)CURRENT_OPERAND(); uint16_t offset = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset); PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
PyObject *attr_o = *value_ptr; PyObject *attr_o = *value_ptr;
@ -2600,7 +2600,7 @@
case _CHECK_ATTR_MODULE: { case _CHECK_ATTR_MODULE: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint32_t dict_version = (uint32_t)CURRENT_OPERAND(); uint32_t dict_version = (uint32_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
if (!PyModule_CheckExact(owner_o)) { if (!PyModule_CheckExact(owner_o)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -2621,7 +2621,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict; PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
@ -2664,7 +2664,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t hint = (uint16_t)CURRENT_OPERAND(); uint16_t hint = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
PyObject *attr_o; PyObject *attr_o;
PyDictObject *dict = _PyObject_GetManagedDict(owner_o); PyDictObject *dict = _PyObject_GetManagedDict(owner_o);
@ -2705,7 +2705,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
(void)null; (void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
char *addr = (char *)owner_o + index; char *addr = (char *)owner_o + index;
PyObject *attr_o = *(PyObject **)addr; PyObject *attr_o = *(PyObject **)addr;
@ -2727,7 +2727,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
(void)null; (void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
char *addr = (char *)owner_o + index; char *addr = (char *)owner_o + index;
PyObject *attr_o = *(PyObject **)addr; PyObject *attr_o = *(PyObject **)addr;
@ -2751,7 +2751,7 @@
case _CHECK_ATTR_CLASS: { case _CHECK_ATTR_CLASS: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint32_t type_version = (uint32_t)CURRENT_OPERAND(); uint32_t type_version = (uint32_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
if (!PyType_Check(owner_o)) { if (!PyType_Check(owner_o)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -2771,7 +2771,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
(void)null; (void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr); attr = PyStackRef_FromPyObjectNew(descr);
@ -2787,7 +2787,7 @@
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
(void)null; (void)null;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
attr = PyStackRef_FromPyObjectNew(descr); attr = PyStackRef_FromPyObjectNew(descr);
@ -2807,7 +2807,7 @@
_PyInterpreterFrame *new_frame; _PyInterpreterFrame *new_frame;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *fget = (PyObject *)CURRENT_OPERAND(); PyObject *fget = (PyObject *)CURRENT_OPERAND0();
assert((oparg & 1) == 0); assert((oparg & 1) == 0);
assert(Py_IS_TYPE(fget, &PyFunction_Type)); assert(Py_IS_TYPE(fget, &PyFunction_Type));
PyFunctionObject *f = (PyFunctionObject *)fget; PyFunctionObject *f = (PyFunctionObject *)fget;
@ -2859,7 +2859,7 @@
_PyStackRef value; _PyStackRef value;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
value = stack_pointer[-2]; value = stack_pointer[-2];
uint16_t offset = (uint16_t)CURRENT_OPERAND(); uint16_t offset = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
STAT_INC(STORE_ATTR, hit); STAT_INC(STORE_ATTR, hit);
assert(_PyObject_GetManagedDict(owner_o) == NULL); assert(_PyObject_GetManagedDict(owner_o) == NULL);
@ -2886,7 +2886,7 @@
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
value = stack_pointer[-2]; value = stack_pointer[-2];
uint16_t hint = (uint16_t)CURRENT_OPERAND(); uint16_t hint = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT); assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictObject *dict = _PyObject_GetManagedDict(owner_o); PyDictObject *dict = _PyObject_GetManagedDict(owner_o);
@ -2937,7 +2937,7 @@
_PyStackRef value; _PyStackRef value;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
value = stack_pointer[-2]; value = stack_pointer[-2];
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
char *addr = (char *)owner_o + index; char *addr = (char *)owner_o + index;
STAT_INC(STORE_ATTR, hit); STAT_INC(STORE_ATTR, hit);
@ -3780,7 +3780,7 @@
case _GUARD_KEYS_VERSION: { case _GUARD_KEYS_VERSION: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint32_t keys_version = (uint32_t)CURRENT_OPERAND(); uint32_t keys_version = (uint32_t)CURRENT_OPERAND0();
PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner)); PyTypeObject *owner_cls = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner));
PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls; PyHeapTypeObject *owner_heap_type = (PyHeapTypeObject *)owner_cls;
if (owner_heap_type->ht_cached_keys->dk_version != keys_version) { if (owner_heap_type->ht_cached_keys->dk_version != keys_version) {
@ -3796,7 +3796,7 @@
_PyStackRef self = PyStackRef_NULL; _PyStackRef self = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert(oparg & 1); assert(oparg & 1);
/* Cached method object */ /* Cached method object */
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
@ -3817,7 +3817,7 @@
_PyStackRef self = PyStackRef_NULL; _PyStackRef self = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert(oparg & 1); assert(oparg & 1);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
@ -3837,7 +3837,7 @@
_PyStackRef attr; _PyStackRef attr;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert((oparg & 1) == 0); assert((oparg & 1) == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3852,7 +3852,7 @@
_PyStackRef attr; _PyStackRef attr;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert((oparg & 1) == 0); assert((oparg & 1) == 0);
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0); assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
@ -3866,7 +3866,7 @@
case _CHECK_ATTR_METHOD_LAZY_DICT: { case _CHECK_ATTR_METHOD_LAZY_DICT: {
_PyStackRef owner; _PyStackRef owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t dictoffset = (uint16_t)CURRENT_OPERAND(); uint16_t dictoffset = (uint16_t)CURRENT_OPERAND0();
char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset; char *ptr = ((char *)PyStackRef_AsPyObjectBorrow(owner)) + MANAGED_DICT_OFFSET + dictoffset;
PyObject *dict = *(PyObject **)ptr; PyObject *dict = *(PyObject **)ptr;
/* This object has a __dict__, just not yet created */ /* This object has a __dict__, just not yet created */
@ -3883,7 +3883,7 @@
_PyStackRef self = PyStackRef_NULL; _PyStackRef self = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)CURRENT_OPERAND(); PyObject *descr = (PyObject *)CURRENT_OPERAND0();
assert(oparg & 1); assert(oparg & 1);
STAT_INC(LOAD_ATTR, hit); STAT_INC(LOAD_ATTR, hit);
assert(descr != NULL); assert(descr != NULL);
@ -3967,7 +3967,7 @@
_PyStackRef *callable; _PyStackRef *callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
callable = &stack_pointer[-2 - oparg]; callable = &stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
if (!PyFunction_Check(callable_o)) { if (!PyFunction_Check(callable_o)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -3981,13 +3981,25 @@
break; break;
} }
case _CHECK_FUNCTION_VERSION_INLINE: {
uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
PyObject *callable_o = (PyObject *)CURRENT_OPERAND1();
assert(PyFunction_Check(callable_o));
PyFunctionObject *func = (PyFunctionObject *)callable_o;
if (func->func_version != func_version) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
break;
}
case _CHECK_METHOD_VERSION: { case _CHECK_METHOD_VERSION: {
_PyStackRef *null; _PyStackRef *null;
_PyStackRef *callable; _PyStackRef *callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
null = &stack_pointer[-1 - oparg]; null = &stack_pointer[-1 - oparg];
callable = &stack_pointer[-2 - oparg]; callable = &stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
if (Py_TYPE(callable_o) != &PyMethod_Type) { if (Py_TYPE(callable_o) != &PyMethod_Type) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -4443,7 +4455,7 @@
callable = &stack_pointer[-2 - oparg]; callable = &stack_pointer[-2 - oparg];
init = &stack_pointer[-2 - oparg]; init = &stack_pointer[-2 - oparg];
self = &stack_pointer[-1 - oparg]; self = &stack_pointer[-1 - oparg];
uint32_t type_version = (uint32_t)CURRENT_OPERAND(); uint32_t type_version = (uint32_t)CURRENT_OPERAND0();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
if (!PyStackRef_IsNull(null[0])) { if (!PyStackRef_IsNull(null[0])) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -5201,7 +5213,7 @@
_PyStackRef *callable; _PyStackRef *callable;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
callable = &stack_pointer[-3 - oparg]; callable = &stack_pointer[-3 - oparg];
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
if (!PyFunction_Check(callable_o)) { if (!PyFunction_Check(callable_o)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -5221,7 +5233,7 @@
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
null = &stack_pointer[-2 - oparg]; null = &stack_pointer[-2 - oparg];
callable = &stack_pointer[-3 - oparg]; callable = &stack_pointer[-3 - oparg];
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]); PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
if (Py_TYPE(callable_o) != &PyMethod_Type) { if (Py_TYPE(callable_o) != &PyMethod_Type) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -5659,13 +5671,13 @@
} }
case _SET_IP: { case _SET_IP: {
PyObject *instr_ptr = (PyObject *)CURRENT_OPERAND(); PyObject *instr_ptr = (PyObject *)CURRENT_OPERAND0();
frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr; frame->instr_ptr = (_Py_CODEUNIT *)instr_ptr;
break; break;
} }
case _CHECK_STACK_SPACE_OPERAND: { case _CHECK_STACK_SPACE_OPERAND: {
uint32_t framesize = (uint32_t)CURRENT_OPERAND(); uint32_t framesize = (uint32_t)CURRENT_OPERAND0();
assert(framesize <= INT_MAX); assert(framesize <= INT_MAX);
if (!_PyThreadState_HasStackSpace(tstate, framesize)) { if (!_PyThreadState_HasStackSpace(tstate, framesize)) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
@ -5690,7 +5702,7 @@
} }
case _EXIT_TRACE: { case _EXIT_TRACE: {
PyObject *exit_p = (PyObject *)CURRENT_OPERAND(); PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
_PyExitData *exit = (_PyExitData *)exit_p; _PyExitData *exit = (_PyExitData *)exit_p;
PyCodeObject *code = _PyFrame_GetCode(frame); PyCodeObject *code = _PyFrame_GetCode(frame);
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);
@ -5757,7 +5769,7 @@
case _LOAD_CONST_INLINE: { case _LOAD_CONST_INLINE: {
_PyStackRef value; _PyStackRef value;
PyObject *ptr = (PyObject *)CURRENT_OPERAND(); PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
value = PyStackRef_FromPyObjectNew(ptr); value = PyStackRef_FromPyObjectNew(ptr);
stack_pointer[0] = value; stack_pointer[0] = value;
stack_pointer += 1; stack_pointer += 1;
@ -5767,7 +5779,7 @@
case _LOAD_CONST_INLINE_BORROW: { case _LOAD_CONST_INLINE_BORROW: {
_PyStackRef value; _PyStackRef value;
PyObject *ptr = (PyObject *)CURRENT_OPERAND(); PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
value = PyStackRef_FromPyObjectImmortal(ptr); value = PyStackRef_FromPyObjectImmortal(ptr);
stack_pointer[0] = value; stack_pointer[0] = value;
stack_pointer += 1; stack_pointer += 1;
@ -5779,7 +5791,7 @@
_PyStackRef pop; _PyStackRef pop;
_PyStackRef value; _PyStackRef value;
pop = stack_pointer[-1]; pop = stack_pointer[-1];
PyObject *ptr = (PyObject *)CURRENT_OPERAND(); PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
PyStackRef_CLOSE(pop); PyStackRef_CLOSE(pop);
value = PyStackRef_FromPyObjectImmortal(ptr); value = PyStackRef_FromPyObjectImmortal(ptr);
stack_pointer[-1] = value; stack_pointer[-1] = value;
@ -5789,7 +5801,7 @@
case _LOAD_CONST_INLINE_WITH_NULL: { case _LOAD_CONST_INLINE_WITH_NULL: {
_PyStackRef value; _PyStackRef value;
_PyStackRef null; _PyStackRef null;
PyObject *ptr = (PyObject *)CURRENT_OPERAND(); PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
value = PyStackRef_FromPyObjectNew(ptr); value = PyStackRef_FromPyObjectNew(ptr);
null = PyStackRef_NULL; null = PyStackRef_NULL;
stack_pointer[0] = value; stack_pointer[0] = value;
@ -5802,7 +5814,7 @@
case _LOAD_CONST_INLINE_BORROW_WITH_NULL: { case _LOAD_CONST_INLINE_BORROW_WITH_NULL: {
_PyStackRef value; _PyStackRef value;
_PyStackRef null; _PyStackRef null;
PyObject *ptr = (PyObject *)CURRENT_OPERAND(); PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
value = PyStackRef_FromPyObjectImmortal(ptr); value = PyStackRef_FromPyObjectImmortal(ptr);
null = PyStackRef_NULL; null = PyStackRef_NULL;
stack_pointer[0] = value; stack_pointer[0] = value;
@ -5813,7 +5825,7 @@
} }
case _CHECK_FUNCTION: { case _CHECK_FUNCTION: {
uint32_t func_version = (uint32_t)CURRENT_OPERAND(); uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
assert(PyStackRef_FunctionCheck(frame->f_funcobj)); assert(PyStackRef_FunctionCheck(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj); PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
if (func->func_version != func_version) { if (func->func_version != func_version) {
@ -5827,7 +5839,7 @@
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)GLOBALS(); PyDictObject *dict = (PyDictObject *)GLOBALS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
PyObject *res_o = entries[index].me_value; PyObject *res_o = entries[index].me_value;
@ -5849,7 +5861,7 @@
_PyStackRef res; _PyStackRef res;
_PyStackRef null = PyStackRef_NULL; _PyStackRef null = PyStackRef_NULL;
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
uint16_t index = (uint16_t)CURRENT_OPERAND(); uint16_t index = (uint16_t)CURRENT_OPERAND0();
PyDictObject *dict = (PyDictObject *)BUILTINS(); PyDictObject *dict = (PyDictObject *)BUILTINS();
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
PyObject *res_o = entries[index].me_value; PyObject *res_o = entries[index].me_value;
@ -5878,7 +5890,7 @@
} }
case _DYNAMIC_EXIT: { case _DYNAMIC_EXIT: {
PyObject *exit_p = (PyObject *)CURRENT_OPERAND(); PyObject *exit_p = (PyObject *)CURRENT_OPERAND0();
tstate->previous_executor = (PyObject *)current_executor; tstate->previous_executor = (PyObject *)current_executor;
_PyExitData *exit = (_PyExitData *)exit_p; _PyExitData *exit = (_PyExitData *)exit_p;
_Py_CODEUNIT *target = frame->instr_ptr; _Py_CODEUNIT *target = frame->instr_ptr;
@ -5925,7 +5937,7 @@
} }
case _START_EXECUTOR: { case _START_EXECUTOR: {
PyObject *executor = (PyObject *)CURRENT_OPERAND(); PyObject *executor = (PyObject *)CURRENT_OPERAND0();
Py_DECREF(tstate->previous_executor); Py_DECREF(tstate->previous_executor);
tstate->previous_executor = NULL; tstate->previous_executor = NULL;
#ifndef _Py_JIT #ifndef _Py_JIT
@ -5951,7 +5963,7 @@
} }
case _CHECK_VALIDITY_AND_SET_IP: { case _CHECK_VALIDITY_AND_SET_IP: {
PyObject *instr_ptr = (PyObject *)CURRENT_OPERAND(); PyObject *instr_ptr = (PyObject *)CURRENT_OPERAND0();
if (!current_executor->vm_data.valid) { if (!current_executor->vm_data.valid) {
UOP_STAT_INC(uopcode, miss); UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET(); JUMP_TO_JUMP_TARGET();
@ -5967,7 +5979,7 @@
case _ERROR_POP_N: { case _ERROR_POP_N: {
oparg = CURRENT_OPARG(); oparg = CURRENT_OPARG();
uint32_t target = (uint32_t)CURRENT_OPERAND(); uint32_t target = (uint32_t)CURRENT_OPERAND0();
stack_pointer += -oparg; stack_pointer += -oparg;
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
_PyFrame_SetStackPointer(frame, stack_pointer); _PyFrame_SetStackPointer(frame, stack_pointer);

View file

@ -192,7 +192,7 @@
assert(next_instr->op.code == STORE_FAST); assert(next_instr->op.code == STORE_FAST);
next_oparg = next_instr->op.arg; next_oparg = next_instr->op.arg;
#else #else
next_oparg = CURRENT_OPERAND(); next_oparg = CURRENT_OPERAND0();
#endif #endif
_PyStackRef *target_local = &GETLOCAL(next_oparg); _PyStackRef *target_local = &GETLOCAL(next_oparg);
DEOPT_IF(!PyStackRef_Is(*target_local, left), BINARY_OP); DEOPT_IF(!PyStackRef_Is(*target_local, left), BINARY_OP);

View file

@ -288,13 +288,13 @@ _PyUOpPrint(const _PyUOpInstruction *uop)
printf(" (%d, target=%d, operand=%#" PRIx64, printf(" (%d, target=%d, operand=%#" PRIx64,
uop->oparg, uop->oparg,
uop->target, uop->target,
(uint64_t)uop->operand); (uint64_t)uop->operand0);
break; break;
case UOP_FORMAT_JUMP: case UOP_FORMAT_JUMP:
printf(" (%d, jump_target=%d, operand=%#" PRIx64, printf(" (%d, jump_target=%d, operand=%#" PRIx64,
uop->oparg, uop->oparg,
uop->jump_target, uop->jump_target,
(uint64_t)uop->operand); (uint64_t)uop->operand0);
break; break;
default: default:
printf(" (%d, Unknown format)", uop->oparg); printf(" (%d, Unknown format)", uop->oparg);
@ -340,7 +340,7 @@ uop_item(_PyExecutorObject *self, Py_ssize_t index)
Py_DECREF(oname); Py_DECREF(oname);
return NULL; return NULL;
} }
PyObject *operand = PyLong_FromUnsignedLongLong(self->trace[index].operand); PyObject *operand = PyLong_FromUnsignedLongLong(self->trace[index].operand0);
if (operand == NULL) { if (operand == NULL) {
Py_DECREF(target); Py_DECREF(target);
Py_DECREF(oparg); Py_DECREF(oparg);
@ -463,7 +463,7 @@ add_to_trace(
trace[trace_length].format = UOP_FORMAT_TARGET; trace[trace_length].format = UOP_FORMAT_TARGET;
trace[trace_length].target = target; trace[trace_length].target = target;
trace[trace_length].oparg = oparg; trace[trace_length].oparg = oparg;
trace[trace_length].operand = operand; trace[trace_length].operand0 = operand;
return trace_length + 1; return trace_length + 1;
} }
@ -970,7 +970,7 @@ static void make_exit(_PyUOpInstruction *inst, int opcode, int target)
{ {
inst->opcode = opcode; inst->opcode = opcode;
inst->oparg = 0; inst->oparg = 0;
inst->operand = 0; inst->operand0 = 0;
inst->format = UOP_FORMAT_TARGET; inst->format = UOP_FORMAT_TARGET;
inst->target = target; inst->target = target;
} }
@ -1033,7 +1033,7 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length)
current_error_target = target; current_error_target = target;
make_exit(&buffer[next_spare], _ERROR_POP_N, 0); make_exit(&buffer[next_spare], _ERROR_POP_N, 0);
buffer[next_spare].oparg = popped; buffer[next_spare].oparg = popped;
buffer[next_spare].operand = target; buffer[next_spare].operand0 = target;
next_spare++; next_spare++;
} }
buffer[i].error_target = current_error; buffer[i].error_target = current_error;
@ -1150,7 +1150,7 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil
int next_exit = exit_count-1; int next_exit = exit_count-1;
_PyUOpInstruction *dest = (_PyUOpInstruction *)&executor->trace[length]; _PyUOpInstruction *dest = (_PyUOpInstruction *)&executor->trace[length];
assert(buffer[0].opcode == _START_EXECUTOR); assert(buffer[0].opcode == _START_EXECUTOR);
buffer[0].operand = (uint64_t)executor; buffer[0].operand0 = (uint64_t)executor;
for (int i = length-1; i >= 0; i--) { for (int i = length-1; i >= 0; i--) {
int opcode = buffer[i].opcode; int opcode = buffer[i].opcode;
dest--; dest--;
@ -1159,13 +1159,13 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil
if (opcode == _EXIT_TRACE) { if (opcode == _EXIT_TRACE) {
_PyExitData *exit = &executor->exits[next_exit]; _PyExitData *exit = &executor->exits[next_exit];
exit->target = buffer[i].target; exit->target = buffer[i].target;
dest->operand = (uint64_t)exit; dest->operand0 = (uint64_t)exit;
next_exit--; next_exit--;
} }
if (opcode == _DYNAMIC_EXIT) { if (opcode == _DYNAMIC_EXIT) {
_PyExitData *exit = &executor->exits[next_exit]; _PyExitData *exit = &executor->exits[next_exit];
exit->target = 0; exit->target = 0;
dest->operand = (uint64_t)exit; dest->operand0 = (uint64_t)exit;
next_exit--; next_exit--;
} }
} }
@ -1312,7 +1312,7 @@ _PyOptimizer_NewUOpOptimizer(void)
static void static void
counter_dealloc(_PyExecutorObject *self) { counter_dealloc(_PyExecutorObject *self) {
/* The optimizer is the operand of the second uop. */ /* The optimizer is the operand of the second uop. */
PyObject *opt = (PyObject *)self->trace[1].operand; PyObject *opt = (PyObject *)self->trace[1].operand0;
Py_DECREF(opt); Py_DECREF(opt);
uop_dealloc(self); uop_dealloc(self);
} }
@ -1352,7 +1352,7 @@ counter_optimize(
_Py_CODEUNIT *target = instr + 1 + _PyOpcode_Caches[JUMP_BACKWARD] - oparg; _Py_CODEUNIT *target = instr + 1 + _PyOpcode_Caches[JUMP_BACKWARD] - oparg;
_PyUOpInstruction buffer[4] = { _PyUOpInstruction buffer[4] = {
{ .opcode = _START_EXECUTOR, .jump_target = 3, .format=UOP_FORMAT_JUMP }, { .opcode = _START_EXECUTOR, .jump_target = 3, .format=UOP_FORMAT_JUMP },
{ .opcode = _LOAD_CONST_INLINE, .operand = (uintptr_t)self }, { .opcode = _LOAD_CONST_INLINE, .operand0 = (uintptr_t)self },
{ .opcode = _INTERNAL_INCREMENT_OPT_COUNTER }, { .opcode = _INTERNAL_INCREMENT_OPT_COUNTER },
{ .opcode = _EXIT_TRACE, .target = (uint32_t)(target - _PyCode_CODE(code)), .format=UOP_FORMAT_TARGET } { .opcode = _EXIT_TRACE, .target = (uint32_t)(target - _PyCode_CODE(code)), .format=UOP_FORMAT_TARGET }
}; };

View file

@ -100,11 +100,11 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
PyDictObject *dict = (PyDictObject *)obj; PyDictObject *dict = (PyDictObject *)obj;
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
assert(inst->operand <= UINT16_MAX); assert(inst->operand0 <= UINT16_MAX);
if ((int)inst->operand >= dict->ma_keys->dk_nentries) { if ((int)inst->operand0 >= dict->ma_keys->dk_nentries) {
return NULL; return NULL;
} }
PyObject *res = entries[inst->operand].me_value; PyObject *res = entries[inst->operand0].me_value;
if (res == NULL) { if (res == NULL) {
return NULL; return NULL;
} }
@ -114,7 +114,7 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
else { else {
inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE; inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE;
} }
inst->operand = (uint64_t)res; inst->operand0 = (uint64_t)res;
return res; return res;
} }
@ -125,7 +125,7 @@ incorrect_keys(_PyUOpInstruction *inst, PyObject *obj)
return 1; return 1;
} }
PyDictObject *dict = (PyDictObject *)obj; PyDictObject *dict = (PyDictObject *)obj;
if (dict->ma_keys->dk_version != inst->operand) { if (dict->ma_keys->dk_version != inst->operand0) {
return 1; return 1;
} }
return 0; return 0;
@ -215,7 +215,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
} }
else { else {
buffer[pc].opcode = _CHECK_FUNCTION; buffer[pc].opcode = _CHECK_FUNCTION;
buffer[pc].operand = function_version; buffer[pc].operand0 = function_version;
function_checked |= 1; function_checked |= 1;
} }
// We're no longer pushing the builtins keys; rewrite the // We're no longer pushing the builtins keys; rewrite the
@ -248,7 +248,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
} }
else { else {
buffer[pc].opcode = _CHECK_FUNCTION; buffer[pc].opcode = _CHECK_FUNCTION;
buffer[pc].operand = function_version; buffer[pc].operand0 = function_version;
function_checked |= 1; function_checked |= 1;
} }
if (opcode == _GUARD_GLOBALS_VERSION_PUSH_KEYS) { if (opcode == _GUARD_GLOBALS_VERSION_PUSH_KEYS) {
@ -273,7 +273,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
builtins_watched <<= 1; builtins_watched <<= 1;
globals_watched <<= 1; globals_watched <<= 1;
function_checked <<= 1; function_checked <<= 1;
uint64_t operand = buffer[pc].operand; uint64_t operand = buffer[pc].operand0;
if (operand == 0 || (operand & 1)) { if (operand == 0 || (operand & 1)) {
// It's either a code object or NULL, so bail // It's either a code object or NULL, so bail
return 1; return 1;
@ -301,7 +301,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
builtins_watched >>= 1; builtins_watched >>= 1;
globals_watched >>= 1; globals_watched >>= 1;
function_checked >>= 1; function_checked >>= 1;
uint64_t operand = buffer[pc].operand; uint64_t operand = buffer[pc].operand0;
if (operand == 0 || (operand & 1)) { if (operand == 0 || (operand & 1)) {
// It's either a code object or NULL, so bail // It's either a code object or NULL, so bail
return 1; return 1;
@ -317,7 +317,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
break; break;
} }
case _CHECK_FUNCTION_EXACT_ARGS: case _CHECK_FUNCTION_EXACT_ARGS:
prechecked_function_version = (uint32_t)buffer[pc].operand; prechecked_function_version = (uint32_t)buffer[pc].operand0;
break; break;
default: default:
if (is_terminator(inst)) { if (is_terminator(inst)) {
@ -343,7 +343,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
#define REPLACE_OP(INST, OP, ARG, OPERAND) \ #define REPLACE_OP(INST, OP, ARG, OPERAND) \
INST->opcode = OP; \ INST->opcode = OP; \
INST->oparg = ARG; \ INST->oparg = ARG; \
INST->operand = OPERAND; INST->operand0 = OPERAND;
/* Shortened forms for convenience, used in optimizer_bytecodes.c */ /* Shortened forms for convenience, used in optimizer_bytecodes.c */
#define sym_is_not_null _Py_uop_sym_is_not_null #define sym_is_not_null _Py_uop_sym_is_not_null
@ -409,7 +409,7 @@ get_code(_PyUOpInstruction *op)
{ {
assert(op->opcode == _PUSH_FRAME || op->opcode == _RETURN_VALUE || op->opcode == _RETURN_GENERATOR); assert(op->opcode == _PUSH_FRAME || op->opcode == _RETURN_VALUE || op->opcode == _RETURN_GENERATOR);
PyCodeObject *co = NULL; PyCodeObject *co = NULL;
uint64_t operand = op->operand; uint64_t operand = op->operand0;
if (operand == 0) { if (operand == 0) {
return NULL; return NULL;
} }
@ -429,7 +429,7 @@ static PyCodeObject *
get_code_with_logging(_PyUOpInstruction *op) get_code_with_logging(_PyUOpInstruction *op)
{ {
PyCodeObject *co = NULL; PyCodeObject *co = NULL;
uint64_t push_operand = op->operand; uint64_t push_operand = op->operand0;
if (push_operand & 1) { if (push_operand & 1) {
co = (PyCodeObject *)(push_operand & ~1); co = (PyCodeObject *)(push_operand & ~1);
DPRINTF(3, "code=%p ", co); DPRINTF(3, "code=%p ", co);
@ -534,7 +534,7 @@ optimize_uops(
assert(max_space <= INT_MAX); assert(max_space <= INT_MAX);
assert(max_space <= INT32_MAX); assert(max_space <= INT32_MAX);
first_valid_check_stack->opcode = _CHECK_STACK_SPACE_OPERAND; first_valid_check_stack->opcode = _CHECK_STACK_SPACE_OPERAND;
first_valid_check_stack->operand = max_space; first_valid_check_stack->operand0 = max_space;
} }
return trace_len; return trace_len;

View file

@ -346,7 +346,7 @@ dummy_func(void) {
res = sym_new_type(ctx, &PyUnicode_Type); res = sym_new_type(ctx, &PyUnicode_Type);
} }
// _STORE_FAST: // _STORE_FAST:
GETLOCAL(this_instr->operand) = res; GETLOCAL(this_instr->operand0) = res;
} }
op(_BINARY_SUBSCR_INIT_CALL, (container, sub -- new_frame: _Py_UOpsAbstractFrame *)) { op(_BINARY_SUBSCR_INIT_CALL, (container, sub -- new_frame: _Py_UOpsAbstractFrame *)) {
@ -589,8 +589,27 @@ dummy_func(void) {
self = sym_new_not_null(ctx); self = sym_new_not_null(ctx);
} }
op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
(void)self_or_null;
if (sym_is_const(callable) && sym_matches_type(callable, &PyFunction_Type)) {
assert(PyFunction_Check(sym_get_const(callable)));
REPLACE_OP(this_instr, _CHECK_FUNCTION_VERSION_INLINE, 0, func_version);
this_instr->operand1 = (uintptr_t)sym_get_const(callable);
}
sym_set_type(callable, &PyFunction_Type); sym_set_type(callable, &PyFunction_Type);
}
op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
assert(sym_matches_type(callable, &PyFunction_Type));
if (sym_is_const(callable)) {
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
PyFunctionObject *func = (PyFunctionObject *)sym_get_const(callable);
PyCodeObject *co = (PyCodeObject *)func->func_code;
if (co->co_argcount == oparg + !sym_is_null(self_or_null)) {
REPLACE_OP(this_instr, _NOP, 0 ,0);
}
}
}
(void)self_or_null; (void)self_or_null;
} }

View file

@ -525,7 +525,7 @@
res = sym_new_type(ctx, &PyUnicode_Type); res = sym_new_type(ctx, &PyUnicode_Type);
} }
// _STORE_FAST: // _STORE_FAST:
GETLOCAL(this_instr->operand) = res; GETLOCAL(this_instr->operand0) = res;
stack_pointer += -2; stack_pointer += -2;
assert(WITHIN_STACK_BOUNDS()); assert(WITHIN_STACK_BOUNDS());
break; break;
@ -888,7 +888,7 @@
case _GUARD_GLOBALS_VERSION_PUSH_KEYS: { case _GUARD_GLOBALS_VERSION_PUSH_KEYS: {
_Py_UopsSymbol *globals_keys; _Py_UopsSymbol *globals_keys;
uint16_t version = (uint16_t)this_instr->operand; uint16_t version = (uint16_t)this_instr->operand0;
globals_keys = sym_new_unknown(ctx); globals_keys = sym_new_unknown(ctx);
(void)version; (void)version;
stack_pointer[0] = globals_keys; stack_pointer[0] = globals_keys;
@ -899,7 +899,7 @@
case _GUARD_BUILTINS_VERSION_PUSH_KEYS: { case _GUARD_BUILTINS_VERSION_PUSH_KEYS: {
_Py_UopsSymbol *builtins_keys; _Py_UopsSymbol *builtins_keys;
uint16_t version = (uint16_t)this_instr->operand; uint16_t version = (uint16_t)this_instr->operand0;
builtins_keys = sym_new_unknown(ctx); builtins_keys = sym_new_unknown(ctx);
(void)version; (void)version;
stack_pointer[0] = builtins_keys; stack_pointer[0] = builtins_keys;
@ -1090,7 +1090,7 @@
case _GUARD_TYPE_VERSION: { case _GUARD_TYPE_VERSION: {
_Py_UopsSymbol *owner; _Py_UopsSymbol *owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint32_t type_version = (uint32_t)this_instr->operand; uint32_t type_version = (uint32_t)this_instr->operand0;
assert(type_version); assert(type_version);
if (sym_matches_type_version(owner, type_version)) { if (sym_matches_type_version(owner, type_version)) {
REPLACE_OP(this_instr, _NOP, 0, 0); REPLACE_OP(this_instr, _NOP, 0, 0);
@ -1122,7 +1122,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *null = NULL; _Py_UopsSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t offset = (uint16_t)this_instr->operand; uint16_t offset = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx); null = sym_new_null(ctx);
(void)offset; (void)offset;
@ -1137,7 +1137,7 @@
case _CHECK_ATTR_MODULE: { case _CHECK_ATTR_MODULE: {
_Py_UopsSymbol *owner; _Py_UopsSymbol *owner;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint32_t dict_version = (uint32_t)this_instr->operand; uint32_t dict_version = (uint32_t)this_instr->operand0;
(void)dict_version; (void)dict_version;
if (sym_is_const(owner)) { if (sym_is_const(owner)) {
PyObject *cnst = sym_get_const(owner); PyObject *cnst = sym_get_const(owner);
@ -1160,7 +1160,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *null = NULL; _Py_UopsSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)this_instr->operand; uint16_t index = (uint16_t)this_instr->operand0;
(void)index; (void)index;
null = sym_new_null(ctx); null = sym_new_null(ctx);
attr = NULL; attr = NULL;
@ -1202,7 +1202,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *null = NULL; _Py_UopsSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t hint = (uint16_t)this_instr->operand; uint16_t hint = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx); null = sym_new_null(ctx);
(void)hint; (void)hint;
@ -1219,7 +1219,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *null = NULL; _Py_UopsSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
uint16_t index = (uint16_t)this_instr->operand; uint16_t index = (uint16_t)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx); null = sym_new_null(ctx);
(void)index; (void)index;
@ -1240,7 +1240,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *null = NULL; _Py_UopsSymbol *null = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand; PyObject *descr = (PyObject *)this_instr->operand0;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
null = sym_new_null(ctx); null = sym_new_null(ctx);
(void)descr; (void)descr;
@ -1256,7 +1256,7 @@
_Py_UopsSymbol *owner; _Py_UopsSymbol *owner;
_Py_UOpsAbstractFrame *new_frame; _Py_UOpsAbstractFrame *new_frame;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *fget = (PyObject *)this_instr->operand; PyObject *fget = (PyObject *)this_instr->operand0;
(void)fget; (void)fget;
(void)owner; (void)owner;
new_frame = NULL; new_frame = NULL;
@ -1639,7 +1639,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *self = NULL; _Py_UopsSymbol *self = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand; PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr; (void)descr;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self = owner; self = owner;
@ -1655,7 +1655,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *self = NULL; _Py_UopsSymbol *self = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand; PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr; (void)descr;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self = owner; self = owner;
@ -1689,7 +1689,7 @@
_Py_UopsSymbol *attr; _Py_UopsSymbol *attr;
_Py_UopsSymbol *self = NULL; _Py_UopsSymbol *self = NULL;
owner = stack_pointer[-1]; owner = stack_pointer[-1];
PyObject *descr = (PyObject *)this_instr->operand; PyObject *descr = (PyObject *)this_instr->operand0;
(void)descr; (void)descr;
attr = sym_new_not_null(ctx); attr = sym_new_not_null(ctx);
self = owner; self = owner;
@ -1749,6 +1749,22 @@
} }
case _CHECK_FUNCTION_VERSION: { case _CHECK_FUNCTION_VERSION: {
_Py_UopsSymbol *self_or_null;
_Py_UopsSymbol *callable;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
uint32_t func_version = (uint32_t)this_instr->operand0;
(void)self_or_null;
if (sym_is_const(callable) && sym_matches_type(callable, &PyFunction_Type)) {
assert(PyFunction_Check(sym_get_const(callable)));
REPLACE_OP(this_instr, _CHECK_FUNCTION_VERSION_INLINE, 0, func_version);
this_instr->operand1 = (uintptr_t)sym_get_const(callable);
}
sym_set_type(callable, &PyFunction_Type);
break;
}
case _CHECK_FUNCTION_VERSION_INLINE: {
break; break;
} }
@ -1816,7 +1832,16 @@
_Py_UopsSymbol *callable; _Py_UopsSymbol *callable;
self_or_null = stack_pointer[-1 - oparg]; self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
sym_set_type(callable, &PyFunction_Type); assert(sym_matches_type(callable, &PyFunction_Type));
if (sym_is_const(callable)) {
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
PyFunctionObject *func = (PyFunctionObject *)sym_get_const(callable);
PyCodeObject *co = (PyCodeObject *)func->func_code;
if (co->co_argcount == oparg + !sym_is_null(self_or_null)) {
REPLACE_OP(this_instr, _NOP, 0 ,0);
}
}
}
(void)self_or_null; (void)self_or_null;
break; break;
} }
@ -1939,7 +1964,7 @@
null = stack_pointer[-1 - oparg]; null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg]; callable = stack_pointer[-2 - oparg];
args = &stack_pointer[-oparg]; args = &stack_pointer[-oparg];
uint32_t type_version = (uint32_t)this_instr->operand; uint32_t type_version = (uint32_t)this_instr->operand0;
(void)type_version; (void)type_version;
(void)callable; (void)callable;
(void)null; (void)null;
@ -2399,7 +2424,7 @@
} }
case _CHECK_STACK_SPACE_OPERAND: { case _CHECK_STACK_SPACE_OPERAND: {
uint32_t framesize = (uint32_t)this_instr->operand; uint32_t framesize = (uint32_t)this_instr->operand0;
(void)framesize; (void)framesize;
/* We should never see _CHECK_STACK_SPACE_OPERANDs. /* We should never see _CHECK_STACK_SPACE_OPERANDs.
* They are only created at the end of this pass. */ * They are only created at the end of this pass. */
@ -2412,7 +2437,7 @@
} }
case _EXIT_TRACE: { case _EXIT_TRACE: {
PyObject *exit_p = (PyObject *)this_instr->operand; PyObject *exit_p = (PyObject *)this_instr->operand0;
(void)exit_p; (void)exit_p;
ctx->done = true; ctx->done = true;
break; break;
@ -2424,7 +2449,7 @@
case _LOAD_CONST_INLINE: { case _LOAD_CONST_INLINE: {
_Py_UopsSymbol *value; _Py_UopsSymbol *value;
PyObject *ptr = (PyObject *)this_instr->operand; PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr); value = sym_new_const(ctx, ptr);
stack_pointer[0] = value; stack_pointer[0] = value;
stack_pointer += 1; stack_pointer += 1;
@ -2434,7 +2459,7 @@
case _LOAD_CONST_INLINE_BORROW: { case _LOAD_CONST_INLINE_BORROW: {
_Py_UopsSymbol *value; _Py_UopsSymbol *value;
PyObject *ptr = (PyObject *)this_instr->operand; PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr); value = sym_new_const(ctx, ptr);
stack_pointer[0] = value; stack_pointer[0] = value;
stack_pointer += 1; stack_pointer += 1;
@ -2452,7 +2477,7 @@
case _LOAD_CONST_INLINE_WITH_NULL: { case _LOAD_CONST_INLINE_WITH_NULL: {
_Py_UopsSymbol *value; _Py_UopsSymbol *value;
_Py_UopsSymbol *null; _Py_UopsSymbol *null;
PyObject *ptr = (PyObject *)this_instr->operand; PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr); value = sym_new_const(ctx, ptr);
null = sym_new_null(ctx); null = sym_new_null(ctx);
stack_pointer[0] = value; stack_pointer[0] = value;
@ -2465,7 +2490,7 @@
case _LOAD_CONST_INLINE_BORROW_WITH_NULL: { case _LOAD_CONST_INLINE_BORROW_WITH_NULL: {
_Py_UopsSymbol *value; _Py_UopsSymbol *value;
_Py_UopsSymbol *null; _Py_UopsSymbol *null;
PyObject *ptr = (PyObject *)this_instr->operand; PyObject *ptr = (PyObject *)this_instr->operand0;
value = sym_new_const(ctx, ptr); value = sym_new_const(ctx, ptr);
null = sym_new_null(ctx); null = sym_new_null(ctx);
stack_pointer[0] = value; stack_pointer[0] = value;

View file

@ -200,7 +200,7 @@ class Uop:
return "has tier 1 control flow" return "has tier 1 control flow"
if self.properties.needs_this: if self.properties.needs_this:
return "uses the 'this_instr' variable" return "uses the 'this_instr' variable"
if len([c for c in self.caches if c.name != "unused"]) > 1: if len([c for c in self.caches if c.name != "unused"]) > 2:
return "has unused cache entries" return "has unused cache entries"
if self.properties.error_with_pop and self.properties.error_without_pop: if self.properties.error_with_pop and self.properties.error_without_pop:
return "has both popping and not-popping errors" return "has both popping and not-popping errors"

View file

@ -143,7 +143,7 @@ def write_uop(
else: else:
type = f"uint{cache.size*16}_t " type = f"uint{cache.size*16}_t "
cast = f"uint{cache.size*16}_t" cast = f"uint{cache.size*16}_t"
out.emit(f"{type}{cache.name} = ({cast})this_instr->operand;\n") out.emit(f"{type}{cache.name} = ({cast})this_instr->operand0;\n")
if override: if override:
emitter = OptimizerEmitter(out) emitter = OptimizerEmitter(out)
# No reference management of inputs needed. # No reference management of inputs needed.

View file

@ -181,14 +181,14 @@ def write_uop(uop: Uop, emitter: Emitter, stack: Stack) -> Stack:
code_list, storage = Storage.for_uop(stack, uop) code_list, storage = Storage.for_uop(stack, uop)
for code in code_list: for code in code_list:
emitter.emit(code) emitter.emit(code)
for cache in uop.caches: for idx, cache in enumerate(uop.caches):
if cache.name != "unused": if cache.name != "unused":
if cache.size == 4: if cache.size == 4:
type = cast = "PyObject *" type = cast = "PyObject *"
else: else:
type = f"uint{cache.size*16}_t " type = f"uint{cache.size*16}_t "
cast = f"uint{cache.size*16}_t" cast = f"uint{cache.size*16}_t"
emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND();\n") emitter.emit(f"{type}{cache.name} = ({cast})CURRENT_OPERAND{idx}();\n")
storage = emitter.emit_tokens(uop, storage, None) storage = emitter.emit_tokens(uop, storage, None)
except StackError as ex: except StackError as ex:
raise analysis_error(ex.args[0], uop.body[0]) from None raise analysis_error(ex.args[0], uop.body[0]) from None

View file

@ -29,11 +29,16 @@ class HoleValue(enum.Enum):
GOT = enum.auto() GOT = enum.auto()
# The current uop's oparg (exposed as _JIT_OPARG): # The current uop's oparg (exposed as _JIT_OPARG):
OPARG = enum.auto() OPARG = enum.auto()
# The current uop's operand on 64-bit platforms (exposed as _JIT_OPERAND): # The current uop's operand0 on 64-bit platforms (exposed as _JIT_OPERAND0):
OPERAND = enum.auto() OPERAND0 = enum.auto()
# The current uop's operand on 32-bit platforms (exposed as _JIT_OPERAND_HI/LO): # The current uop's operand0 on 32-bit platforms (exposed as _JIT_OPERAND0_HI/LO):
OPERAND_HI = enum.auto() OPERAND0_HI = enum.auto()
OPERAND_LO = enum.auto() OPERAND0_LO = enum.auto()
# The current uop's operand1 on 64-bit platforms (exposed as _JIT_OPERAND1):
OPERAND1 = enum.auto()
# The current uop's operand1 on 32-bit platforms (exposed as _JIT_OPERAND1_HI/LO):
OPERAND1_HI = enum.auto()
OPERAND1_LO = enum.auto()
# The current uop's target (exposed as _JIT_TARGET): # The current uop's target (exposed as _JIT_TARGET):
TARGET = enum.auto() TARGET = enum.auto()
# The base address of the machine code for the jump target (exposed as _JIT_JUMP_TARGET): # The base address of the machine code for the jump target (exposed as _JIT_JUMP_TARGET):
@ -99,9 +104,12 @@ _HOLE_EXPRS = {
# These should all have been turned into DATA values by process_relocations: # These should all have been turned into DATA values by process_relocations:
# HoleValue.GOT: "", # HoleValue.GOT: "",
HoleValue.OPARG: "instruction->oparg", HoleValue.OPARG: "instruction->oparg",
HoleValue.OPERAND: "instruction->operand", HoleValue.OPERAND0: "instruction->operand0",
HoleValue.OPERAND_HI: "(instruction->operand >> 32)", HoleValue.OPERAND0_HI: "(instruction->operand0 >> 32)",
HoleValue.OPERAND_LO: "(instruction->operand & UINT32_MAX)", HoleValue.OPERAND0_LO: "(instruction->operand0 & UINT32_MAX)",
HoleValue.OPERAND1: "instruction->operand1",
HoleValue.OPERAND1_HI: "(instruction->operand1 >> 32)",
HoleValue.OPERAND1_LO: "(instruction->operand1 & UINT32_MAX)",
HoleValue.TARGET: "instruction->target", HoleValue.TARGET: "instruction->target",
HoleValue.JUMP_TARGET: "state->instruction_starts[instruction->jump_target]", HoleValue.JUMP_TARGET: "state->instruction_starts[instruction->jump_target]",
HoleValue.ERROR_TARGET: "state->instruction_starts[instruction->error_target]", HoleValue.ERROR_TARGET: "state->instruction_starts[instruction->error_target]",

View file

@ -26,8 +26,11 @@
#undef CURRENT_OPARG #undef CURRENT_OPARG
#define CURRENT_OPARG() (_oparg) #define CURRENT_OPARG() (_oparg)
#undef CURRENT_OPERAND #undef CURRENT_OPERAND0
#define CURRENT_OPERAND() (_operand) #define CURRENT_OPERAND0() (_operand0)
#undef CURRENT_OPERAND1
#define CURRENT_OPERAND1() (_operand1)
#undef DEOPT_IF #undef DEOPT_IF
#define DEOPT_IF(COND, INSTNAME) \ #define DEOPT_IF(COND, INSTNAME) \
@ -99,12 +102,17 @@ _JIT_ENTRY(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState
// Other stuff we need handy: // Other stuff we need handy:
PATCH_VALUE(uint16_t, _oparg, _JIT_OPARG) PATCH_VALUE(uint16_t, _oparg, _JIT_OPARG)
#if SIZEOF_VOID_P == 8 #if SIZEOF_VOID_P == 8
PATCH_VALUE(uint64_t, _operand, _JIT_OPERAND) PATCH_VALUE(uint64_t, _operand0, _JIT_OPERAND0)
PATCH_VALUE(uint64_t, _operand1, _JIT_OPERAND1)
#else #else
assert(SIZEOF_VOID_P == 4); assert(SIZEOF_VOID_P == 4);
PATCH_VALUE(uint32_t, _operand_hi, _JIT_OPERAND_HI) PATCH_VALUE(uint32_t, _operand0_hi, _JIT_OPERAND0_HI)
PATCH_VALUE(uint32_t, _operand_lo, _JIT_OPERAND_LO) PATCH_VALUE(uint32_t, _operand0_lo, _JIT_OPERAND0_LO)
uint64_t _operand = ((uint64_t)_operand_hi << 32) | _operand_lo; uint64_t _operand0 = ((uint64_t)_operand0_hi << 32) | _operand0_lo;
PATCH_VALUE(uint32_t, _operand1_hi, _JIT_OPERAND1_HI)
PATCH_VALUE(uint32_t, _operand1_lo, _JIT_OPERAND1_LO)
uint64_t _operand1 = ((uint64_t)_operand1_hi << 32) | _operand1_lo;
#endif #endif
PATCH_VALUE(uint32_t, _target, _JIT_TARGET) PATCH_VALUE(uint32_t, _target, _JIT_TARGET)