mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
GH-120024: Remove CHECK_EVAL_BREAKER
macro. (GH-122968)
* Factor some instructions into micro-ops to isolate CHECK_EVAL_BREAKER for escape analysis * Eliminate CHECK_EVAL_BREAKER macro
This commit is contained in:
parent
315a933a5b
commit
eec7bdaf01
16 changed files with 821 additions and 518 deletions
14
Include/internal/pycore_opcode_metadata.h
generated
14
Include/internal/pycore_opcode_metadata.h
generated
|
@ -469,6 +469,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
||||||
return 5;
|
return 5;
|
||||||
case YIELD_VALUE:
|
case YIELD_VALUE:
|
||||||
return 1;
|
return 1;
|
||||||
|
case _DO_CALL_FUNCTION_EX:
|
||||||
|
return 3 + (oparg & 1);
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -916,6 +918,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
|
||||||
return 6;
|
return 6;
|
||||||
case YIELD_VALUE:
|
case YIELD_VALUE:
|
||||||
return 1;
|
return 1;
|
||||||
|
case _DO_CALL_FUNCTION_EX:
|
||||||
|
return 1;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1089,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[264] = {
|
||||||
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
|
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG },
|
||||||
[INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
|
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
[INSTRUMENTED_LINE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG },
|
||||||
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
[INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
|
@ -1155,7 +1159,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[264] = {
|
||||||
[RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[RAISE_VARARGS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[RERAISE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[RESERVED] = { true, INSTR_FMT_IX, 0 },
|
[RESERVED] = { true, INSTR_FMT_IX, 0 },
|
||||||
[RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[RESUME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
[RESUME_CHECK] = { true, INSTR_FMT_IX, HAS_DEOPT_FLAG },
|
||||||
[RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
|
[RETURN_CONST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_CONST_FLAG },
|
||||||
[RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
[RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
@ -1198,6 +1202,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[264] = {
|
||||||
[UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
[UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||||
[WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[WITH_EXCEPT_START] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
[YIELD_VALUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ESCAPES_FLAG },
|
||||||
|
[_DO_CALL_FUNCTION_EX] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
[JUMP] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||||
[JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
[JUMP_NO_INTERRUPT] = { true, -1, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG },
|
[LOAD_CLOSURE] = { true, -1, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG },
|
||||||
|
@ -1613,13 +1618,13 @@ const char *_PyOpcode_OpName[264] = {
|
||||||
[UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
|
[UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE",
|
||||||
[WITH_EXCEPT_START] = "WITH_EXCEPT_START",
|
[WITH_EXCEPT_START] = "WITH_EXCEPT_START",
|
||||||
[YIELD_VALUE] = "YIELD_VALUE",
|
[YIELD_VALUE] = "YIELD_VALUE",
|
||||||
|
[_DO_CALL_FUNCTION_EX] = "_DO_CALL_FUNCTION_EX",
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const uint8_t _PyOpcode_Caches[256];
|
extern const uint8_t _PyOpcode_Caches[256];
|
||||||
#ifdef NEED_OPCODE_METADATA
|
#ifdef NEED_OPCODE_METADATA
|
||||||
const uint8_t _PyOpcode_Caches[256] = {
|
const uint8_t _PyOpcode_Caches[256] = {
|
||||||
[JUMP_BACKWARD] = 1,
|
|
||||||
[TO_BOOL] = 3,
|
[TO_BOOL] = 3,
|
||||||
[BINARY_SUBSCR] = 1,
|
[BINARY_SUBSCR] = 1,
|
||||||
[STORE_SUBSCR] = 1,
|
[STORE_SUBSCR] = 1,
|
||||||
|
@ -1631,6 +1636,7 @@ const uint8_t _PyOpcode_Caches[256] = {
|
||||||
[LOAD_ATTR] = 9,
|
[LOAD_ATTR] = 9,
|
||||||
[COMPARE_OP] = 1,
|
[COMPARE_OP] = 1,
|
||||||
[CONTAINS_OP] = 1,
|
[CONTAINS_OP] = 1,
|
||||||
|
[JUMP_BACKWARD] = 1,
|
||||||
[POP_JUMP_IF_TRUE] = 1,
|
[POP_JUMP_IF_TRUE] = 1,
|
||||||
[POP_JUMP_IF_FALSE] = 1,
|
[POP_JUMP_IF_FALSE] = 1,
|
||||||
[POP_JUMP_IF_NONE] = 1,
|
[POP_JUMP_IF_NONE] = 1,
|
||||||
|
@ -1854,12 +1860,12 @@ const uint8_t _PyOpcode_Deopt[256] = {
|
||||||
[UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
|
[UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
|
||||||
[WITH_EXCEPT_START] = WITH_EXCEPT_START,
|
[WITH_EXCEPT_START] = WITH_EXCEPT_START,
|
||||||
[YIELD_VALUE] = YIELD_VALUE,
|
[YIELD_VALUE] = YIELD_VALUE,
|
||||||
|
[_DO_CALL_FUNCTION_EX] = _DO_CALL_FUNCTION_EX,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NEED_OPCODE_METADATA
|
#endif // NEED_OPCODE_METADATA
|
||||||
|
|
||||||
#define EXTRA_CASES \
|
#define EXTRA_CASES \
|
||||||
case 116: \
|
|
||||||
case 117: \
|
case 117: \
|
||||||
case 118: \
|
case 118: \
|
||||||
case 119: \
|
case 119: \
|
||||||
|
|
252
Include/internal/pycore_uop_ids.h
generated
252
Include/internal/pycore_uop_ids.h
generated
|
@ -39,11 +39,9 @@ extern "C" {
|
||||||
#define _CALL_BUILTIN_FAST 315
|
#define _CALL_BUILTIN_FAST 315
|
||||||
#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 316
|
#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 316
|
||||||
#define _CALL_BUILTIN_O 317
|
#define _CALL_BUILTIN_O 317
|
||||||
#define _CALL_FUNCTION_EX CALL_FUNCTION_EX
|
|
||||||
#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
|
#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
|
||||||
#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
|
#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
|
||||||
#define _CALL_ISINSTANCE CALL_ISINSTANCE
|
#define _CALL_ISINSTANCE CALL_ISINSTANCE
|
||||||
#define _CALL_KW CALL_KW
|
|
||||||
#define _CALL_LEN CALL_LEN
|
#define _CALL_LEN CALL_LEN
|
||||||
#define _CALL_LIST_APPEND CALL_LIST_APPEND
|
#define _CALL_LIST_APPEND CALL_LIST_APPEND
|
||||||
#define _CALL_METHOD_DESCRIPTOR_FAST 318
|
#define _CALL_METHOD_DESCRIPTOR_FAST 318
|
||||||
|
@ -69,15 +67,16 @@ extern "C" {
|
||||||
#define _CHECK_METHOD_VERSION 335
|
#define _CHECK_METHOD_VERSION 335
|
||||||
#define _CHECK_PEP_523 336
|
#define _CHECK_PEP_523 336
|
||||||
#define _CHECK_PERIODIC 337
|
#define _CHECK_PERIODIC 337
|
||||||
#define _CHECK_STACK_SPACE 338
|
#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 338
|
||||||
#define _CHECK_STACK_SPACE_OPERAND 339
|
#define _CHECK_STACK_SPACE 339
|
||||||
#define _CHECK_VALIDITY 340
|
#define _CHECK_STACK_SPACE_OPERAND 340
|
||||||
#define _CHECK_VALIDITY_AND_SET_IP 341
|
#define _CHECK_VALIDITY 341
|
||||||
#define _COMPARE_OP 342
|
#define _CHECK_VALIDITY_AND_SET_IP 342
|
||||||
#define _COMPARE_OP_FLOAT 343
|
#define _COMPARE_OP 343
|
||||||
#define _COMPARE_OP_INT 344
|
#define _COMPARE_OP_FLOAT 344
|
||||||
#define _COMPARE_OP_STR 345
|
#define _COMPARE_OP_INT 345
|
||||||
#define _CONTAINS_OP 346
|
#define _COMPARE_OP_STR 346
|
||||||
|
#define _CONTAINS_OP 347
|
||||||
#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
|
||||||
|
@ -89,61 +88,61 @@ extern "C" {
|
||||||
#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 347
|
#define _DEOPT 348
|
||||||
#define _DICT_MERGE DICT_MERGE
|
#define _DICT_MERGE DICT_MERGE
|
||||||
#define _DICT_UPDATE DICT_UPDATE
|
#define _DICT_UPDATE DICT_UPDATE
|
||||||
#define _DO_CALL 348
|
#define _DO_CALL 349
|
||||||
#define _DYNAMIC_EXIT 349
|
#define _DO_CALL_KW 350
|
||||||
|
#define _DYNAMIC_EXIT 351
|
||||||
#define _END_SEND END_SEND
|
#define _END_SEND END_SEND
|
||||||
#define _ERROR_POP_N 350
|
#define _ERROR_POP_N 352
|
||||||
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
|
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
|
||||||
#define _EXPAND_METHOD 351
|
#define _EXPAND_METHOD 353
|
||||||
#define _FATAL_ERROR 352
|
#define _FATAL_ERROR 354
|
||||||
#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 353
|
#define _FOR_ITER 355
|
||||||
#define _FOR_ITER_GEN_FRAME 354
|
#define _FOR_ITER_GEN_FRAME 356
|
||||||
#define _FOR_ITER_TIER_TWO 355
|
#define _FOR_ITER_TIER_TWO 357
|
||||||
#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 356
|
#define _GUARD_BOTH_FLOAT 358
|
||||||
#define _GUARD_BOTH_INT 357
|
#define _GUARD_BOTH_INT 359
|
||||||
#define _GUARD_BOTH_UNICODE 358
|
#define _GUARD_BOTH_UNICODE 360
|
||||||
#define _GUARD_BUILTINS_VERSION 359
|
#define _GUARD_BUILTINS_VERSION 361
|
||||||
#define _GUARD_DORV_NO_DICT 360
|
#define _GUARD_DORV_NO_DICT 362
|
||||||
#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 361
|
#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 363
|
||||||
#define _GUARD_GLOBALS_VERSION 362
|
#define _GUARD_GLOBALS_VERSION 364
|
||||||
#define _GUARD_IS_FALSE_POP 363
|
#define _GUARD_IS_FALSE_POP 365
|
||||||
#define _GUARD_IS_NONE_POP 364
|
#define _GUARD_IS_NONE_POP 366
|
||||||
#define _GUARD_IS_NOT_NONE_POP 365
|
#define _GUARD_IS_NOT_NONE_POP 367
|
||||||
#define _GUARD_IS_TRUE_POP 366
|
#define _GUARD_IS_TRUE_POP 368
|
||||||
#define _GUARD_KEYS_VERSION 367
|
#define _GUARD_KEYS_VERSION 369
|
||||||
#define _GUARD_NOS_FLOAT 368
|
#define _GUARD_NOS_FLOAT 370
|
||||||
#define _GUARD_NOS_INT 369
|
#define _GUARD_NOS_INT 371
|
||||||
#define _GUARD_NOT_EXHAUSTED_LIST 370
|
#define _GUARD_NOT_EXHAUSTED_LIST 372
|
||||||
#define _GUARD_NOT_EXHAUSTED_RANGE 371
|
#define _GUARD_NOT_EXHAUSTED_RANGE 373
|
||||||
#define _GUARD_NOT_EXHAUSTED_TUPLE 372
|
#define _GUARD_NOT_EXHAUSTED_TUPLE 374
|
||||||
#define _GUARD_TOS_FLOAT 373
|
#define _GUARD_TOS_FLOAT 375
|
||||||
#define _GUARD_TOS_INT 374
|
#define _GUARD_TOS_INT 376
|
||||||
#define _GUARD_TYPE_VERSION 375
|
#define _GUARD_TYPE_VERSION 377
|
||||||
#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 376
|
#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 378
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS 377
|
#define _INIT_CALL_PY_EXACT_ARGS 379
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_0 378
|
#define _INIT_CALL_PY_EXACT_ARGS_0 380
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_1 379
|
#define _INIT_CALL_PY_EXACT_ARGS_1 381
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_2 380
|
#define _INIT_CALL_PY_EXACT_ARGS_2 382
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_3 381
|
#define _INIT_CALL_PY_EXACT_ARGS_3 383
|
||||||
#define _INIT_CALL_PY_EXACT_ARGS_4 382
|
#define _INIT_CALL_PY_EXACT_ARGS_4 384
|
||||||
#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
|
||||||
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
|
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
|
||||||
#define _INSTRUMENTED_JUMP_BACKWARD INSTRUMENTED_JUMP_BACKWARD
|
|
||||||
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
|
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
|
||||||
#define _INSTRUMENTED_LINE INSTRUMENTED_LINE
|
#define _INSTRUMENTED_LINE INSTRUMENTED_LINE
|
||||||
#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
|
#define _INSTRUMENTED_LOAD_SUPER_ATTR INSTRUMENTED_LOAD_SUPER_ATTR
|
||||||
|
@ -151,66 +150,65 @@ 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 _INSTRUMENTED_RESUME INSTRUMENTED_RESUME
|
#define _INTERNAL_INCREMENT_OPT_COUNTER 385
|
||||||
#define _INTERNAL_INCREMENT_OPT_COUNTER 383
|
#define _IS_NONE 386
|
||||||
#define _IS_NONE 384
|
|
||||||
#define _IS_OP IS_OP
|
#define _IS_OP IS_OP
|
||||||
#define _ITER_CHECK_LIST 385
|
#define _ITER_CHECK_LIST 387
|
||||||
#define _ITER_CHECK_RANGE 386
|
#define _ITER_CHECK_RANGE 388
|
||||||
#define _ITER_CHECK_TUPLE 387
|
#define _ITER_CHECK_TUPLE 389
|
||||||
#define _ITER_JUMP_LIST 388
|
#define _ITER_JUMP_LIST 390
|
||||||
#define _ITER_JUMP_RANGE 389
|
#define _ITER_JUMP_RANGE 391
|
||||||
#define _ITER_JUMP_TUPLE 390
|
#define _ITER_JUMP_TUPLE 392
|
||||||
#define _ITER_NEXT_LIST 391
|
#define _ITER_NEXT_LIST 393
|
||||||
#define _ITER_NEXT_RANGE 392
|
#define _ITER_NEXT_RANGE 394
|
||||||
#define _ITER_NEXT_TUPLE 393
|
#define _ITER_NEXT_TUPLE 395
|
||||||
#define _JUMP_TO_TOP 394
|
#define _JUMP_TO_TOP 396
|
||||||
#define _LIST_APPEND LIST_APPEND
|
#define _LIST_APPEND LIST_APPEND
|
||||||
#define _LIST_EXTEND LIST_EXTEND
|
#define _LIST_EXTEND LIST_EXTEND
|
||||||
#define _LOAD_ATTR 395
|
#define _LOAD_ATTR 397
|
||||||
#define _LOAD_ATTR_CLASS 396
|
#define _LOAD_ATTR_CLASS 398
|
||||||
#define _LOAD_ATTR_CLASS_0 397
|
#define _LOAD_ATTR_CLASS_0 399
|
||||||
#define _LOAD_ATTR_CLASS_1 398
|
#define _LOAD_ATTR_CLASS_1 400
|
||||||
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
|
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
|
||||||
#define _LOAD_ATTR_INSTANCE_VALUE 399
|
#define _LOAD_ATTR_INSTANCE_VALUE 401
|
||||||
#define _LOAD_ATTR_INSTANCE_VALUE_0 400
|
#define _LOAD_ATTR_INSTANCE_VALUE_0 402
|
||||||
#define _LOAD_ATTR_INSTANCE_VALUE_1 401
|
#define _LOAD_ATTR_INSTANCE_VALUE_1 403
|
||||||
#define _LOAD_ATTR_METHOD_LAZY_DICT 402
|
#define _LOAD_ATTR_METHOD_LAZY_DICT 404
|
||||||
#define _LOAD_ATTR_METHOD_NO_DICT 403
|
#define _LOAD_ATTR_METHOD_NO_DICT 405
|
||||||
#define _LOAD_ATTR_METHOD_WITH_VALUES 404
|
#define _LOAD_ATTR_METHOD_WITH_VALUES 406
|
||||||
#define _LOAD_ATTR_MODULE 405
|
#define _LOAD_ATTR_MODULE 407
|
||||||
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 406
|
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 408
|
||||||
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 407
|
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 409
|
||||||
#define _LOAD_ATTR_PROPERTY_FRAME 408
|
#define _LOAD_ATTR_PROPERTY_FRAME 410
|
||||||
#define _LOAD_ATTR_SLOT 409
|
#define _LOAD_ATTR_SLOT 411
|
||||||
#define _LOAD_ATTR_SLOT_0 410
|
#define _LOAD_ATTR_SLOT_0 412
|
||||||
#define _LOAD_ATTR_SLOT_1 411
|
#define _LOAD_ATTR_SLOT_1 413
|
||||||
#define _LOAD_ATTR_WITH_HINT 412
|
#define _LOAD_ATTR_WITH_HINT 414
|
||||||
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
|
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
|
||||||
#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_INLINE 413
|
#define _LOAD_CONST_INLINE 415
|
||||||
#define _LOAD_CONST_INLINE_BORROW 414
|
#define _LOAD_CONST_INLINE_BORROW 416
|
||||||
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 415
|
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 417
|
||||||
#define _LOAD_CONST_INLINE_WITH_NULL 416
|
#define _LOAD_CONST_INLINE_WITH_NULL 418
|
||||||
#define _LOAD_DEREF LOAD_DEREF
|
#define _LOAD_DEREF LOAD_DEREF
|
||||||
#define _LOAD_FAST 417
|
#define _LOAD_FAST 419
|
||||||
#define _LOAD_FAST_0 418
|
#define _LOAD_FAST_0 420
|
||||||
#define _LOAD_FAST_1 419
|
#define _LOAD_FAST_1 421
|
||||||
#define _LOAD_FAST_2 420
|
#define _LOAD_FAST_2 422
|
||||||
#define _LOAD_FAST_3 421
|
#define _LOAD_FAST_3 423
|
||||||
#define _LOAD_FAST_4 422
|
#define _LOAD_FAST_4 424
|
||||||
#define _LOAD_FAST_5 423
|
#define _LOAD_FAST_5 425
|
||||||
#define _LOAD_FAST_6 424
|
#define _LOAD_FAST_6 426
|
||||||
#define _LOAD_FAST_7 425
|
#define _LOAD_FAST_7 427
|
||||||
#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 426
|
#define _LOAD_GLOBAL 428
|
||||||
#define _LOAD_GLOBAL_BUILTINS 427
|
#define _LOAD_GLOBAL_BUILTINS 429
|
||||||
#define _LOAD_GLOBAL_MODULE 428
|
#define _LOAD_GLOBAL_MODULE 430
|
||||||
#define _LOAD_LOCALS LOAD_LOCALS
|
#define _LOAD_LOCALS LOAD_LOCALS
|
||||||
#define _LOAD_NAME LOAD_NAME
|
#define _LOAD_NAME LOAD_NAME
|
||||||
#define _LOAD_SPECIAL LOAD_SPECIAL
|
#define _LOAD_SPECIAL LOAD_SPECIAL
|
||||||
|
@ -223,55 +221,58 @@ extern "C" {
|
||||||
#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 429
|
#define _MAYBE_EXPAND_METHOD 431
|
||||||
#define _MONITOR_CALL 430
|
#define _MONITOR_CALL 432
|
||||||
|
#define _MONITOR_JUMP_BACKWARD 433
|
||||||
|
#define _MONITOR_RESUME 434
|
||||||
#define _NOP NOP
|
#define _NOP NOP
|
||||||
#define _POP_EXCEPT POP_EXCEPT
|
#define _POP_EXCEPT POP_EXCEPT
|
||||||
#define _POP_JUMP_IF_FALSE 431
|
#define _POP_JUMP_IF_FALSE 435
|
||||||
#define _POP_JUMP_IF_TRUE 432
|
#define _POP_JUMP_IF_TRUE 436
|
||||||
#define _POP_TOP POP_TOP
|
#define _POP_TOP POP_TOP
|
||||||
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 433
|
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 437
|
||||||
#define _PUSH_EXC_INFO PUSH_EXC_INFO
|
#define _PUSH_EXC_INFO PUSH_EXC_INFO
|
||||||
#define _PUSH_FRAME 434
|
#define _PUSH_FRAME 438
|
||||||
#define _PUSH_NULL PUSH_NULL
|
#define _PUSH_NULL PUSH_NULL
|
||||||
#define _PY_FRAME_GENERAL 435
|
#define _PY_FRAME_GENERAL 439
|
||||||
#define _REPLACE_WITH_TRUE 436
|
#define _QUICKEN_RESUME 440
|
||||||
|
#define _REPLACE_WITH_TRUE 441
|
||||||
#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 437
|
#define _SAVE_RETURN_OFFSET 442
|
||||||
#define _SEND 438
|
#define _SEND 443
|
||||||
#define _SEND_GEN_FRAME 439
|
#define _SEND_GEN_FRAME 444
|
||||||
#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 440
|
#define _START_EXECUTOR 445
|
||||||
#define _STORE_ATTR 441
|
#define _STORE_ATTR 446
|
||||||
#define _STORE_ATTR_INSTANCE_VALUE 442
|
#define _STORE_ATTR_INSTANCE_VALUE 447
|
||||||
#define _STORE_ATTR_SLOT 443
|
#define _STORE_ATTR_SLOT 448
|
||||||
#define _STORE_ATTR_WITH_HINT 444
|
#define _STORE_ATTR_WITH_HINT 449
|
||||||
#define _STORE_DEREF STORE_DEREF
|
#define _STORE_DEREF STORE_DEREF
|
||||||
#define _STORE_FAST 445
|
#define _STORE_FAST 450
|
||||||
#define _STORE_FAST_0 446
|
#define _STORE_FAST_0 451
|
||||||
#define _STORE_FAST_1 447
|
#define _STORE_FAST_1 452
|
||||||
#define _STORE_FAST_2 448
|
#define _STORE_FAST_2 453
|
||||||
#define _STORE_FAST_3 449
|
#define _STORE_FAST_3 454
|
||||||
#define _STORE_FAST_4 450
|
#define _STORE_FAST_4 455
|
||||||
#define _STORE_FAST_5 451
|
#define _STORE_FAST_5 456
|
||||||
#define _STORE_FAST_6 452
|
#define _STORE_FAST_6 457
|
||||||
#define _STORE_FAST_7 453
|
#define _STORE_FAST_7 458
|
||||||
#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 STORE_SLICE
|
#define _STORE_SLICE STORE_SLICE
|
||||||
#define _STORE_SUBSCR 454
|
#define _STORE_SUBSCR 459
|
||||||
#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 455
|
#define _TIER2_RESUME_CHECK 460
|
||||||
#define _TO_BOOL 456
|
#define _TO_BOOL 461
|
||||||
#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
|
||||||
|
@ -281,13 +282,14 @@ 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 457
|
#define _UNPACK_SEQUENCE 462
|
||||||
#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 457
|
#define __DO_CALL_FUNCTION_EX _DO_CALL_FUNCTION_EX
|
||||||
|
#define MAX_UOP_ID 462
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
10
Include/internal/pycore_uop_metadata.h
generated
10
Include/internal/pycore_uop_metadata.h
generated
|
@ -20,6 +20,8 @@ extern int _PyUop_num_popped(int opcode, int oparg);
|
||||||
#ifdef NEED_OPCODE_METADATA
|
#ifdef NEED_OPCODE_METADATA
|
||||||
const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_NOP] = HAS_PURE_FLAG,
|
[_NOP] = HAS_PURE_FLAG,
|
||||||
|
[_CHECK_PERIODIC] = HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
|
[_CHECK_PERIODIC_IF_NOT_YIELD_FROM] = HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_RESUME_CHECK] = HAS_DEOPT_FLAG,
|
[_RESUME_CHECK] = HAS_DEOPT_FLAG,
|
||||||
[_LOAD_FAST_CHECK] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
[_LOAD_FAST_CHECK] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||||
[_LOAD_FAST_0] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
|
[_LOAD_FAST_0] = HAS_LOCAL_FLAG | HAS_PURE_FLAG,
|
||||||
|
@ -202,7 +204,6 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
||||||
[_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
|
[_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
|
||||||
[_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG,
|
[_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG,
|
||||||
[_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG,
|
[_MAYBE_EXPAND_METHOD] = HAS_ARG_FLAG,
|
||||||
[_CHECK_PERIODIC] = HAS_EVAL_BREAK_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_METHOD_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
|
[_CHECK_METHOD_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
|
||||||
|
@ -334,6 +335,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
||||||
[_CHECK_METHOD_VERSION] = "_CHECK_METHOD_VERSION",
|
[_CHECK_METHOD_VERSION] = "_CHECK_METHOD_VERSION",
|
||||||
[_CHECK_PEP_523] = "_CHECK_PEP_523",
|
[_CHECK_PEP_523] = "_CHECK_PEP_523",
|
||||||
[_CHECK_PERIODIC] = "_CHECK_PERIODIC",
|
[_CHECK_PERIODIC] = "_CHECK_PERIODIC",
|
||||||
|
[_CHECK_PERIODIC_IF_NOT_YIELD_FROM] = "_CHECK_PERIODIC_IF_NOT_YIELD_FROM",
|
||||||
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
|
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
|
||||||
[_CHECK_STACK_SPACE_OPERAND] = "_CHECK_STACK_SPACE_OPERAND",
|
[_CHECK_STACK_SPACE_OPERAND] = "_CHECK_STACK_SPACE_OPERAND",
|
||||||
[_CHECK_VALIDITY] = "_CHECK_VALIDITY",
|
[_CHECK_VALIDITY] = "_CHECK_VALIDITY",
|
||||||
|
@ -536,6 +538,10 @@ int _PyUop_num_popped(int opcode, int oparg)
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case _NOP:
|
case _NOP:
|
||||||
return 0;
|
return 0;
|
||||||
|
case _CHECK_PERIODIC:
|
||||||
|
return 0;
|
||||||
|
case _CHECK_PERIODIC_IF_NOT_YIELD_FROM:
|
||||||
|
return 0;
|
||||||
case _RESUME_CHECK:
|
case _RESUME_CHECK:
|
||||||
return 0;
|
return 0;
|
||||||
case _LOAD_FAST_CHECK:
|
case _LOAD_FAST_CHECK:
|
||||||
|
@ -900,8 +906,6 @@ int _PyUop_num_popped(int opcode, int oparg)
|
||||||
return 1;
|
return 1;
|
||||||
case _MAYBE_EXPAND_METHOD:
|
case _MAYBE_EXPAND_METHOD:
|
||||||
return 2 + oparg;
|
return 2 + oparg;
|
||||||
case _CHECK_PERIODIC:
|
|
||||||
return 0;
|
|
||||||
case _PY_FRAME_GENERAL:
|
case _PY_FRAME_GENERAL:
|
||||||
return 2 + oparg;
|
return 2 + oparg;
|
||||||
case _CHECK_FUNCTION_VERSION:
|
case _CHECK_FUNCTION_VERSION:
|
||||||
|
|
37
Include/opcode_ids.h
generated
37
Include/opcode_ids.h
generated
|
@ -126,6 +126,7 @@ extern "C" {
|
||||||
#define UNPACK_EX 113
|
#define UNPACK_EX 113
|
||||||
#define UNPACK_SEQUENCE 114
|
#define UNPACK_SEQUENCE 114
|
||||||
#define YIELD_VALUE 115
|
#define YIELD_VALUE 115
|
||||||
|
#define _DO_CALL_FUNCTION_EX 116
|
||||||
#define RESUME 149
|
#define RESUME 149
|
||||||
#define BINARY_OP_ADD_FLOAT 150
|
#define BINARY_OP_ADD_FLOAT 150
|
||||||
#define BINARY_OP_ADD_INT 151
|
#define BINARY_OP_ADD_INT 151
|
||||||
|
@ -200,24 +201,24 @@ extern "C" {
|
||||||
#define UNPACK_SEQUENCE_LIST 220
|
#define UNPACK_SEQUENCE_LIST 220
|
||||||
#define UNPACK_SEQUENCE_TUPLE 221
|
#define UNPACK_SEQUENCE_TUPLE 221
|
||||||
#define UNPACK_SEQUENCE_TWO_TUPLE 222
|
#define UNPACK_SEQUENCE_TWO_TUPLE 222
|
||||||
#define INSTRUMENTED_RESUME 236
|
#define INSTRUMENTED_END_FOR 236
|
||||||
#define INSTRUMENTED_END_FOR 237
|
#define INSTRUMENTED_END_SEND 237
|
||||||
#define INSTRUMENTED_END_SEND 238
|
#define INSTRUMENTED_LOAD_SUPER_ATTR 238
|
||||||
#define INSTRUMENTED_LOAD_SUPER_ATTR 239
|
#define INSTRUMENTED_FOR_ITER 239
|
||||||
#define INSTRUMENTED_FOR_ITER 240
|
#define INSTRUMENTED_CALL_KW 240
|
||||||
#define INSTRUMENTED_CALL_KW 241
|
#define INSTRUMENTED_CALL_FUNCTION_EX 241
|
||||||
#define INSTRUMENTED_CALL_FUNCTION_EX 242
|
#define INSTRUMENTED_INSTRUCTION 242
|
||||||
#define INSTRUMENTED_INSTRUCTION 243
|
#define INSTRUMENTED_JUMP_FORWARD 243
|
||||||
#define INSTRUMENTED_JUMP_FORWARD 244
|
#define INSTRUMENTED_POP_JUMP_IF_TRUE 244
|
||||||
#define INSTRUMENTED_JUMP_BACKWARD 245
|
#define INSTRUMENTED_POP_JUMP_IF_FALSE 245
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_TRUE 246
|
#define INSTRUMENTED_POP_JUMP_IF_NONE 246
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_FALSE 247
|
#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 247
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_NONE 248
|
#define INSTRUMENTED_RESUME 248
|
||||||
#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 249
|
#define INSTRUMENTED_RETURN_VALUE 249
|
||||||
#define INSTRUMENTED_RETURN_VALUE 250
|
#define INSTRUMENTED_RETURN_CONST 250
|
||||||
#define INSTRUMENTED_RETURN_CONST 251
|
#define INSTRUMENTED_YIELD_VALUE 251
|
||||||
#define INSTRUMENTED_YIELD_VALUE 252
|
#define INSTRUMENTED_CALL 252
|
||||||
#define INSTRUMENTED_CALL 253
|
#define INSTRUMENTED_JUMP_BACKWARD 253
|
||||||
#define INSTRUMENTED_LINE 254
|
#define INSTRUMENTED_LINE 254
|
||||||
#define ENTER_EXECUTOR 255
|
#define ENTER_EXECUTOR 255
|
||||||
#define JUMP 256
|
#define JUMP 256
|
||||||
|
|
37
Lib/_opcode_metadata.py
generated
37
Lib/_opcode_metadata.py
generated
|
@ -305,24 +305,25 @@ opmap = {
|
||||||
'UNPACK_EX': 113,
|
'UNPACK_EX': 113,
|
||||||
'UNPACK_SEQUENCE': 114,
|
'UNPACK_SEQUENCE': 114,
|
||||||
'YIELD_VALUE': 115,
|
'YIELD_VALUE': 115,
|
||||||
'INSTRUMENTED_RESUME': 236,
|
'_DO_CALL_FUNCTION_EX': 116,
|
||||||
'INSTRUMENTED_END_FOR': 237,
|
'INSTRUMENTED_END_FOR': 236,
|
||||||
'INSTRUMENTED_END_SEND': 238,
|
'INSTRUMENTED_END_SEND': 237,
|
||||||
'INSTRUMENTED_LOAD_SUPER_ATTR': 239,
|
'INSTRUMENTED_LOAD_SUPER_ATTR': 238,
|
||||||
'INSTRUMENTED_FOR_ITER': 240,
|
'INSTRUMENTED_FOR_ITER': 239,
|
||||||
'INSTRUMENTED_CALL_KW': 241,
|
'INSTRUMENTED_CALL_KW': 240,
|
||||||
'INSTRUMENTED_CALL_FUNCTION_EX': 242,
|
'INSTRUMENTED_CALL_FUNCTION_EX': 241,
|
||||||
'INSTRUMENTED_INSTRUCTION': 243,
|
'INSTRUMENTED_INSTRUCTION': 242,
|
||||||
'INSTRUMENTED_JUMP_FORWARD': 244,
|
'INSTRUMENTED_JUMP_FORWARD': 243,
|
||||||
'INSTRUMENTED_JUMP_BACKWARD': 245,
|
'INSTRUMENTED_POP_JUMP_IF_TRUE': 244,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_TRUE': 246,
|
'INSTRUMENTED_POP_JUMP_IF_FALSE': 245,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_FALSE': 247,
|
'INSTRUMENTED_POP_JUMP_IF_NONE': 246,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_NONE': 248,
|
'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 247,
|
||||||
'INSTRUMENTED_POP_JUMP_IF_NOT_NONE': 249,
|
'INSTRUMENTED_RESUME': 248,
|
||||||
'INSTRUMENTED_RETURN_VALUE': 250,
|
'INSTRUMENTED_RETURN_VALUE': 249,
|
||||||
'INSTRUMENTED_RETURN_CONST': 251,
|
'INSTRUMENTED_RETURN_CONST': 250,
|
||||||
'INSTRUMENTED_YIELD_VALUE': 252,
|
'INSTRUMENTED_YIELD_VALUE': 251,
|
||||||
'INSTRUMENTED_CALL': 253,
|
'INSTRUMENTED_CALL': 252,
|
||||||
|
'INSTRUMENTED_JUMP_BACKWARD': 253,
|
||||||
'JUMP': 256,
|
'JUMP': 256,
|
||||||
'JUMP_NO_INTERRUPT': 257,
|
'JUMP_NO_INTERRUPT': 257,
|
||||||
'LOAD_CLOSURE': 258,
|
'LOAD_CLOSURE': 258,
|
||||||
|
|
|
@ -247,14 +247,13 @@ class TestGeneratedCases(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
self.run_cases_test(input, output)
|
self.run_cases_test(input, output)
|
||||||
|
|
||||||
def test_predictions_and_eval_breaker(self):
|
def test_predictions(self):
|
||||||
input = """
|
input = """
|
||||||
inst(OP1, (arg -- rest)) {
|
inst(OP1, (arg -- rest)) {
|
||||||
}
|
}
|
||||||
inst(OP3, (arg -- res)) {
|
inst(OP3, (arg -- res)) {
|
||||||
DEOPT_IF(xxx);
|
DEOPT_IF(xxx);
|
||||||
res = Py_None;
|
res = Py_None;
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
}
|
}
|
||||||
family(OP1, INLINE_CACHE_ENTRIES_OP1) = { OP3 };
|
family(OP1, INLINE_CACHE_ENTRIES_OP1) = { OP3 };
|
||||||
"""
|
"""
|
||||||
|
@ -277,7 +276,6 @@ class TestGeneratedCases(unittest.TestCase):
|
||||||
DEOPT_IF(xxx, OP1);
|
DEOPT_IF(xxx, OP1);
|
||||||
res = Py_None;
|
res = Py_None;
|
||||||
stack_pointer[-1] = res;
|
stack_pointer[-1] = res;
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "pycore_abstract.h" // _PyIndex_Check()
|
#include "pycore_abstract.h" // _PyIndex_Check()
|
||||||
#include "pycore_backoff.h"
|
#include "pycore_backoff.h"
|
||||||
#include "pycore_cell.h" // PyCell_GetRef()
|
#include "pycore_cell.h" // PyCell_GetRef()
|
||||||
|
#include "pycore_ceval.h"
|
||||||
#include "pycore_code.h"
|
#include "pycore_code.h"
|
||||||
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
|
#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS
|
||||||
#include "pycore_function.h"
|
#include "pycore_function.h"
|
||||||
|
@ -146,36 +147,54 @@ dummy_func(
|
||||||
RESUME_CHECK,
|
RESUME_CHECK,
|
||||||
};
|
};
|
||||||
|
|
||||||
tier1 inst(RESUME, (--)) {
|
op(_CHECK_PERIODIC, (--)) {
|
||||||
assert(frame == tstate->current_frame);
|
_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, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
op(_CHECK_PERIODIC_IF_NOT_YIELD_FROM, (--)) {
|
||||||
|
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||||
|
_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, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
op(_QUICKEN_RESUME, (--)) {
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
if (tstate->tracing == 0 && this_instr->op.code == RESUME) {
|
||||||
|
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_SPECIALIZATION */
|
||||||
|
}
|
||||||
|
|
||||||
|
tier1 op(_MAYBE_INSTRUMENT, (--)) {
|
||||||
if (tstate->tracing == 0) {
|
if (tstate->tracing == 0) {
|
||||||
uintptr_t global_version =
|
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
||||||
_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) &
|
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version);
|
||||||
~_PY_EVAL_EVENTS_MASK;
|
|
||||||
PyCodeObject* code = _PyFrame_GetCode(frame);
|
|
||||||
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(code->_co_instrumentation_version);
|
|
||||||
assert((code_version & 255) == 0);
|
|
||||||
if (code_version != global_version) {
|
if (code_version != global_version) {
|
||||||
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
||||||
ERROR_IF(err, error);
|
if (err) {
|
||||||
|
ERROR_NO_POP();
|
||||||
|
}
|
||||||
next_instr = this_instr;
|
next_instr = this_instr;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
assert(this_instr->op.code == RESUME ||
|
|
||||||
this_instr->op.code == RESUME_CHECK ||
|
|
||||||
this_instr->op.code == INSTRUMENTED_RESUME ||
|
|
||||||
this_instr->op.code == ENTER_EXECUTOR);
|
|
||||||
if (this_instr->op.code == RESUME) {
|
|
||||||
#if ENABLE_SPECIALIZATION
|
|
||||||
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
|
|
||||||
#endif /* ENABLE_SPECIALIZATION */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro(RESUME) =
|
||||||
|
_MAYBE_INSTRUMENT +
|
||||||
|
_QUICKEN_RESUME +
|
||||||
|
_CHECK_PERIODIC_IF_NOT_YIELD_FROM;
|
||||||
|
|
||||||
inst(RESUME_CHECK, (--)) {
|
inst(RESUME_CHECK, (--)) {
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__)
|
||||||
DEOPT_IF(_Py_emscripten_signal_clock == 0);
|
DEOPT_IF(_Py_emscripten_signal_clock == 0);
|
||||||
|
@ -187,33 +206,23 @@ dummy_func(
|
||||||
DEOPT_IF(eval_breaker != version);
|
DEOPT_IF(eval_breaker != version);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(INSTRUMENTED_RESUME, (--)) {
|
op(_MONITOR_RESUME, (--)) {
|
||||||
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version);
|
int err = _Py_call_instrumentation(
|
||||||
if (code_version != global_version && tstate->tracing == 0) {
|
tstate, oparg > 0, frame, this_instr);
|
||||||
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (err) {
|
ERROR_IF(err, error);
|
||||||
ERROR_NO_POP();
|
if (frame->instr_ptr != this_instr) {
|
||||||
}
|
/* Instrumentation has jumped */
|
||||||
next_instr = this_instr;
|
next_instr = frame->instr_ptr;
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
}
|
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
|
||||||
int err = _Py_call_instrumentation(
|
|
||||||
tstate, oparg > 0, frame, this_instr);
|
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
|
||||||
ERROR_IF(err, error);
|
|
||||||
if (frame->instr_ptr != this_instr) {
|
|
||||||
/* Instrumentation has jumped */
|
|
||||||
next_instr = frame->instr_ptr;
|
|
||||||
DISPATCH();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro(INSTRUMENTED_RESUME) =
|
||||||
|
_MAYBE_INSTRUMENT +
|
||||||
|
_CHECK_PERIODIC_IF_NOT_YIELD_FROM +
|
||||||
|
_MONITOR_RESUME;
|
||||||
|
|
||||||
pseudo(LOAD_CLOSURE, (-- unused)) = {
|
pseudo(LOAD_CLOSURE, (-- unused)) = {
|
||||||
LOAD_FAST,
|
LOAD_FAST,
|
||||||
};
|
};
|
||||||
|
@ -2486,8 +2495,7 @@ dummy_func(
|
||||||
JUMPBY(oparg);
|
JUMPBY(oparg);
|
||||||
}
|
}
|
||||||
|
|
||||||
tier1 inst(JUMP_BACKWARD, (unused/1 --)) {
|
tier1 op(_JUMP_BACKWARD, (the_counter/1 --)) {
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
assert(oparg <= INSTR_OFFSET());
|
assert(oparg <= INSTR_OFFSET());
|
||||||
JUMPBY(-oparg);
|
JUMPBY(-oparg);
|
||||||
#ifdef _Py_TIER2
|
#ifdef _Py_TIER2
|
||||||
|
@ -2519,6 +2527,10 @@ dummy_func(
|
||||||
#endif /* _Py_TIER2 */
|
#endif /* _Py_TIER2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro(JUMP_BACKWARD) =
|
||||||
|
_CHECK_PERIODIC +
|
||||||
|
_JUMP_BACKWARD;
|
||||||
|
|
||||||
pseudo(JUMP, (--)) = {
|
pseudo(JUMP, (--)) = {
|
||||||
JUMP_FORWARD,
|
JUMP_FORWARD,
|
||||||
JUMP_BACKWARD,
|
JUMP_BACKWARD,
|
||||||
|
@ -3265,10 +3277,6 @@ dummy_func(
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CHECK_PERIODIC, (--)) {
|
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
}
|
|
||||||
|
|
||||||
op(_MONITOR_CALL, (func, maybe_self, args[oparg] -- func, maybe_self, args[oparg])) {
|
op(_MONITOR_CALL, (func, maybe_self, args[oparg] -- func, maybe_self, args[oparg])) {
|
||||||
int is_meth = !PyStackRef_IsNull(maybe_self);
|
int is_meth = !PyStackRef_IsNull(maybe_self);
|
||||||
PyObject *function = PyStackRef_AsPyObjectBorrow(func);
|
PyObject *function = PyStackRef_AsPyObjectBorrow(func);
|
||||||
|
@ -4012,7 +4020,7 @@ dummy_func(
|
||||||
GO_TO_INSTRUCTION(CALL_KW);
|
GO_TO_INSTRUCTION(CALL_KW);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) {
|
op(_DO_CALL_KW, (callable, self_or_null, args[oparg], kwnames -- res)) {
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||||
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
|
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
|
||||||
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
||||||
|
@ -4094,14 +4102,17 @@ dummy_func(
|
||||||
}
|
}
|
||||||
ERROR_IF(res_o == NULL, error);
|
ERROR_IF(res_o == NULL, error);
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro(CALL_KW) =
|
||||||
|
_DO_CALL_KW +
|
||||||
|
_CHECK_PERIODIC;
|
||||||
|
|
||||||
inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) {
|
inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) {
|
||||||
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
|
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
|
inst(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
|
||||||
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
||||||
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
||||||
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
||||||
|
@ -4175,9 +4186,13 @@ dummy_func(
|
||||||
DECREF_INPUTS();
|
DECREF_INPUTS();
|
||||||
assert(PyStackRef_AsPyObjectBorrow(PEEK(2 + (oparg & 1))) == NULL);
|
assert(PyStackRef_AsPyObjectBorrow(PEEK(2 + (oparg & 1))) == NULL);
|
||||||
ERROR_IF(PyStackRef_IsNull(result), error);
|
ERROR_IF(PyStackRef_IsNull(result), error);
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro(CALL_FUNCTION_EX) =
|
||||||
|
_DO_CALL_FUNCTION_EX +
|
||||||
|
_CHECK_PERIODIC;
|
||||||
|
|
||||||
|
|
||||||
inst(MAKE_FUNCTION, (codeobj_st -- func)) {
|
inst(MAKE_FUNCTION, (codeobj_st -- func)) {
|
||||||
PyObject *codeobj = PyStackRef_AsPyObjectBorrow(codeobj_st);
|
PyObject *codeobj = PyStackRef_AsPyObjectBorrow(codeobj_st);
|
||||||
|
|
||||||
|
@ -4381,11 +4396,15 @@ dummy_func(
|
||||||
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
|
INSTRUMENTED_JUMP(this_instr, next_instr + oparg, PY_MONITORING_EVENT_JUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(INSTRUMENTED_JUMP_BACKWARD, (unused/1 -- )) {
|
op(_MONITOR_JUMP_BACKWARD, (-- )) {
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
|
INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro(INSTRUMENTED_JUMP_BACKWARD) =
|
||||||
|
unused/1 +
|
||||||
|
_CHECK_PERIODIC +
|
||||||
|
_MONITOR_JUMP_BACKWARD;
|
||||||
|
|
||||||
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
|
inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
|
||||||
_PyStackRef cond = POP();
|
_PyStackRef cond = POP();
|
||||||
assert(PyStackRef_BoolCheck(cond));
|
assert(PyStackRef_BoolCheck(cond));
|
||||||
|
|
|
@ -133,16 +133,6 @@ do { \
|
||||||
// Use this instead of 'goto error' so Tier 2 can go to a different label
|
// Use this instead of 'goto error' so Tier 2 can go to a different label
|
||||||
#define GOTO_ERROR(LABEL) goto LABEL
|
#define GOTO_ERROR(LABEL) goto LABEL
|
||||||
|
|
||||||
#define CHECK_EVAL_BREAKER() \
|
|
||||||
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \
|
|
||||||
QSBR_QUIESCENT_STATE(tstate); \
|
|
||||||
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { \
|
|
||||||
if (_Py_HandlePending(tstate) != 0) { \
|
|
||||||
GOTO_ERROR(error); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Tuple access macros */
|
/* Tuple access macros */
|
||||||
|
|
||||||
#ifndef Py_DEBUG
|
#ifndef Py_DEBUG
|
||||||
|
|
38
Python/executor_cases.c.h
generated
38
Python/executor_cases.c.h
generated
|
@ -12,6 +12,31 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case _CHECK_PERIODIC: {
|
||||||
|
_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);
|
||||||
|
if (err != 0) JUMP_TO_ERROR();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _CHECK_PERIODIC_IF_NOT_YIELD_FROM: {
|
||||||
|
oparg = CURRENT_OPARG();
|
||||||
|
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||||
|
_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);
|
||||||
|
if (err != 0) JUMP_TO_ERROR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _QUICKEN_RESUME is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
case _RESUME_CHECK: {
|
case _RESUME_CHECK: {
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__)
|
||||||
if (_Py_emscripten_signal_clock == 0) {
|
if (_Py_emscripten_signal_clock == 0) {
|
||||||
|
@ -30,7 +55,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_RESUME is not a viable micro-op for tier 2 because it is instrumented */
|
/* _MONITOR_RESUME is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
case _LOAD_FAST_CHECK: {
|
case _LOAD_FAST_CHECK: {
|
||||||
_PyStackRef value;
|
_PyStackRef value;
|
||||||
|
@ -3555,11 +3580,6 @@
|
||||||
|
|
||||||
/* _DO_CALL is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
/* _DO_CALL is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
case _CHECK_PERIODIC: {
|
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _MONITOR_CALL is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
/* _MONITOR_CALL is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
case _PY_FRAME_GENERAL: {
|
case _PY_FRAME_GENERAL: {
|
||||||
|
@ -4657,11 +4677,11 @@
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 because it is instrumented */
|
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 because it is instrumented */
|
||||||
|
|
||||||
/* _CALL_KW is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
/* _DO_CALL_KW is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
|
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
|
||||||
|
|
||||||
/* _CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
/* __DO_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
case _MAKE_FUNCTION: {
|
case _MAKE_FUNCTION: {
|
||||||
_PyStackRef codeobj_st;
|
_PyStackRef codeobj_st;
|
||||||
|
@ -4882,7 +4902,7 @@
|
||||||
|
|
||||||
/* _INSTRUMENTED_JUMP_FORWARD is not a viable micro-op for tier 2 because it is instrumented */
|
/* _INSTRUMENTED_JUMP_FORWARD is not a viable micro-op for tier 2 because it is instrumented */
|
||||||
|
|
||||||
/* _INSTRUMENTED_JUMP_BACKWARD is not a viable micro-op for tier 2 because it is instrumented */
|
/* _MONITOR_JUMP_BACKWARD is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||||
|
|
||||||
/* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 because it is instrumented */
|
/* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 because it is instrumented */
|
||||||
|
|
||||||
|
|
740
Python/generated_cases.c.h
generated
740
Python/generated_cases.c.h
generated
|
@ -949,11 +949,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1275,11 +1285,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,11 +1364,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1412,11 +1442,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1466,11 +1506,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1485,89 +1535,105 @@
|
||||||
_PyStackRef callargs_st;
|
_PyStackRef callargs_st;
|
||||||
_PyStackRef kwargs_st = PyStackRef_NULL;
|
_PyStackRef kwargs_st = PyStackRef_NULL;
|
||||||
_PyStackRef result;
|
_PyStackRef result;
|
||||||
|
// __DO_CALL_FUNCTION_EX
|
||||||
if (oparg & 1) { kwargs_st = stack_pointer[-(oparg & 1)]; }
|
if (oparg & 1) { kwargs_st = stack_pointer[-(oparg & 1)]; }
|
||||||
callargs_st = stack_pointer[-1 - (oparg & 1)];
|
callargs_st = stack_pointer[-1 - (oparg & 1)];
|
||||||
func_st = stack_pointer[-3 - (oparg & 1)];
|
func_st = stack_pointer[-3 - (oparg & 1)];
|
||||||
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
{
|
||||||
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
||||||
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
||||||
// DICT_MERGE is called before this opcode if there are kwargs.
|
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
||||||
// It converts all dict subtypes in kwargs into regular dicts.
|
// DICT_MERGE is called before this opcode if there are kwargs.
|
||||||
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
// It converts all dict subtypes in kwargs into regular dicts.
|
||||||
if (!PyTuple_CheckExact(callargs)) {
|
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||||
int err = check_args_iterable(tstate, func, callargs);
|
if (!PyTuple_CheckExact(callargs)) {
|
||||||
if (err < 0) {
|
int err = check_args_iterable(tstate, func, callargs);
|
||||||
goto error;
|
if (err < 0) {
|
||||||
}
|
goto error;
|
||||||
PyObject *tuple = PySequence_Tuple(callargs);
|
|
||||||
if (tuple == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
PyStackRef_CLOSE(callargs_st);
|
|
||||||
callargs_st = PyStackRef_FromPyObjectSteal(tuple);
|
|
||||||
callargs = tuple;
|
|
||||||
}
|
|
||||||
assert(PyTuple_CheckExact(callargs));
|
|
||||||
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func);
|
|
||||||
if (opcode == INSTRUMENTED_CALL_FUNCTION_EX) {
|
|
||||||
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
|
|
||||||
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
|
|
||||||
int err = _Py_call_instrumentation_2args(
|
|
||||||
tstate, PY_MONITORING_EVENT_CALL,
|
|
||||||
frame, this_instr, func, arg);
|
|
||||||
if (err) goto error;
|
|
||||||
result = PyStackRef_FromPyObjectSteal(PyObject_Call(func, callargs, kwargs));
|
|
||||||
if (!PyFunction_Check(func) && !PyMethod_Check(func)) {
|
|
||||||
if (PyStackRef_IsNull(result)) {
|
|
||||||
_Py_call_instrumentation_exc2(
|
|
||||||
tstate, PY_MONITORING_EVENT_C_RAISE,
|
|
||||||
frame, this_instr, func, arg);
|
|
||||||
}
|
}
|
||||||
else {
|
PyObject *tuple = PySequence_Tuple(callargs);
|
||||||
int err = _Py_call_instrumentation_2args(
|
if (tuple == NULL) {
|
||||||
tstate, PY_MONITORING_EVENT_C_RETURN,
|
goto error;
|
||||||
frame, this_instr, func, arg);
|
}
|
||||||
if (err < 0) {
|
PyStackRef_CLOSE(callargs_st);
|
||||||
PyStackRef_CLEAR(result);
|
callargs_st = PyStackRef_FromPyObjectSteal(tuple);
|
||||||
|
callargs = tuple;
|
||||||
|
}
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func);
|
||||||
|
if (opcode == INSTRUMENTED_CALL_FUNCTION_EX) {
|
||||||
|
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
|
||||||
|
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
if (err) goto error;
|
||||||
|
result = PyStackRef_FromPyObjectSteal(PyObject_Call(func, callargs, kwargs));
|
||||||
|
if (!PyFunction_Check(func) && !PyMethod_Check(func)) {
|
||||||
|
if (PyStackRef_IsNull(result)) {
|
||||||
|
_Py_call_instrumentation_exc2(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
if (err < 0) {
|
||||||
|
PyStackRef_CLEAR(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if (Py_TYPE(func) == &PyFunction_Type &&
|
||||||
|
tstate->interp->eval_frame == NULL &&
|
||||||
|
((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
|
||||||
|
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
|
||||||
|
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
|
||||||
|
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate,
|
||||||
|
(PyFunctionObject *)PyStackRef_AsPyObjectSteal(func_st), locals,
|
||||||
|
nargs, callargs, kwargs);
|
||||||
|
// Need to manually shrink the stack since we exit with DISPATCH_INLINED.
|
||||||
|
STACK_SHRINK(oparg + 3);
|
||||||
|
if (new_frame == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert(next_instr - this_instr == 1);
|
||||||
|
frame->return_offset = 1;
|
||||||
|
DISPATCH_INLINED(new_frame);
|
||||||
|
}
|
||||||
|
result = PyStackRef_FromPyObjectSteal(PyObject_Call(func, callargs, kwargs));
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(func_st);
|
||||||
|
PyStackRef_CLOSE(callargs_st);
|
||||||
|
PyStackRef_XCLOSE(kwargs_st);
|
||||||
|
assert(PyStackRef_AsPyObjectBorrow(PEEK(2 + (oparg & 1))) == NULL);
|
||||||
|
if (PyStackRef_IsNull(result)) {
|
||||||
|
stack_pointer += -3 - (oparg & 1);
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
// _CHECK_PERIODIC
|
||||||
if (Py_TYPE(func) == &PyFunction_Type &&
|
{
|
||||||
tstate->interp->eval_frame == NULL &&
|
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
|
||||||
((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
|
QSBR_QUIESCENT_STATE(tstate); \
|
||||||
assert(PyTuple_CheckExact(callargs));
|
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
|
||||||
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
|
int err = _Py_HandlePending(tstate);
|
||||||
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
|
if (err != 0) {
|
||||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
|
stack_pointer[-3 - (oparg & 1)] = result;
|
||||||
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate,
|
stack_pointer += -2 - (oparg & 1);
|
||||||
(PyFunctionObject *)PyStackRef_AsPyObjectSteal(func_st), locals,
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
nargs, callargs, kwargs);
|
|
||||||
// Need to manually shrink the stack since we exit with DISPATCH_INLINED.
|
|
||||||
STACK_SHRINK(oparg + 3);
|
|
||||||
if (new_frame == NULL) {
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
assert(next_instr - this_instr == 1);
|
|
||||||
frame->return_offset = 1;
|
|
||||||
DISPATCH_INLINED(new_frame);
|
|
||||||
}
|
}
|
||||||
result = PyStackRef_FromPyObjectSteal(PyObject_Call(func, callargs, kwargs));
|
|
||||||
}
|
|
||||||
PyStackRef_CLOSE(func_st);
|
|
||||||
PyStackRef_CLOSE(callargs_st);
|
|
||||||
PyStackRef_XCLOSE(kwargs_st);
|
|
||||||
assert(PyStackRef_AsPyObjectBorrow(PEEK(2 + (oparg & 1))) == NULL);
|
|
||||||
if (PyStackRef_IsNull(result)) {
|
|
||||||
stack_pointer += -3 - (oparg & 1);
|
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
stack_pointer[-3 - (oparg & 1)] = result;
|
stack_pointer[-3 - (oparg & 1)] = result;
|
||||||
stack_pointer += -2 - (oparg & 1);
|
stack_pointer += -2 - (oparg & 1);
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1664,107 +1730,123 @@
|
||||||
_PyStackRef *args;
|
_PyStackRef *args;
|
||||||
_PyStackRef kwnames;
|
_PyStackRef kwnames;
|
||||||
_PyStackRef res;
|
_PyStackRef res;
|
||||||
|
// _DO_CALL_KW
|
||||||
kwnames = stack_pointer[-1];
|
kwnames = stack_pointer[-1];
|
||||||
args = &stack_pointer[-1 - oparg];
|
args = &stack_pointer[-1 - oparg];
|
||||||
self_or_null = stack_pointer[-2 - oparg];
|
self_or_null = stack_pointer[-2 - oparg];
|
||||||
callable = stack_pointer[-3 - oparg];
|
callable = stack_pointer[-3 - oparg];
|
||||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
|
||||||
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
|
|
||||||
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
|
||||||
// oparg counts all of the args, but *not* self:
|
|
||||||
int total_args = oparg;
|
|
||||||
if (self_or_null_o != NULL) {
|
|
||||||
args--;
|
|
||||||
total_args++;
|
|
||||||
}
|
|
||||||
if (self_or_null_o == NULL && Py_TYPE(callable_o) == &PyMethod_Type) {
|
|
||||||
args--;
|
|
||||||
total_args++;
|
|
||||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
|
||||||
args[0] = PyStackRef_FromPyObjectNew(self);
|
|
||||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
|
||||||
args[-1] = PyStackRef_FromPyObjectNew(method);
|
|
||||||
PyStackRef_CLOSE(callable);
|
|
||||||
callable_o = method;
|
|
||||||
callable = args[-1];
|
|
||||||
}
|
|
||||||
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames_o);
|
|
||||||
// Check if the call can be inlined or not
|
|
||||||
if (Py_TYPE(callable_o) == &PyFunction_Type &&
|
|
||||||
tstate->interp->eval_frame == NULL &&
|
|
||||||
((PyFunctionObject *)callable_o)->vectorcall == _PyFunction_Vectorcall)
|
|
||||||
{
|
{
|
||||||
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
|
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
|
PyObject *self_or_null_o = PyStackRef_AsPyObjectBorrow(self_or_null);
|
||||||
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
|
||||||
tstate, (PyFunctionObject *)PyStackRef_AsPyObjectSteal(callable), locals,
|
// oparg counts all of the args, but *not* self:
|
||||||
args, positional_args, kwnames_o
|
int total_args = oparg;
|
||||||
);
|
if (self_or_null_o != NULL) {
|
||||||
PyStackRef_CLOSE(kwnames);
|
args--;
|
||||||
// Manipulate stack directly since we leave using DISPATCH_INLINED().
|
total_args++;
|
||||||
STACK_SHRINK(oparg + 3);
|
|
||||||
// The frame has stolen all the arguments from the stack,
|
|
||||||
// so there is no need to clean them up.
|
|
||||||
if (new_frame == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
assert(next_instr - this_instr == 1);
|
if (self_or_null_o == NULL && Py_TYPE(callable_o) == &PyMethod_Type) {
|
||||||
frame->return_offset = 1;
|
args--;
|
||||||
DISPATCH_INLINED(new_frame);
|
total_args++;
|
||||||
}
|
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||||
/* Callable is not a normal Python function */
|
args[0] = PyStackRef_FromPyObjectNew(self);
|
||||||
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||||
if (CONVERSION_FAILED(args_o)) {
|
args[-1] = PyStackRef_FromPyObjectNew(method);
|
||||||
|
PyStackRef_CLOSE(callable);
|
||||||
|
callable_o = method;
|
||||||
|
callable = args[-1];
|
||||||
|
}
|
||||||
|
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames_o);
|
||||||
|
// Check if the call can be inlined or not
|
||||||
|
if (Py_TYPE(callable_o) == &PyFunction_Type &&
|
||||||
|
tstate->interp->eval_frame == NULL &&
|
||||||
|
((PyFunctionObject *)callable_o)->vectorcall == _PyFunction_Vectorcall)
|
||||||
|
{
|
||||||
|
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable_o))->co_flags;
|
||||||
|
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
|
||||||
|
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
|
||||||
|
tstate, (PyFunctionObject *)PyStackRef_AsPyObjectSteal(callable), locals,
|
||||||
|
args, positional_args, kwnames_o
|
||||||
|
);
|
||||||
|
PyStackRef_CLOSE(kwnames);
|
||||||
|
// Manipulate stack directly since we leave using DISPATCH_INLINED().
|
||||||
|
STACK_SHRINK(oparg + 3);
|
||||||
|
// The frame has stolen all the arguments from the stack,
|
||||||
|
// so there is no need to clean them up.
|
||||||
|
if (new_frame == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert(next_instr - this_instr == 1);
|
||||||
|
frame->return_offset = 1;
|
||||||
|
DISPATCH_INLINED(new_frame);
|
||||||
|
}
|
||||||
|
/* Callable is not a normal Python function */
|
||||||
|
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
|
||||||
|
if (CONVERSION_FAILED(args_o)) {
|
||||||
|
PyStackRef_CLOSE(callable);
|
||||||
|
PyStackRef_CLOSE(self_or_null);
|
||||||
|
for (int _i = oparg; --_i >= 0;) {
|
||||||
|
PyStackRef_CLOSE(args[_i]);
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(kwnames);
|
||||||
|
if (true) {
|
||||||
|
stack_pointer += -3 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyObject *res_o = PyObject_Vectorcall(
|
||||||
|
callable_o, args_o,
|
||||||
|
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||||
|
kwnames_o);
|
||||||
|
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
||||||
|
if (opcode == INSTRUMENTED_CALL_KW) {
|
||||||
|
PyObject *arg = total_args == 0 ?
|
||||||
|
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(args[0]);
|
||||||
|
if (res_o == NULL) {
|
||||||
|
_Py_call_instrumentation_exc2(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||||
|
frame, this_instr, callable_o, arg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||||
|
frame, this_instr, callable_o, arg);
|
||||||
|
if (err < 0) {
|
||||||
|
Py_CLEAR(res_o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(kwnames);
|
||||||
|
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
PyStackRef_CLOSE(callable);
|
PyStackRef_CLOSE(callable);
|
||||||
PyStackRef_CLOSE(self_or_null);
|
for (int i = 0; i < total_args; i++) {
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
PyStackRef_CLOSE(args[i]);
|
||||||
PyStackRef_CLOSE(args[_i]);
|
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(kwnames);
|
if (res_o == NULL) {
|
||||||
if (true) {
|
|
||||||
stack_pointer += -3 - oparg;
|
stack_pointer += -3 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||||
}
|
}
|
||||||
PyObject *res_o = PyObject_Vectorcall(
|
// _CHECK_PERIODIC
|
||||||
callable_o, args_o,
|
{
|
||||||
positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
|
||||||
kwnames_o);
|
QSBR_QUIESCENT_STATE(tstate); \
|
||||||
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
|
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
|
||||||
if (opcode == INSTRUMENTED_CALL_KW) {
|
int err = _Py_HandlePending(tstate);
|
||||||
PyObject *arg = total_args == 0 ?
|
if (err != 0) {
|
||||||
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(args[0]);
|
stack_pointer[-3 - oparg] = res;
|
||||||
if (res_o == NULL) {
|
stack_pointer += -2 - oparg;
|
||||||
_Py_call_instrumentation_exc2(
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
tstate, PY_MONITORING_EVENT_C_RAISE,
|
goto error;
|
||||||
frame, this_instr, callable_o, arg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int err = _Py_call_instrumentation_2args(
|
|
||||||
tstate, PY_MONITORING_EVENT_C_RETURN,
|
|
||||||
frame, this_instr, callable_o, arg);
|
|
||||||
if (err < 0) {
|
|
||||||
Py_CLEAR(res_o);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PyStackRef_CLOSE(kwnames);
|
|
||||||
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
|
||||||
PyStackRef_CLOSE(callable);
|
|
||||||
for (int i = 0; i < total_args; i++) {
|
|
||||||
PyStackRef_CLOSE(args[i]);
|
|
||||||
}
|
|
||||||
if (res_o == NULL) {
|
|
||||||
stack_pointer += -3 - oparg;
|
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
|
||||||
stack_pointer[-3 - oparg] = res;
|
stack_pointer[-3 - oparg] = res;
|
||||||
stack_pointer += -2 - oparg;
|
stack_pointer += -2 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1912,11 +1994,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1983,11 +2075,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2041,11 +2143,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2102,11 +2214,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2175,11 +2297,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2369,11 +2501,16 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) goto pop_2_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-3] = res;
|
stack_pointer[-3] = res;
|
||||||
stack_pointer += -2;
|
stack_pointer += -2;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2405,11 +2542,16 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) goto pop_2_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-3] = res;
|
stack_pointer[-3] = res;
|
||||||
stack_pointer += -2;
|
stack_pointer += -2;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3736,11 +3878,21 @@
|
||||||
}
|
}
|
||||||
// _CHECK_PERIODIC
|
// _CHECK_PERIODIC
|
||||||
{
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) {
|
||||||
|
stack_pointer[-2 - oparg] = res;
|
||||||
|
stack_pointer += -1 - oparg;
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-2 - oparg] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -1 - oparg;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
CHECK_EVAL_BREAKER();
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3872,8 +4024,19 @@
|
||||||
next_instr += 2;
|
next_instr += 2;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_JUMP_BACKWARD);
|
INSTRUCTION_STATS(INSTRUMENTED_JUMP_BACKWARD);
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
CHECK_EVAL_BREAKER();
|
// _CHECK_PERIODIC
|
||||||
INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
|
{
|
||||||
|
_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);
|
||||||
|
if (err != 0) goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// _MONITOR_JUMP_BACKWARD
|
||||||
|
{
|
||||||
|
INSTRUMENTED_JUMP(this_instr, next_instr - oparg, PY_MONITORING_EVENT_JUMP);
|
||||||
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4018,19 +4181,34 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 1;
|
next_instr += 1;
|
||||||
INSTRUCTION_STATS(INSTRUMENTED_RESUME);
|
INSTRUCTION_STATS(INSTRUMENTED_RESUME);
|
||||||
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
// _MAYBE_INSTRUMENT
|
||||||
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version);
|
{
|
||||||
if (code_version != global_version && tstate->tracing == 0) {
|
if (tstate->tracing == 0) {
|
||||||
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
||||||
if (err) {
|
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version);
|
||||||
goto error;
|
if (code_version != global_version) {
|
||||||
|
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
||||||
|
if (err) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
next_instr = this_instr;
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
next_instr = this_instr;
|
|
||||||
}
|
}
|
||||||
else {
|
// _CHECK_PERIODIC_IF_NOT_YIELD_FROM
|
||||||
|
{
|
||||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||||
CHECK_EVAL_BREAKER();
|
_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);
|
||||||
|
if (err != 0) goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// _MONITOR_RESUME
|
||||||
|
{
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int err = _Py_call_instrumentation(
|
int err = _Py_call_instrumentation(
|
||||||
tstate, oparg > 0, frame, this_instr);
|
tstate, oparg > 0, frame, this_instr);
|
||||||
|
@ -4039,7 +4217,6 @@
|
||||||
if (frame->instr_ptr != this_instr) {
|
if (frame->instr_ptr != this_instr) {
|
||||||
/* Instrumentation has jumped */
|
/* Instrumentation has jumped */
|
||||||
next_instr = frame->instr_ptr;
|
next_instr = frame->instr_ptr;
|
||||||
DISPATCH();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
|
@ -4244,37 +4421,49 @@
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
next_instr += 2;
|
next_instr += 2;
|
||||||
INSTRUCTION_STATS(JUMP_BACKWARD);
|
INSTRUCTION_STATS(JUMP_BACKWARD);
|
||||||
/* Skip 1 cache entry */
|
// _CHECK_PERIODIC
|
||||||
CHECK_EVAL_BREAKER();
|
{
|
||||||
assert(oparg <= INSTR_OFFSET());
|
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
|
||||||
JUMPBY(-oparg);
|
QSBR_QUIESCENT_STATE(tstate); \
|
||||||
#ifdef _Py_TIER2
|
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
|
||||||
#if ENABLE_SPECIALIZATION
|
int err = _Py_HandlePending(tstate);
|
||||||
_Py_BackoffCounter counter = this_instr[1].counter;
|
if (err != 0) goto error;
|
||||||
if (backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD) {
|
|
||||||
_Py_CODEUNIT *start = this_instr;
|
|
||||||
/* Back up over EXTENDED_ARGs so optimizer sees the whole instruction */
|
|
||||||
while (oparg > 255) {
|
|
||||||
oparg >>= 8;
|
|
||||||
start--;
|
|
||||||
}
|
}
|
||||||
_PyExecutorObject *executor;
|
}
|
||||||
int optimized = _PyOptimizer_Optimize(frame, start, stack_pointer, &executor, 0);
|
// _JUMP_BACKWARD
|
||||||
if (optimized < 0) goto error;
|
{
|
||||||
if (optimized) {
|
uint16_t the_counter = read_u16(&this_instr[1].cache);
|
||||||
assert(tstate->previous_executor == NULL);
|
(void)the_counter;
|
||||||
tstate->previous_executor = Py_None;
|
assert(oparg <= INSTR_OFFSET());
|
||||||
GOTO_TIER_TWO(executor);
|
JUMPBY(-oparg);
|
||||||
|
#ifdef _Py_TIER2
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
_Py_BackoffCounter counter = this_instr[1].counter;
|
||||||
|
if (backoff_counter_triggers(counter) && this_instr->op.code == JUMP_BACKWARD) {
|
||||||
|
_Py_CODEUNIT *start = this_instr;
|
||||||
|
/* Back up over EXTENDED_ARGs so optimizer sees the whole instruction */
|
||||||
|
while (oparg > 255) {
|
||||||
|
oparg >>= 8;
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
_PyExecutorObject *executor;
|
||||||
|
int optimized = _PyOptimizer_Optimize(frame, start, stack_pointer, &executor, 0);
|
||||||
|
if (optimized < 0) goto error;
|
||||||
|
if (optimized) {
|
||||||
|
assert(tstate->previous_executor == NULL);
|
||||||
|
tstate->previous_executor = Py_None;
|
||||||
|
GOTO_TIER_TWO(executor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this_instr[1].counter = restart_backoff_counter(counter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this_instr[1].counter = restart_backoff_counter(counter);
|
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
||||||
}
|
}
|
||||||
|
#endif /* ENABLE_SPECIALIZATION */
|
||||||
|
#endif /* _Py_TIER2 */
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
ADVANCE_ADAPTIVE_COUNTER(this_instr[1].counter);
|
|
||||||
}
|
|
||||||
#endif /* ENABLE_SPECIALIZATION */
|
|
||||||
#endif /* _Py_TIER2 */
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5889,32 +6078,39 @@
|
||||||
PREDICTED(RESUME);
|
PREDICTED(RESUME);
|
||||||
_Py_CODEUNIT *this_instr = next_instr - 1;
|
_Py_CODEUNIT *this_instr = next_instr - 1;
|
||||||
(void)this_instr;
|
(void)this_instr;
|
||||||
assert(frame == tstate->current_frame);
|
// _MAYBE_INSTRUMENT
|
||||||
if (tstate->tracing == 0) {
|
{
|
||||||
uintptr_t global_version =
|
if (tstate->tracing == 0) {
|
||||||
_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) &
|
uintptr_t global_version = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & ~_PY_EVAL_EVENTS_MASK;
|
||||||
~_PY_EVAL_EVENTS_MASK;
|
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(_PyFrame_GetCode(frame)->_co_instrumentation_version);
|
||||||
PyCodeObject* code = _PyFrame_GetCode(frame);
|
if (code_version != global_version) {
|
||||||
uintptr_t code_version = FT_ATOMIC_LOAD_UINTPTR_ACQUIRE(code->_co_instrumentation_version);
|
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
||||||
assert((code_version & 255) == 0);
|
if (err) {
|
||||||
if (code_version != global_version) {
|
goto error;
|
||||||
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
|
}
|
||||||
if (err) goto error;
|
next_instr = this_instr;
|
||||||
next_instr = this_instr;
|
DISPATCH();
|
||||||
DISPATCH();
|
}
|
||||||
}
|
|
||||||
assert(this_instr->op.code == RESUME ||
|
|
||||||
this_instr->op.code == RESUME_CHECK ||
|
|
||||||
this_instr->op.code == INSTRUMENTED_RESUME ||
|
|
||||||
this_instr->op.code == ENTER_EXECUTOR);
|
|
||||||
if (this_instr->op.code == RESUME) {
|
|
||||||
#if ENABLE_SPECIALIZATION
|
|
||||||
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
|
|
||||||
#endif /* ENABLE_SPECIALIZATION */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
// _QUICKEN_RESUME
|
||||||
CHECK_EVAL_BREAKER();
|
{
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
if (tstate->tracing == 0 && this_instr->op.code == RESUME) {
|
||||||
|
FT_ATOMIC_STORE_UINT8_RELAXED(this_instr->op.code, RESUME_CHECK);
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_SPECIALIZATION */
|
||||||
|
}
|
||||||
|
// _CHECK_PERIODIC_IF_NOT_YIELD_FROM
|
||||||
|
{
|
||||||
|
if ((oparg & RESUME_OPARG_LOCATION_MASK) < RESUME_AFTER_YIELD_FROM) {
|
||||||
|
_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);
|
||||||
|
if (err != 0) goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
@ -7108,4 +7304,98 @@
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TARGET(_DO_CALL_FUNCTION_EX) {
|
||||||
|
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
|
||||||
|
(void)this_instr;
|
||||||
|
next_instr += 1;
|
||||||
|
INSTRUCTION_STATS(_DO_CALL_FUNCTION_EX);
|
||||||
|
_PyStackRef func_st;
|
||||||
|
_PyStackRef callargs_st;
|
||||||
|
_PyStackRef kwargs_st = PyStackRef_NULL;
|
||||||
|
_PyStackRef result;
|
||||||
|
if (oparg & 1) { kwargs_st = stack_pointer[-(oparg & 1)]; }
|
||||||
|
callargs_st = stack_pointer[-1 - (oparg & 1)];
|
||||||
|
func_st = stack_pointer[-3 - (oparg & 1)];
|
||||||
|
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
||||||
|
PyObject *callargs = PyStackRef_AsPyObjectBorrow(callargs_st);
|
||||||
|
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
||||||
|
// DICT_MERGE is called before this opcode if there are kwargs.
|
||||||
|
// It converts all dict subtypes in kwargs into regular dicts.
|
||||||
|
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||||
|
if (!PyTuple_CheckExact(callargs)) {
|
||||||
|
int err = check_args_iterable(tstate, func, callargs);
|
||||||
|
if (err < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
PyObject *tuple = PySequence_Tuple(callargs);
|
||||||
|
if (tuple == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(callargs_st);
|
||||||
|
callargs_st = PyStackRef_FromPyObjectSteal(tuple);
|
||||||
|
callargs = tuple;
|
||||||
|
}
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func);
|
||||||
|
if (opcode == INSTRUMENTED_CALL_FUNCTION_EX) {
|
||||||
|
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
|
||||||
|
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_CALL,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
if (err) goto error;
|
||||||
|
result = PyStackRef_FromPyObjectSteal(PyObject_Call(func, callargs, kwargs));
|
||||||
|
if (!PyFunction_Check(func) && !PyMethod_Check(func)) {
|
||||||
|
if (PyStackRef_IsNull(result)) {
|
||||||
|
_Py_call_instrumentation_exc2(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RAISE,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int err = _Py_call_instrumentation_2args(
|
||||||
|
tstate, PY_MONITORING_EVENT_C_RETURN,
|
||||||
|
frame, this_instr, func, arg);
|
||||||
|
if (err < 0) {
|
||||||
|
PyStackRef_CLEAR(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Py_TYPE(func) == &PyFunction_Type &&
|
||||||
|
tstate->interp->eval_frame == NULL &&
|
||||||
|
((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) {
|
||||||
|
assert(PyTuple_CheckExact(callargs));
|
||||||
|
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
|
||||||
|
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
|
||||||
|
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
|
||||||
|
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate,
|
||||||
|
(PyFunctionObject *)PyStackRef_AsPyObjectSteal(func_st), locals,
|
||||||
|
nargs, callargs, kwargs);
|
||||||
|
// Need to manually shrink the stack since we exit with DISPATCH_INLINED.
|
||||||
|
STACK_SHRINK(oparg + 3);
|
||||||
|
if (new_frame == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
assert(next_instr - this_instr == 1);
|
||||||
|
frame->return_offset = 1;
|
||||||
|
DISPATCH_INLINED(new_frame);
|
||||||
|
}
|
||||||
|
result = PyStackRef_FromPyObjectSteal(PyObject_Call(func, callargs, kwargs));
|
||||||
|
}
|
||||||
|
PyStackRef_CLOSE(func_st);
|
||||||
|
PyStackRef_CLOSE(callargs_st);
|
||||||
|
PyStackRef_XCLOSE(kwargs_st);
|
||||||
|
assert(PyStackRef_AsPyObjectBorrow(PEEK(2 + (oparg & 1))) == NULL);
|
||||||
|
if (PyStackRef_IsNull(result)) {
|
||||||
|
stack_pointer += -3 - (oparg & 1);
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
stack_pointer[-3 - (oparg & 1)] = result;
|
||||||
|
stack_pointer += -2 - (oparg & 1);
|
||||||
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
#undef TIER_ONE
|
#undef TIER_ONE
|
||||||
|
|
6
Python/opcode_targets.h
generated
6
Python/opcode_targets.h
generated
|
@ -115,7 +115,7 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_UNPACK_EX,
|
&&TARGET_UNPACK_EX,
|
||||||
&&TARGET_UNPACK_SEQUENCE,
|
&&TARGET_UNPACK_SEQUENCE,
|
||||||
&&TARGET_YIELD_VALUE,
|
&&TARGET_YIELD_VALUE,
|
||||||
&&_unknown_opcode,
|
&&TARGET__DO_CALL_FUNCTION_EX,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
|
@ -235,7 +235,6 @@ static void *opcode_targets[256] = {
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&_unknown_opcode,
|
&&_unknown_opcode,
|
||||||
&&TARGET_INSTRUMENTED_RESUME,
|
|
||||||
&&TARGET_INSTRUMENTED_END_FOR,
|
&&TARGET_INSTRUMENTED_END_FOR,
|
||||||
&&TARGET_INSTRUMENTED_END_SEND,
|
&&TARGET_INSTRUMENTED_END_SEND,
|
||||||
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
|
&&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR,
|
||||||
|
@ -244,15 +243,16 @@ static void *opcode_targets[256] = {
|
||||||
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
|
&&TARGET_INSTRUMENTED_CALL_FUNCTION_EX,
|
||||||
&&TARGET_INSTRUMENTED_INSTRUCTION,
|
&&TARGET_INSTRUMENTED_INSTRUCTION,
|
||||||
&&TARGET_INSTRUMENTED_JUMP_FORWARD,
|
&&TARGET_INSTRUMENTED_JUMP_FORWARD,
|
||||||
&&TARGET_INSTRUMENTED_JUMP_BACKWARD,
|
|
||||||
&&TARGET_INSTRUMENTED_POP_JUMP_IF_TRUE,
|
&&TARGET_INSTRUMENTED_POP_JUMP_IF_TRUE,
|
||||||
&&TARGET_INSTRUMENTED_POP_JUMP_IF_FALSE,
|
&&TARGET_INSTRUMENTED_POP_JUMP_IF_FALSE,
|
||||||
&&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE,
|
&&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE,
|
||||||
&&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
|
&&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
|
||||||
|
&&TARGET_INSTRUMENTED_RESUME,
|
||||||
&&TARGET_INSTRUMENTED_RETURN_VALUE,
|
&&TARGET_INSTRUMENTED_RETURN_VALUE,
|
||||||
&&TARGET_INSTRUMENTED_RETURN_CONST,
|
&&TARGET_INSTRUMENTED_RETURN_CONST,
|
||||||
&&TARGET_INSTRUMENTED_YIELD_VALUE,
|
&&TARGET_INSTRUMENTED_YIELD_VALUE,
|
||||||
&&TARGET_INSTRUMENTED_CALL,
|
&&TARGET_INSTRUMENTED_CALL,
|
||||||
|
&&TARGET_INSTRUMENTED_JUMP_BACKWARD,
|
||||||
&&TARGET_INSTRUMENTED_LINE,
|
&&TARGET_INSTRUMENTED_LINE,
|
||||||
&&TARGET_ENTER_EXECUTOR,
|
&&TARGET_ENTER_EXECUTOR,
|
||||||
};
|
};
|
||||||
|
|
22
Python/optimizer_cases.c.h
generated
22
Python/optimizer_cases.c.h
generated
|
@ -7,11 +7,21 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case _CHECK_PERIODIC: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _CHECK_PERIODIC_IF_NOT_YIELD_FROM: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* _QUICKEN_RESUME is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _RESUME_CHECK: {
|
case _RESUME_CHECK: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _INSTRUMENTED_RESUME is not a viable micro-op for tier 2 */
|
/* _MONITOR_RESUME is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _LOAD_FAST_CHECK: {
|
case _LOAD_FAST_CHECK: {
|
||||||
_Py_UopsSymbol *value;
|
_Py_UopsSymbol *value;
|
||||||
|
@ -1644,10 +1654,6 @@
|
||||||
|
|
||||||
/* _DO_CALL is not a viable micro-op for tier 2 */
|
/* _DO_CALL is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _CHECK_PERIODIC: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _MONITOR_CALL is not a viable micro-op for tier 2 */
|
/* _MONITOR_CALL is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _PY_FRAME_GENERAL: {
|
case _PY_FRAME_GENERAL: {
|
||||||
|
@ -1966,11 +1972,11 @@
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 */
|
/* _INSTRUMENTED_CALL_KW is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
/* _CALL_KW is not a viable micro-op for tier 2 */
|
/* _DO_CALL_KW is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
|
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
/* _CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
|
/* __DO_CALL_FUNCTION_EX is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _MAKE_FUNCTION: {
|
case _MAKE_FUNCTION: {
|
||||||
_Py_UopsSymbol *func;
|
_Py_UopsSymbol *func;
|
||||||
|
@ -2100,7 +2106,7 @@
|
||||||
|
|
||||||
/* _INSTRUMENTED_JUMP_FORWARD is not a viable micro-op for tier 2 */
|
/* _INSTRUMENTED_JUMP_FORWARD is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
/* _INSTRUMENTED_JUMP_BACKWARD is not a viable micro-op for tier 2 */
|
/* _MONITOR_JUMP_BACKWARD is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
/* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */
|
/* _INSTRUMENTED_POP_JUMP_IF_TRUE is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@ class Properties:
|
||||||
oparg: bool
|
oparg: bool
|
||||||
jumps: bool
|
jumps: bool
|
||||||
eval_breaker: bool
|
eval_breaker: bool
|
||||||
ends_with_eval_breaker: bool
|
|
||||||
needs_this: bool
|
needs_this: bool
|
||||||
always_exits: bool
|
always_exits: bool
|
||||||
stores_sp: bool
|
stores_sp: bool
|
||||||
|
@ -44,7 +43,6 @@ class Properties:
|
||||||
oparg=any(p.oparg for p in properties),
|
oparg=any(p.oparg for p in properties),
|
||||||
jumps=any(p.jumps for p in properties),
|
jumps=any(p.jumps for p in properties),
|
||||||
eval_breaker=any(p.eval_breaker for p in properties),
|
eval_breaker=any(p.eval_breaker for p in properties),
|
||||||
ends_with_eval_breaker=any(p.ends_with_eval_breaker for p in properties),
|
|
||||||
needs_this=any(p.needs_this for p in properties),
|
needs_this=any(p.needs_this for p in properties),
|
||||||
always_exits=any(p.always_exits for p in properties),
|
always_exits=any(p.always_exits for p in properties),
|
||||||
stores_sp=any(p.stores_sp for p in properties),
|
stores_sp=any(p.stores_sp for p in properties),
|
||||||
|
@ -70,7 +68,6 @@ SKIP_PROPERTIES = Properties(
|
||||||
oparg=False,
|
oparg=False,
|
||||||
jumps=False,
|
jumps=False,
|
||||||
eval_breaker=False,
|
eval_breaker=False,
|
||||||
ends_with_eval_breaker=False,
|
|
||||||
needs_this=False,
|
needs_this=False,
|
||||||
always_exits=False,
|
always_exits=False,
|
||||||
stores_sp=False,
|
stores_sp=False,
|
||||||
|
@ -194,13 +191,6 @@ class Uop:
|
||||||
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"
|
||||||
if self.properties.eval_breaker:
|
|
||||||
if self.properties.error_with_pop or self.properties.error_without_pop:
|
|
||||||
return "has error handling and eval-breaker check"
|
|
||||||
if self.properties.side_exit:
|
|
||||||
return "exits and eval-breaker check"
|
|
||||||
if self.properties.deopts:
|
|
||||||
return "deopts and eval-breaker check"
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def is_viable(self) -> bool:
|
def is_viable(self) -> bool:
|
||||||
|
@ -587,10 +577,6 @@ EXITS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def eval_breaker_at_end(op: parser.InstDef) -> bool:
|
|
||||||
return op.tokens[-5].text == "CHECK_EVAL_BREAKER"
|
|
||||||
|
|
||||||
|
|
||||||
def always_exits(op: parser.InstDef) -> bool:
|
def always_exits(op: parser.InstDef) -> bool:
|
||||||
depth = 0
|
depth = 0
|
||||||
tkn_iter = iter(op.tokens)
|
tkn_iter = iter(op.tokens)
|
||||||
|
@ -678,8 +664,7 @@ def compute_properties(op: parser.InstDef) -> Properties:
|
||||||
side_exit=exits_if,
|
side_exit=exits_if,
|
||||||
oparg=oparg_used(op),
|
oparg=oparg_used(op),
|
||||||
jumps=variable_used(op, "JUMPBY"),
|
jumps=variable_used(op, "JUMPBY"),
|
||||||
eval_breaker=variable_used(op, "CHECK_EVAL_BREAKER"),
|
eval_breaker="CHECK_PERIODIC" in op.name,
|
||||||
ends_with_eval_breaker=eval_breaker_at_end(op),
|
|
||||||
needs_this=variable_used(op, "this_instr"),
|
needs_this=variable_used(op, "this_instr"),
|
||||||
always_exits=always_exits(op),
|
always_exits=always_exits(op),
|
||||||
stores_sp=variable_used(op, "SYNC_SP"),
|
stores_sp=variable_used(op, "SYNC_SP"),
|
||||||
|
|
|
@ -75,7 +75,6 @@ class Emitter:
|
||||||
"ERROR_IF": self.error_if,
|
"ERROR_IF": self.error_if,
|
||||||
"ERROR_NO_POP": self.error_no_pop,
|
"ERROR_NO_POP": self.error_no_pop,
|
||||||
"DECREF_INPUTS": self.decref_inputs,
|
"DECREF_INPUTS": self.decref_inputs,
|
||||||
"CHECK_EVAL_BREAKER": self.check_eval_breaker,
|
|
||||||
"SYNC_SP": self.sync_sp,
|
"SYNC_SP": self.sync_sp,
|
||||||
"PyStackRef_FromPyObjectNew": self.py_stack_ref_from_py_object_new,
|
"PyStackRef_FromPyObjectNew": self.py_stack_ref_from_py_object_new,
|
||||||
}
|
}
|
||||||
|
@ -190,20 +189,6 @@ class Emitter:
|
||||||
next(tkn_iter)
|
next(tkn_iter)
|
||||||
stack.flush(self.out)
|
stack.flush(self.out)
|
||||||
|
|
||||||
def check_eval_breaker(
|
|
||||||
self,
|
|
||||||
tkn: Token,
|
|
||||||
tkn_iter: Iterator[Token],
|
|
||||||
uop: Uop,
|
|
||||||
stack: Stack,
|
|
||||||
inst: Instruction | None,
|
|
||||||
) -> None:
|
|
||||||
next(tkn_iter)
|
|
||||||
next(tkn_iter)
|
|
||||||
next(tkn_iter)
|
|
||||||
if not uop.properties.ends_with_eval_breaker:
|
|
||||||
self.out.emit_at("CHECK_EVAL_BREAKER();", tkn)
|
|
||||||
|
|
||||||
def py_stack_ref_from_py_object_new(
|
def py_stack_ref_from_py_object_new(
|
||||||
self,
|
self,
|
||||||
tkn: Token,
|
tkn: Token,
|
||||||
|
|
|
@ -201,8 +201,6 @@ def generate_tier1(
|
||||||
out.start_line()
|
out.start_line()
|
||||||
if not inst.parts[-1].properties.always_exits:
|
if not inst.parts[-1].properties.always_exits:
|
||||||
stack.flush(out)
|
stack.flush(out)
|
||||||
if inst.parts[-1].properties.ends_with_eval_breaker:
|
|
||||||
out.emit("CHECK_EVAL_BREAKER();\n")
|
|
||||||
out.emit("DISPATCH();\n")
|
out.emit("DISPATCH();\n")
|
||||||
out.start_line()
|
out.start_line()
|
||||||
out.emit("}")
|
out.emit("}")
|
||||||
|
|
|
@ -230,8 +230,6 @@ def generate_tier2(
|
||||||
out.start_line()
|
out.start_line()
|
||||||
if not uop.properties.always_exits:
|
if not uop.properties.always_exits:
|
||||||
stack.flush(out)
|
stack.flush(out)
|
||||||
if uop.properties.ends_with_eval_breaker:
|
|
||||||
out.emit("CHECK_EVAL_BREAKER();\n")
|
|
||||||
out.emit("break;\n")
|
out.emit("break;\n")
|
||||||
out.start_line()
|
out.start_line()
|
||||||
out.emit("}")
|
out.emit("}")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue