mirror of https://github.com/python/cpython
GH-118095: Use broader specializations of CALL in tier 1, for better tier 2 support of calls. (GH-118322)
* Add CALL_PY_GENERAL, CALL_BOUND_METHOD_GENERAL and call CALL_NON_PY_GENERAL specializations. * Remove CALL_PY_WITH_DEFAULTS specialization * Use CALL_NON_PY_GENERAL in more cases when otherwise failing to specialize
This commit is contained in:
parent
00da0afa0d
commit
1ab6356ebe
|
@ -318,6 +318,11 @@ PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
|
|||
return (PyGenObject *)(((char *)frame) - offset_in_gen);
|
||||
}
|
||||
|
||||
PyAPI_FUNC(_PyInterpreterFrame *)
|
||||
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, PyObject* const* args,
|
||||
size_t argcount, PyObject *kwnames);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -95,6 +95,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
|||
return 2 + oparg;
|
||||
case CALL_BOUND_METHOD_EXACT_ARGS:
|
||||
return 2 + oparg;
|
||||
case CALL_BOUND_METHOD_GENERAL:
|
||||
return 2 + oparg;
|
||||
case CALL_BUILTIN_CLASS:
|
||||
return 2 + oparg;
|
||||
case CALL_BUILTIN_FAST:
|
||||
|
@ -125,9 +127,11 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
|||
return 2 + oparg;
|
||||
case CALL_METHOD_DESCRIPTOR_O:
|
||||
return 2 + oparg;
|
||||
case CALL_NON_PY_GENERAL:
|
||||
return 2 + oparg;
|
||||
case CALL_PY_EXACT_ARGS:
|
||||
return 2 + oparg;
|
||||
case CALL_PY_WITH_DEFAULTS:
|
||||
case CALL_PY_GENERAL:
|
||||
return 2 + oparg;
|
||||
case CALL_STR_1:
|
||||
return 3;
|
||||
|
@ -524,6 +528,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
|
|||
return 1;
|
||||
case CALL_BOUND_METHOD_EXACT_ARGS:
|
||||
return 0;
|
||||
case CALL_BOUND_METHOD_GENERAL:
|
||||
return 0;
|
||||
case CALL_BUILTIN_CLASS:
|
||||
return 1;
|
||||
case CALL_BUILTIN_FAST:
|
||||
|
@ -554,10 +560,12 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
|
|||
return 1;
|
||||
case CALL_METHOD_DESCRIPTOR_O:
|
||||
return 1;
|
||||
case CALL_NON_PY_GENERAL:
|
||||
return 1;
|
||||
case CALL_PY_EXACT_ARGS:
|
||||
return 0;
|
||||
case CALL_PY_WITH_DEFAULTS:
|
||||
return 1;
|
||||
case CALL_PY_GENERAL:
|
||||
return 0;
|
||||
case CALL_STR_1:
|
||||
return 1;
|
||||
case CALL_TUPLE_1:
|
||||
|
@ -985,6 +993,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[268] = {
|
|||
[CALL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
|
||||
[CALL_BOUND_METHOD_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BUILTIN_FAST] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
|
@ -1000,8 +1009,9 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[268] = {
|
|||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_NON_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
|
||||
[CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||
[CALL_PY_GENERAL] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_STR_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_TUPLE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
|
||||
[CALL_TYPE_1] = { true, INSTR_FMT_IBC00, HAS_ARG_FLAG | HAS_DEOPT_FLAG },
|
||||
|
@ -1211,6 +1221,7 @@ _PyOpcode_macro_expansion[256] = {
|
|||
[BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } },
|
||||
[BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, 0, 0 } } },
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = { .nuops = 8, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
|
||||
[CALL_BOUND_METHOD_GENERAL] = { .nuops = 6, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_METHOD_VERSION, 2, 1 }, { _EXPAND_METHOD, 0, 0 }, { _PY_FRAME_GENERAL, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
|
||||
[CALL_BUILTIN_CLASS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_CLASS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_BUILTIN_FAST] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST_WITH_KEYWORDS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
|
@ -1223,7 +1234,9 @@ _PyOpcode_macro_expansion[256] = {
|
|||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_METHOD_DESCRIPTOR_O] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_O, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_NON_PY_GENERAL] = { .nuops = 3, .uops = { { _CHECK_IS_NOT_PY_CALLABLE, 0, 0 }, { _CALL_NON_PY_GENERAL, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_PY_EXACT_ARGS] = { .nuops = 6, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_EXACT_ARGS, 2, 1 }, { _CHECK_STACK_SPACE, 0, 0 }, { _INIT_CALL_PY_EXACT_ARGS, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
|
||||
[CALL_PY_GENERAL] = { .nuops = 5, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _PY_FRAME_GENERAL, 0, 0 }, { _SAVE_RETURN_OFFSET, 7, 3 }, { _PUSH_FRAME, 0, 0 } } },
|
||||
[CALL_STR_1] = { .nuops = 2, .uops = { { _CALL_STR_1, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_TUPLE_1] = { .nuops = 2, .uops = { { _CALL_TUPLE_1, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||
[CALL_TYPE_1] = { .nuops = 1, .uops = { { _CALL_TYPE_1, 0, 0 } } },
|
||||
|
@ -1383,6 +1396,7 @@ const char *_PyOpcode_OpName[268] = {
|
|||
[CALL] = "CALL",
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = "CALL_ALLOC_AND_ENTER_INIT",
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS",
|
||||
[CALL_BOUND_METHOD_GENERAL] = "CALL_BOUND_METHOD_GENERAL",
|
||||
[CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS",
|
||||
[CALL_BUILTIN_FAST] = "CALL_BUILTIN_FAST",
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS",
|
||||
|
@ -1398,8 +1412,9 @@ const char *_PyOpcode_OpName[268] = {
|
|||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = "CALL_METHOD_DESCRIPTOR_NOARGS",
|
||||
[CALL_METHOD_DESCRIPTOR_O] = "CALL_METHOD_DESCRIPTOR_O",
|
||||
[CALL_NON_PY_GENERAL] = "CALL_NON_PY_GENERAL",
|
||||
[CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS",
|
||||
[CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS",
|
||||
[CALL_PY_GENERAL] = "CALL_PY_GENERAL",
|
||||
[CALL_STR_1] = "CALL_STR_1",
|
||||
[CALL_TUPLE_1] = "CALL_TUPLE_1",
|
||||
[CALL_TYPE_1] = "CALL_TYPE_1",
|
||||
|
@ -1636,6 +1651,7 @@ const uint8_t _PyOpcode_Deopt[256] = {
|
|||
[CALL] = CALL,
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = CALL,
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
|
||||
[CALL_BOUND_METHOD_GENERAL] = CALL,
|
||||
[CALL_BUILTIN_CLASS] = CALL,
|
||||
[CALL_BUILTIN_FAST] = CALL,
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
|
||||
|
@ -1651,8 +1667,9 @@ const uint8_t _PyOpcode_Deopt[256] = {
|
|||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = CALL,
|
||||
[CALL_METHOD_DESCRIPTOR_O] = CALL,
|
||||
[CALL_NON_PY_GENERAL] = CALL,
|
||||
[CALL_PY_EXACT_ARGS] = CALL,
|
||||
[CALL_PY_WITH_DEFAULTS] = CALL,
|
||||
[CALL_PY_GENERAL] = CALL,
|
||||
[CALL_STR_1] = CALL,
|
||||
[CALL_TUPLE_1] = CALL,
|
||||
[CALL_TYPE_1] = CALL,
|
||||
|
@ -1852,8 +1869,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
|
|||
case 146: \
|
||||
case 147: \
|
||||
case 148: \
|
||||
case 221: \
|
||||
case 222: \
|
||||
case 223: \
|
||||
case 224: \
|
||||
case 225: \
|
||||
|
|
|
@ -51,32 +51,35 @@ extern "C" {
|
|||
#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 317
|
||||
#define _CALL_METHOD_DESCRIPTOR_NOARGS 318
|
||||
#define _CALL_METHOD_DESCRIPTOR_O 319
|
||||
#define _CALL_PY_WITH_DEFAULTS CALL_PY_WITH_DEFAULTS
|
||||
#define _CALL_STR_1 320
|
||||
#define _CALL_TUPLE_1 321
|
||||
#define _CALL_NON_PY_GENERAL 320
|
||||
#define _CALL_STR_1 321
|
||||
#define _CALL_TUPLE_1 322
|
||||
#define _CALL_TYPE_1 CALL_TYPE_1
|
||||
#define _CHECK_ATTR_CLASS 322
|
||||
#define _CHECK_ATTR_METHOD_LAZY_DICT 323
|
||||
#define _CHECK_ATTR_MODULE 324
|
||||
#define _CHECK_ATTR_WITH_HINT 325
|
||||
#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 326
|
||||
#define _CHECK_ATTR_CLASS 323
|
||||
#define _CHECK_ATTR_METHOD_LAZY_DICT 324
|
||||
#define _CHECK_ATTR_MODULE 325
|
||||
#define _CHECK_ATTR_WITH_HINT 326
|
||||
#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 327
|
||||
#define _CHECK_EG_MATCH CHECK_EG_MATCH
|
||||
#define _CHECK_EXC_MATCH CHECK_EXC_MATCH
|
||||
#define _CHECK_FUNCTION 327
|
||||
#define _CHECK_FUNCTION_EXACT_ARGS 328
|
||||
#define _CHECK_MANAGED_OBJECT_HAS_VALUES 329
|
||||
#define _CHECK_PEP_523 330
|
||||
#define _CHECK_PERIODIC 331
|
||||
#define _CHECK_STACK_SPACE 332
|
||||
#define _CHECK_STACK_SPACE_OPERAND 333
|
||||
#define _CHECK_VALIDITY 334
|
||||
#define _CHECK_VALIDITY_AND_SET_IP 335
|
||||
#define _COLD_EXIT 336
|
||||
#define _COMPARE_OP 337
|
||||
#define _COMPARE_OP_FLOAT 338
|
||||
#define _COMPARE_OP_INT 339
|
||||
#define _COMPARE_OP_STR 340
|
||||
#define _CONTAINS_OP 341
|
||||
#define _CHECK_FUNCTION 328
|
||||
#define _CHECK_FUNCTION_EXACT_ARGS 329
|
||||
#define _CHECK_FUNCTION_VERSION 330
|
||||
#define _CHECK_IS_NOT_PY_CALLABLE 331
|
||||
#define _CHECK_MANAGED_OBJECT_HAS_VALUES 332
|
||||
#define _CHECK_METHOD_VERSION 333
|
||||
#define _CHECK_PEP_523 334
|
||||
#define _CHECK_PERIODIC 335
|
||||
#define _CHECK_STACK_SPACE 336
|
||||
#define _CHECK_STACK_SPACE_OPERAND 337
|
||||
#define _CHECK_VALIDITY 338
|
||||
#define _CHECK_VALIDITY_AND_SET_IP 339
|
||||
#define _COLD_EXIT 340
|
||||
#define _COMPARE_OP 341
|
||||
#define _COMPARE_OP_FLOAT 342
|
||||
#define _COMPARE_OP_INT 343
|
||||
#define _COMPARE_OP_STR 344
|
||||
#define _CONTAINS_OP 345
|
||||
#define _CONTAINS_OP_DICT CONTAINS_OP_DICT
|
||||
#define _CONTAINS_OP_SET CONTAINS_OP_SET
|
||||
#define _CONVERT_VALUE CONVERT_VALUE
|
||||
|
@ -88,52 +91,53 @@ extern "C" {
|
|||
#define _DELETE_GLOBAL DELETE_GLOBAL
|
||||
#define _DELETE_NAME DELETE_NAME
|
||||
#define _DELETE_SUBSCR DELETE_SUBSCR
|
||||
#define _DEOPT 342
|
||||
#define _DEOPT 346
|
||||
#define _DICT_MERGE DICT_MERGE
|
||||
#define _DICT_UPDATE DICT_UPDATE
|
||||
#define _DYNAMIC_EXIT 343
|
||||
#define _DYNAMIC_EXIT 347
|
||||
#define _END_SEND END_SEND
|
||||
#define _ERROR_POP_N 344
|
||||
#define _ERROR_POP_N 348
|
||||
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
|
||||
#define _FATAL_ERROR 345
|
||||
#define _EXPAND_METHOD 349
|
||||
#define _FATAL_ERROR 350
|
||||
#define _FORMAT_SIMPLE FORMAT_SIMPLE
|
||||
#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
|
||||
#define _FOR_ITER 346
|
||||
#define _FOR_ITER_GEN_FRAME 347
|
||||
#define _FOR_ITER_TIER_TWO 348
|
||||
#define _FOR_ITER 351
|
||||
#define _FOR_ITER_GEN_FRAME 352
|
||||
#define _FOR_ITER_TIER_TWO 353
|
||||
#define _GET_AITER GET_AITER
|
||||
#define _GET_ANEXT GET_ANEXT
|
||||
#define _GET_AWAITABLE GET_AWAITABLE
|
||||
#define _GET_ITER GET_ITER
|
||||
#define _GET_LEN GET_LEN
|
||||
#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
|
||||
#define _GUARD_BOTH_FLOAT 349
|
||||
#define _GUARD_BOTH_INT 350
|
||||
#define _GUARD_BOTH_UNICODE 351
|
||||
#define _GUARD_BUILTINS_VERSION 352
|
||||
#define _GUARD_DORV_NO_DICT 353
|
||||
#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 354
|
||||
#define _GUARD_GLOBALS_VERSION 355
|
||||
#define _GUARD_IS_FALSE_POP 356
|
||||
#define _GUARD_IS_NONE_POP 357
|
||||
#define _GUARD_IS_NOT_NONE_POP 358
|
||||
#define _GUARD_IS_TRUE_POP 359
|
||||
#define _GUARD_KEYS_VERSION 360
|
||||
#define _GUARD_NOS_FLOAT 361
|
||||
#define _GUARD_NOS_INT 362
|
||||
#define _GUARD_NOT_EXHAUSTED_LIST 363
|
||||
#define _GUARD_NOT_EXHAUSTED_RANGE 364
|
||||
#define _GUARD_NOT_EXHAUSTED_TUPLE 365
|
||||
#define _GUARD_TOS_FLOAT 366
|
||||
#define _GUARD_TOS_INT 367
|
||||
#define _GUARD_TYPE_VERSION 368
|
||||
#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 369
|
||||
#define _INIT_CALL_PY_EXACT_ARGS 370
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_0 371
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_1 372
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_2 373
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_3 374
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_4 375
|
||||
#define _GUARD_BOTH_FLOAT 354
|
||||
#define _GUARD_BOTH_INT 355
|
||||
#define _GUARD_BOTH_UNICODE 356
|
||||
#define _GUARD_BUILTINS_VERSION 357
|
||||
#define _GUARD_DORV_NO_DICT 358
|
||||
#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 359
|
||||
#define _GUARD_GLOBALS_VERSION 360
|
||||
#define _GUARD_IS_FALSE_POP 361
|
||||
#define _GUARD_IS_NONE_POP 362
|
||||
#define _GUARD_IS_NOT_NONE_POP 363
|
||||
#define _GUARD_IS_TRUE_POP 364
|
||||
#define _GUARD_KEYS_VERSION 365
|
||||
#define _GUARD_NOS_FLOAT 366
|
||||
#define _GUARD_NOS_INT 367
|
||||
#define _GUARD_NOT_EXHAUSTED_LIST 368
|
||||
#define _GUARD_NOT_EXHAUSTED_RANGE 369
|
||||
#define _GUARD_NOT_EXHAUSTED_TUPLE 370
|
||||
#define _GUARD_TOS_FLOAT 371
|
||||
#define _GUARD_TOS_INT 372
|
||||
#define _GUARD_TYPE_VERSION 373
|
||||
#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 374
|
||||
#define _INIT_CALL_PY_EXACT_ARGS 375
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_0 376
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_1 377
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_2 378
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_3 379
|
||||
#define _INIT_CALL_PY_EXACT_ARGS_4 380
|
||||
#define _INSTRUMENTED_CALL INSTRUMENTED_CALL
|
||||
#define _INSTRUMENTED_CALL_FUNCTION_EX INSTRUMENTED_CALL_FUNCTION_EX
|
||||
#define _INSTRUMENTED_CALL_KW INSTRUMENTED_CALL_KW
|
||||
|
@ -150,65 +154,65 @@ extern "C" {
|
|||
#define _INSTRUMENTED_RETURN_CONST INSTRUMENTED_RETURN_CONST
|
||||
#define _INSTRUMENTED_RETURN_VALUE INSTRUMENTED_RETURN_VALUE
|
||||
#define _INSTRUMENTED_YIELD_VALUE INSTRUMENTED_YIELD_VALUE
|
||||
#define _INTERNAL_INCREMENT_OPT_COUNTER 376
|
||||
#define _IS_NONE 377
|
||||
#define _INTERNAL_INCREMENT_OPT_COUNTER 381
|
||||
#define _IS_NONE 382
|
||||
#define _IS_OP IS_OP
|
||||
#define _ITER_CHECK_LIST 378
|
||||
#define _ITER_CHECK_RANGE 379
|
||||
#define _ITER_CHECK_TUPLE 380
|
||||
#define _ITER_JUMP_LIST 381
|
||||
#define _ITER_JUMP_RANGE 382
|
||||
#define _ITER_JUMP_TUPLE 383
|
||||
#define _ITER_NEXT_LIST 384
|
||||
#define _ITER_NEXT_RANGE 385
|
||||
#define _ITER_NEXT_TUPLE 386
|
||||
#define _JUMP_TO_TOP 387
|
||||
#define _ITER_CHECK_LIST 383
|
||||
#define _ITER_CHECK_RANGE 384
|
||||
#define _ITER_CHECK_TUPLE 385
|
||||
#define _ITER_JUMP_LIST 386
|
||||
#define _ITER_JUMP_RANGE 387
|
||||
#define _ITER_JUMP_TUPLE 388
|
||||
#define _ITER_NEXT_LIST 389
|
||||
#define _ITER_NEXT_RANGE 390
|
||||
#define _ITER_NEXT_TUPLE 391
|
||||
#define _JUMP_TO_TOP 392
|
||||
#define _LIST_APPEND LIST_APPEND
|
||||
#define _LIST_EXTEND LIST_EXTEND
|
||||
#define _LOAD_ASSERTION_ERROR LOAD_ASSERTION_ERROR
|
||||
#define _LOAD_ATTR 388
|
||||
#define _LOAD_ATTR_CLASS 389
|
||||
#define _LOAD_ATTR_CLASS_0 390
|
||||
#define _LOAD_ATTR_CLASS_1 391
|
||||
#define _LOAD_ATTR 393
|
||||
#define _LOAD_ATTR_CLASS 394
|
||||
#define _LOAD_ATTR_CLASS_0 395
|
||||
#define _LOAD_ATTR_CLASS_1 396
|
||||
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE 392
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE_0 393
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE_1 394
|
||||
#define _LOAD_ATTR_METHOD_LAZY_DICT 395
|
||||
#define _LOAD_ATTR_METHOD_NO_DICT 396
|
||||
#define _LOAD_ATTR_METHOD_WITH_VALUES 397
|
||||
#define _LOAD_ATTR_MODULE 398
|
||||
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 399
|
||||
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 400
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE 397
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE_0 398
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE_1 399
|
||||
#define _LOAD_ATTR_METHOD_LAZY_DICT 400
|
||||
#define _LOAD_ATTR_METHOD_NO_DICT 401
|
||||
#define _LOAD_ATTR_METHOD_WITH_VALUES 402
|
||||
#define _LOAD_ATTR_MODULE 403
|
||||
#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 404
|
||||
#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 405
|
||||
#define _LOAD_ATTR_PROPERTY LOAD_ATTR_PROPERTY
|
||||
#define _LOAD_ATTR_SLOT 401
|
||||
#define _LOAD_ATTR_SLOT_0 402
|
||||
#define _LOAD_ATTR_SLOT_1 403
|
||||
#define _LOAD_ATTR_WITH_HINT 404
|
||||
#define _LOAD_ATTR_SLOT 406
|
||||
#define _LOAD_ATTR_SLOT_0 407
|
||||
#define _LOAD_ATTR_SLOT_1 408
|
||||
#define _LOAD_ATTR_WITH_HINT 409
|
||||
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
|
||||
#define _LOAD_CONST LOAD_CONST
|
||||
#define _LOAD_CONST_INLINE 405
|
||||
#define _LOAD_CONST_INLINE_BORROW 406
|
||||
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 407
|
||||
#define _LOAD_CONST_INLINE_WITH_NULL 408
|
||||
#define _LOAD_CONST_INLINE 410
|
||||
#define _LOAD_CONST_INLINE_BORROW 411
|
||||
#define _LOAD_CONST_INLINE_BORROW_WITH_NULL 412
|
||||
#define _LOAD_CONST_INLINE_WITH_NULL 413
|
||||
#define _LOAD_DEREF LOAD_DEREF
|
||||
#define _LOAD_FAST 409
|
||||
#define _LOAD_FAST_0 410
|
||||
#define _LOAD_FAST_1 411
|
||||
#define _LOAD_FAST_2 412
|
||||
#define _LOAD_FAST_3 413
|
||||
#define _LOAD_FAST_4 414
|
||||
#define _LOAD_FAST_5 415
|
||||
#define _LOAD_FAST_6 416
|
||||
#define _LOAD_FAST_7 417
|
||||
#define _LOAD_FAST 414
|
||||
#define _LOAD_FAST_0 415
|
||||
#define _LOAD_FAST_1 416
|
||||
#define _LOAD_FAST_2 417
|
||||
#define _LOAD_FAST_3 418
|
||||
#define _LOAD_FAST_4 419
|
||||
#define _LOAD_FAST_5 420
|
||||
#define _LOAD_FAST_6 421
|
||||
#define _LOAD_FAST_7 422
|
||||
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
|
||||
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
|
||||
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
|
||||
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
|
||||
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
|
||||
#define _LOAD_GLOBAL 418
|
||||
#define _LOAD_GLOBAL_BUILTINS 419
|
||||
#define _LOAD_GLOBAL_MODULE 420
|
||||
#define _LOAD_GLOBAL 423
|
||||
#define _LOAD_GLOBAL_BUILTINS 424
|
||||
#define _LOAD_GLOBAL_MODULE 425
|
||||
#define _LOAD_LOCALS LOAD_LOCALS
|
||||
#define _LOAD_NAME LOAD_NAME
|
||||
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
|
||||
|
@ -222,50 +226,51 @@ extern "C" {
|
|||
#define _MATCH_SEQUENCE MATCH_SEQUENCE
|
||||
#define _NOP NOP
|
||||
#define _POP_EXCEPT POP_EXCEPT
|
||||
#define _POP_FRAME 421
|
||||
#define _POP_JUMP_IF_FALSE 422
|
||||
#define _POP_JUMP_IF_TRUE 423
|
||||
#define _POP_FRAME 426
|
||||
#define _POP_JUMP_IF_FALSE 427
|
||||
#define _POP_JUMP_IF_TRUE 428
|
||||
#define _POP_TOP POP_TOP
|
||||
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 424
|
||||
#define _POP_TOP_LOAD_CONST_INLINE_BORROW 429
|
||||
#define _PUSH_EXC_INFO PUSH_EXC_INFO
|
||||
#define _PUSH_FRAME 425
|
||||
#define _PUSH_FRAME 430
|
||||
#define _PUSH_NULL PUSH_NULL
|
||||
#define _REPLACE_WITH_TRUE 426
|
||||
#define _PY_FRAME_GENERAL 431
|
||||
#define _REPLACE_WITH_TRUE 432
|
||||
#define _RESUME_CHECK RESUME_CHECK
|
||||
#define _RETURN_GENERATOR RETURN_GENERATOR
|
||||
#define _SAVE_RETURN_OFFSET 427
|
||||
#define _SEND 428
|
||||
#define _SAVE_RETURN_OFFSET 433
|
||||
#define _SEND 434
|
||||
#define _SEND_GEN SEND_GEN
|
||||
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
|
||||
#define _SET_ADD SET_ADD
|
||||
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
|
||||
#define _SET_UPDATE SET_UPDATE
|
||||
#define _START_EXECUTOR 429
|
||||
#define _STORE_ATTR 430
|
||||
#define _STORE_ATTR_INSTANCE_VALUE 431
|
||||
#define _STORE_ATTR_SLOT 432
|
||||
#define _START_EXECUTOR 435
|
||||
#define _STORE_ATTR 436
|
||||
#define _STORE_ATTR_INSTANCE_VALUE 437
|
||||
#define _STORE_ATTR_SLOT 438
|
||||
#define _STORE_ATTR_WITH_HINT STORE_ATTR_WITH_HINT
|
||||
#define _STORE_DEREF STORE_DEREF
|
||||
#define _STORE_FAST 433
|
||||
#define _STORE_FAST_0 434
|
||||
#define _STORE_FAST_1 435
|
||||
#define _STORE_FAST_2 436
|
||||
#define _STORE_FAST_3 437
|
||||
#define _STORE_FAST_4 438
|
||||
#define _STORE_FAST_5 439
|
||||
#define _STORE_FAST_6 440
|
||||
#define _STORE_FAST_7 441
|
||||
#define _STORE_FAST 439
|
||||
#define _STORE_FAST_0 440
|
||||
#define _STORE_FAST_1 441
|
||||
#define _STORE_FAST_2 442
|
||||
#define _STORE_FAST_3 443
|
||||
#define _STORE_FAST_4 444
|
||||
#define _STORE_FAST_5 445
|
||||
#define _STORE_FAST_6 446
|
||||
#define _STORE_FAST_7 447
|
||||
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
|
||||
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
|
||||
#define _STORE_GLOBAL STORE_GLOBAL
|
||||
#define _STORE_NAME STORE_NAME
|
||||
#define _STORE_SLICE STORE_SLICE
|
||||
#define _STORE_SUBSCR 442
|
||||
#define _STORE_SUBSCR 448
|
||||
#define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT
|
||||
#define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT
|
||||
#define _SWAP SWAP
|
||||
#define _TIER2_RESUME_CHECK 443
|
||||
#define _TO_BOOL 444
|
||||
#define _TIER2_RESUME_CHECK 449
|
||||
#define _TO_BOOL 450
|
||||
#define _TO_BOOL_BOOL TO_BOOL_BOOL
|
||||
#define _TO_BOOL_INT TO_BOOL_INT
|
||||
#define _TO_BOOL_LIST TO_BOOL_LIST
|
||||
|
@ -275,13 +280,13 @@ extern "C" {
|
|||
#define _UNARY_NEGATIVE UNARY_NEGATIVE
|
||||
#define _UNARY_NOT UNARY_NOT
|
||||
#define _UNPACK_EX UNPACK_EX
|
||||
#define _UNPACK_SEQUENCE 445
|
||||
#define _UNPACK_SEQUENCE 451
|
||||
#define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST
|
||||
#define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE
|
||||
#define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE
|
||||
#define _WITH_EXCEPT_START WITH_EXCEPT_START
|
||||
#define _YIELD_VALUE YIELD_VALUE
|
||||
#define MAX_UOP_ID 445
|
||||
#define MAX_UOP_ID 451
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -193,7 +193,13 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
|||
[_CHECK_ATTR_METHOD_LAZY_DICT] = HAS_DEOPT_FLAG,
|
||||
[_LOAD_ATTR_METHOD_LAZY_DICT] = HAS_ARG_FLAG,
|
||||
[_CHECK_PERIODIC] = HAS_EVAL_BREAK_FLAG,
|
||||
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG | HAS_DEOPT_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_METHOD_VERSION] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
|
||||
[_EXPAND_METHOD] = HAS_ARG_FLAG,
|
||||
[_CHECK_IS_NOT_PY_CALLABLE] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
|
||||
[_CALL_NON_PY_GENERAL] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||
[_CHECK_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
|
||||
[_INIT_CALL_BOUND_METHOD_EXACT_ARGS] = HAS_ARG_FLAG,
|
||||
[_CHECK_PEP_523] = HAS_DEOPT_FLAG,
|
||||
[_CHECK_FUNCTION_EXACT_ARGS] = HAS_ARG_FLAG | HAS_EXIT_FLAG,
|
||||
|
@ -295,6 +301,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
|||
[_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS",
|
||||
[_CALL_METHOD_DESCRIPTOR_NOARGS] = "_CALL_METHOD_DESCRIPTOR_NOARGS",
|
||||
[_CALL_METHOD_DESCRIPTOR_O] = "_CALL_METHOD_DESCRIPTOR_O",
|
||||
[_CALL_NON_PY_GENERAL] = "_CALL_NON_PY_GENERAL",
|
||||
[_CALL_STR_1] = "_CALL_STR_1",
|
||||
[_CALL_TUPLE_1] = "_CALL_TUPLE_1",
|
||||
[_CALL_TYPE_1] = "_CALL_TYPE_1",
|
||||
|
@ -307,7 +314,10 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
|||
[_CHECK_EXC_MATCH] = "_CHECK_EXC_MATCH",
|
||||
[_CHECK_FUNCTION] = "_CHECK_FUNCTION",
|
||||
[_CHECK_FUNCTION_EXACT_ARGS] = "_CHECK_FUNCTION_EXACT_ARGS",
|
||||
[_CHECK_FUNCTION_VERSION] = "_CHECK_FUNCTION_VERSION",
|
||||
[_CHECK_IS_NOT_PY_CALLABLE] = "_CHECK_IS_NOT_PY_CALLABLE",
|
||||
[_CHECK_MANAGED_OBJECT_HAS_VALUES] = "_CHECK_MANAGED_OBJECT_HAS_VALUES",
|
||||
[_CHECK_METHOD_VERSION] = "_CHECK_METHOD_VERSION",
|
||||
[_CHECK_PEP_523] = "_CHECK_PEP_523",
|
||||
[_CHECK_PERIODIC] = "_CHECK_PERIODIC",
|
||||
[_CHECK_STACK_SPACE] = "_CHECK_STACK_SPACE",
|
||||
|
@ -339,6 +349,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
|||
[_ERROR_POP_N] = "_ERROR_POP_N",
|
||||
[_EXIT_INIT_CHECK] = "_EXIT_INIT_CHECK",
|
||||
[_EXIT_TRACE] = "_EXIT_TRACE",
|
||||
[_EXPAND_METHOD] = "_EXPAND_METHOD",
|
||||
[_FATAL_ERROR] = "_FATAL_ERROR",
|
||||
[_FORMAT_SIMPLE] = "_FORMAT_SIMPLE",
|
||||
[_FORMAT_WITH_SPEC] = "_FORMAT_WITH_SPEC",
|
||||
|
@ -449,6 +460,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
|
|||
[_PUSH_EXC_INFO] = "_PUSH_EXC_INFO",
|
||||
[_PUSH_FRAME] = "_PUSH_FRAME",
|
||||
[_PUSH_NULL] = "_PUSH_NULL",
|
||||
[_PY_FRAME_GENERAL] = "_PY_FRAME_GENERAL",
|
||||
[_REPLACE_WITH_TRUE] = "_REPLACE_WITH_TRUE",
|
||||
[_RESUME_CHECK] = "_RESUME_CHECK",
|
||||
[_RETURN_GENERATOR] = "_RETURN_GENERATOR",
|
||||
|
@ -850,6 +862,18 @@ int _PyUop_num_popped(int opcode, int oparg)
|
|||
return 1;
|
||||
case _CHECK_PERIODIC:
|
||||
return 0;
|
||||
case _PY_FRAME_GENERAL:
|
||||
return 2 + oparg;
|
||||
case _CHECK_FUNCTION_VERSION:
|
||||
return 2 + oparg;
|
||||
case _CHECK_METHOD_VERSION:
|
||||
return 2 + oparg;
|
||||
case _EXPAND_METHOD:
|
||||
return 2 + oparg;
|
||||
case _CHECK_IS_NOT_PY_CALLABLE:
|
||||
return 2 + oparg;
|
||||
case _CALL_NON_PY_GENERAL:
|
||||
return 2 + oparg;
|
||||
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS:
|
||||
return 2 + oparg;
|
||||
case _INIT_CALL_BOUND_METHOD_EXACT_ARGS:
|
||||
|
|
|
@ -144,63 +144,65 @@ extern "C" {
|
|||
#define BINARY_SUBSCR_TUPLE_INT 161
|
||||
#define CALL_ALLOC_AND_ENTER_INIT 162
|
||||
#define CALL_BOUND_METHOD_EXACT_ARGS 163
|
||||
#define CALL_BUILTIN_CLASS 164
|
||||
#define CALL_BUILTIN_FAST 165
|
||||
#define CALL_BUILTIN_FAST_WITH_KEYWORDS 166
|
||||
#define CALL_BUILTIN_O 167
|
||||
#define CALL_ISINSTANCE 168
|
||||
#define CALL_LEN 169
|
||||
#define CALL_LIST_APPEND 170
|
||||
#define CALL_METHOD_DESCRIPTOR_FAST 171
|
||||
#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 172
|
||||
#define CALL_METHOD_DESCRIPTOR_NOARGS 173
|
||||
#define CALL_METHOD_DESCRIPTOR_O 174
|
||||
#define CALL_PY_EXACT_ARGS 175
|
||||
#define CALL_PY_WITH_DEFAULTS 176
|
||||
#define CALL_STR_1 177
|
||||
#define CALL_TUPLE_1 178
|
||||
#define CALL_TYPE_1 179
|
||||
#define COMPARE_OP_FLOAT 180
|
||||
#define COMPARE_OP_INT 181
|
||||
#define COMPARE_OP_STR 182
|
||||
#define CONTAINS_OP_DICT 183
|
||||
#define CONTAINS_OP_SET 184
|
||||
#define FOR_ITER_GEN 185
|
||||
#define FOR_ITER_LIST 186
|
||||
#define FOR_ITER_RANGE 187
|
||||
#define FOR_ITER_TUPLE 188
|
||||
#define LOAD_ATTR_CLASS 189
|
||||
#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 190
|
||||
#define LOAD_ATTR_INSTANCE_VALUE 191
|
||||
#define LOAD_ATTR_METHOD_LAZY_DICT 192
|
||||
#define LOAD_ATTR_METHOD_NO_DICT 193
|
||||
#define LOAD_ATTR_METHOD_WITH_VALUES 194
|
||||
#define LOAD_ATTR_MODULE 195
|
||||
#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 196
|
||||
#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 197
|
||||
#define LOAD_ATTR_PROPERTY 198
|
||||
#define LOAD_ATTR_SLOT 199
|
||||
#define LOAD_ATTR_WITH_HINT 200
|
||||
#define LOAD_GLOBAL_BUILTIN 201
|
||||
#define LOAD_GLOBAL_MODULE 202
|
||||
#define LOAD_SUPER_ATTR_ATTR 203
|
||||
#define LOAD_SUPER_ATTR_METHOD 204
|
||||
#define RESUME_CHECK 205
|
||||
#define SEND_GEN 206
|
||||
#define STORE_ATTR_INSTANCE_VALUE 207
|
||||
#define STORE_ATTR_SLOT 208
|
||||
#define STORE_ATTR_WITH_HINT 209
|
||||
#define STORE_SUBSCR_DICT 210
|
||||
#define STORE_SUBSCR_LIST_INT 211
|
||||
#define TO_BOOL_ALWAYS_TRUE 212
|
||||
#define TO_BOOL_BOOL 213
|
||||
#define TO_BOOL_INT 214
|
||||
#define TO_BOOL_LIST 215
|
||||
#define TO_BOOL_NONE 216
|
||||
#define TO_BOOL_STR 217
|
||||
#define UNPACK_SEQUENCE_LIST 218
|
||||
#define UNPACK_SEQUENCE_TUPLE 219
|
||||
#define UNPACK_SEQUENCE_TWO_TUPLE 220
|
||||
#define CALL_BOUND_METHOD_GENERAL 164
|
||||
#define CALL_BUILTIN_CLASS 165
|
||||
#define CALL_BUILTIN_FAST 166
|
||||
#define CALL_BUILTIN_FAST_WITH_KEYWORDS 167
|
||||
#define CALL_BUILTIN_O 168
|
||||
#define CALL_ISINSTANCE 169
|
||||
#define CALL_LEN 170
|
||||
#define CALL_LIST_APPEND 171
|
||||
#define CALL_METHOD_DESCRIPTOR_FAST 172
|
||||
#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 173
|
||||
#define CALL_METHOD_DESCRIPTOR_NOARGS 174
|
||||
#define CALL_METHOD_DESCRIPTOR_O 175
|
||||
#define CALL_NON_PY_GENERAL 176
|
||||
#define CALL_PY_EXACT_ARGS 177
|
||||
#define CALL_PY_GENERAL 178
|
||||
#define CALL_STR_1 179
|
||||
#define CALL_TUPLE_1 180
|
||||
#define CALL_TYPE_1 181
|
||||
#define COMPARE_OP_FLOAT 182
|
||||
#define COMPARE_OP_INT 183
|
||||
#define COMPARE_OP_STR 184
|
||||
#define CONTAINS_OP_DICT 185
|
||||
#define CONTAINS_OP_SET 186
|
||||
#define FOR_ITER_GEN 187
|
||||
#define FOR_ITER_LIST 188
|
||||
#define FOR_ITER_RANGE 189
|
||||
#define FOR_ITER_TUPLE 190
|
||||
#define LOAD_ATTR_CLASS 191
|
||||
#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 192
|
||||
#define LOAD_ATTR_INSTANCE_VALUE 193
|
||||
#define LOAD_ATTR_METHOD_LAZY_DICT 194
|
||||
#define LOAD_ATTR_METHOD_NO_DICT 195
|
||||
#define LOAD_ATTR_METHOD_WITH_VALUES 196
|
||||
#define LOAD_ATTR_MODULE 197
|
||||
#define LOAD_ATTR_NONDESCRIPTOR_NO_DICT 198
|
||||
#define LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 199
|
||||
#define LOAD_ATTR_PROPERTY 200
|
||||
#define LOAD_ATTR_SLOT 201
|
||||
#define LOAD_ATTR_WITH_HINT 202
|
||||
#define LOAD_GLOBAL_BUILTIN 203
|
||||
#define LOAD_GLOBAL_MODULE 204
|
||||
#define LOAD_SUPER_ATTR_ATTR 205
|
||||
#define LOAD_SUPER_ATTR_METHOD 206
|
||||
#define RESUME_CHECK 207
|
||||
#define SEND_GEN 208
|
||||
#define STORE_ATTR_INSTANCE_VALUE 209
|
||||
#define STORE_ATTR_SLOT 210
|
||||
#define STORE_ATTR_WITH_HINT 211
|
||||
#define STORE_SUBSCR_DICT 212
|
||||
#define STORE_SUBSCR_LIST_INT 213
|
||||
#define TO_BOOL_ALWAYS_TRUE 214
|
||||
#define TO_BOOL_BOOL 215
|
||||
#define TO_BOOL_INT 216
|
||||
#define TO_BOOL_LIST 217
|
||||
#define TO_BOOL_NONE 218
|
||||
#define TO_BOOL_STR 219
|
||||
#define UNPACK_SEQUENCE_LIST 220
|
||||
#define UNPACK_SEQUENCE_TUPLE 221
|
||||
#define UNPACK_SEQUENCE_TWO_TUPLE 222
|
||||
#define INSTRUMENTED_RESUME 236
|
||||
#define INSTRUMENTED_END_FOR 237
|
||||
#define INSTRUMENTED_END_SEND 238
|
||||
|
|
|
@ -88,7 +88,6 @@ _specializations = {
|
|||
"CALL": [
|
||||
"CALL_BOUND_METHOD_EXACT_ARGS",
|
||||
"CALL_PY_EXACT_ARGS",
|
||||
"CALL_PY_WITH_DEFAULTS",
|
||||
"CALL_TYPE_1",
|
||||
"CALL_STR_1",
|
||||
"CALL_TUPLE_1",
|
||||
|
@ -104,6 +103,9 @@ _specializations = {
|
|||
"CALL_METHOD_DESCRIPTOR_NOARGS",
|
||||
"CALL_METHOD_DESCRIPTOR_FAST",
|
||||
"CALL_ALLOC_AND_ENTER_INIT",
|
||||
"CALL_PY_GENERAL",
|
||||
"CALL_BOUND_METHOD_GENERAL",
|
||||
"CALL_NON_PY_GENERAL",
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -123,63 +125,65 @@ _specialized_opmap = {
|
|||
'BINARY_SUBSCR_TUPLE_INT': 161,
|
||||
'CALL_ALLOC_AND_ENTER_INIT': 162,
|
||||
'CALL_BOUND_METHOD_EXACT_ARGS': 163,
|
||||
'CALL_BUILTIN_CLASS': 164,
|
||||
'CALL_BUILTIN_FAST': 165,
|
||||
'CALL_BUILTIN_FAST_WITH_KEYWORDS': 166,
|
||||
'CALL_BUILTIN_O': 167,
|
||||
'CALL_ISINSTANCE': 168,
|
||||
'CALL_LEN': 169,
|
||||
'CALL_LIST_APPEND': 170,
|
||||
'CALL_METHOD_DESCRIPTOR_FAST': 171,
|
||||
'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 172,
|
||||
'CALL_METHOD_DESCRIPTOR_NOARGS': 173,
|
||||
'CALL_METHOD_DESCRIPTOR_O': 174,
|
||||
'CALL_PY_EXACT_ARGS': 175,
|
||||
'CALL_PY_WITH_DEFAULTS': 176,
|
||||
'CALL_STR_1': 177,
|
||||
'CALL_TUPLE_1': 178,
|
||||
'CALL_TYPE_1': 179,
|
||||
'COMPARE_OP_FLOAT': 180,
|
||||
'COMPARE_OP_INT': 181,
|
||||
'COMPARE_OP_STR': 182,
|
||||
'CONTAINS_OP_DICT': 183,
|
||||
'CONTAINS_OP_SET': 184,
|
||||
'FOR_ITER_GEN': 185,
|
||||
'FOR_ITER_LIST': 186,
|
||||
'FOR_ITER_RANGE': 187,
|
||||
'FOR_ITER_TUPLE': 188,
|
||||
'LOAD_ATTR_CLASS': 189,
|
||||
'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 190,
|
||||
'LOAD_ATTR_INSTANCE_VALUE': 191,
|
||||
'LOAD_ATTR_METHOD_LAZY_DICT': 192,
|
||||
'LOAD_ATTR_METHOD_NO_DICT': 193,
|
||||
'LOAD_ATTR_METHOD_WITH_VALUES': 194,
|
||||
'LOAD_ATTR_MODULE': 195,
|
||||
'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 196,
|
||||
'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 197,
|
||||
'LOAD_ATTR_PROPERTY': 198,
|
||||
'LOAD_ATTR_SLOT': 199,
|
||||
'LOAD_ATTR_WITH_HINT': 200,
|
||||
'LOAD_GLOBAL_BUILTIN': 201,
|
||||
'LOAD_GLOBAL_MODULE': 202,
|
||||
'LOAD_SUPER_ATTR_ATTR': 203,
|
||||
'LOAD_SUPER_ATTR_METHOD': 204,
|
||||
'RESUME_CHECK': 205,
|
||||
'SEND_GEN': 206,
|
||||
'STORE_ATTR_INSTANCE_VALUE': 207,
|
||||
'STORE_ATTR_SLOT': 208,
|
||||
'STORE_ATTR_WITH_HINT': 209,
|
||||
'STORE_SUBSCR_DICT': 210,
|
||||
'STORE_SUBSCR_LIST_INT': 211,
|
||||
'TO_BOOL_ALWAYS_TRUE': 212,
|
||||
'TO_BOOL_BOOL': 213,
|
||||
'TO_BOOL_INT': 214,
|
||||
'TO_BOOL_LIST': 215,
|
||||
'TO_BOOL_NONE': 216,
|
||||
'TO_BOOL_STR': 217,
|
||||
'UNPACK_SEQUENCE_LIST': 218,
|
||||
'UNPACK_SEQUENCE_TUPLE': 219,
|
||||
'UNPACK_SEQUENCE_TWO_TUPLE': 220,
|
||||
'CALL_BOUND_METHOD_GENERAL': 164,
|
||||
'CALL_BUILTIN_CLASS': 165,
|
||||
'CALL_BUILTIN_FAST': 166,
|
||||
'CALL_BUILTIN_FAST_WITH_KEYWORDS': 167,
|
||||
'CALL_BUILTIN_O': 168,
|
||||
'CALL_ISINSTANCE': 169,
|
||||
'CALL_LEN': 170,
|
||||
'CALL_LIST_APPEND': 171,
|
||||
'CALL_METHOD_DESCRIPTOR_FAST': 172,
|
||||
'CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS': 173,
|
||||
'CALL_METHOD_DESCRIPTOR_NOARGS': 174,
|
||||
'CALL_METHOD_DESCRIPTOR_O': 175,
|
||||
'CALL_NON_PY_GENERAL': 176,
|
||||
'CALL_PY_EXACT_ARGS': 177,
|
||||
'CALL_PY_GENERAL': 178,
|
||||
'CALL_STR_1': 179,
|
||||
'CALL_TUPLE_1': 180,
|
||||
'CALL_TYPE_1': 181,
|
||||
'COMPARE_OP_FLOAT': 182,
|
||||
'COMPARE_OP_INT': 183,
|
||||
'COMPARE_OP_STR': 184,
|
||||
'CONTAINS_OP_DICT': 185,
|
||||
'CONTAINS_OP_SET': 186,
|
||||
'FOR_ITER_GEN': 187,
|
||||
'FOR_ITER_LIST': 188,
|
||||
'FOR_ITER_RANGE': 189,
|
||||
'FOR_ITER_TUPLE': 190,
|
||||
'LOAD_ATTR_CLASS': 191,
|
||||
'LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN': 192,
|
||||
'LOAD_ATTR_INSTANCE_VALUE': 193,
|
||||
'LOAD_ATTR_METHOD_LAZY_DICT': 194,
|
||||
'LOAD_ATTR_METHOD_NO_DICT': 195,
|
||||
'LOAD_ATTR_METHOD_WITH_VALUES': 196,
|
||||
'LOAD_ATTR_MODULE': 197,
|
||||
'LOAD_ATTR_NONDESCRIPTOR_NO_DICT': 198,
|
||||
'LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES': 199,
|
||||
'LOAD_ATTR_PROPERTY': 200,
|
||||
'LOAD_ATTR_SLOT': 201,
|
||||
'LOAD_ATTR_WITH_HINT': 202,
|
||||
'LOAD_GLOBAL_BUILTIN': 203,
|
||||
'LOAD_GLOBAL_MODULE': 204,
|
||||
'LOAD_SUPER_ATTR_ATTR': 205,
|
||||
'LOAD_SUPER_ATTR_METHOD': 206,
|
||||
'RESUME_CHECK': 207,
|
||||
'SEND_GEN': 208,
|
||||
'STORE_ATTR_INSTANCE_VALUE': 209,
|
||||
'STORE_ATTR_SLOT': 210,
|
||||
'STORE_ATTR_WITH_HINT': 211,
|
||||
'STORE_SUBSCR_DICT': 212,
|
||||
'STORE_SUBSCR_LIST_INT': 213,
|
||||
'TO_BOOL_ALWAYS_TRUE': 214,
|
||||
'TO_BOOL_BOOL': 215,
|
||||
'TO_BOOL_INT': 216,
|
||||
'TO_BOOL_LIST': 217,
|
||||
'TO_BOOL_NONE': 218,
|
||||
'TO_BOOL_STR': 219,
|
||||
'UNPACK_SEQUENCE_LIST': 220,
|
||||
'UNPACK_SEQUENCE_TUPLE': 221,
|
||||
'UNPACK_SEQUENCE_TWO_TUPLE': 222,
|
||||
}
|
||||
|
||||
opmap = {
|
||||
|
|
|
@ -46,11 +46,16 @@ class FunctionCalls(unittest.TestCase):
|
|||
# recovering from failed calls:
|
||||
def f():
|
||||
pass
|
||||
for _ in range(1000):
|
||||
try:
|
||||
f(None)
|
||||
except TypeError:
|
||||
class C:
|
||||
def m(self):
|
||||
pass
|
||||
callables = [f, C.m, [].__len__]
|
||||
for c in callables:
|
||||
for _ in range(1000):
|
||||
try:
|
||||
c(None)
|
||||
except TypeError:
|
||||
pass
|
||||
# BOOM!
|
||||
|
||||
|
||||
|
|
|
@ -840,7 +840,7 @@ dis_loop_test_quickened_code = """\
|
|||
|
||||
%3d LOAD_GLOBAL_MODULE 1 (load_test + NULL)
|
||||
LOAD_FAST 0 (i)
|
||||
CALL_PY_WITH_DEFAULTS 1
|
||||
CALL_PY_GENERAL 1
|
||||
POP_TOP
|
||||
JUMP_BACKWARD 16 (to L1)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import builtins
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
from test.support import swap_item, swap_attr
|
||||
from test.support import swap_item, swap_attr, is_wasi, Py_DEBUG
|
||||
|
||||
|
||||
class RebindBuiltinsTests(unittest.TestCase):
|
||||
|
@ -134,6 +134,7 @@ class RebindBuiltinsTests(unittest.TestCase):
|
|||
|
||||
self.assertEqual(foo(), 7)
|
||||
|
||||
@unittest.skipIf(is_wasi and Py_DEBUG, "requires too much stack")
|
||||
def test_load_global_specialization_failure_keeps_oparg(self):
|
||||
# https://github.com/python/cpython/issues/91625
|
||||
class MyGlobals(dict):
|
||||
|
|
|
@ -6,6 +6,7 @@ import sys
|
|||
import unittest
|
||||
import warnings
|
||||
|
||||
from test.support import is_wasi, Py_DEBUG
|
||||
from test.support.os_helper import (TESTFN, skip_unless_symlink,
|
||||
can_symlink, create_empty_file, change_cwd)
|
||||
|
||||
|
@ -366,6 +367,8 @@ class GlobTests(unittest.TestCase):
|
|||
self.assertEqual(self.rglob('mypipe', 'sub'), [])
|
||||
self.assertEqual(self.rglob('mypipe', '*'), [])
|
||||
|
||||
|
||||
@unittest.skipIf(is_wasi and Py_DEBUG, "requires too much stack")
|
||||
def test_glob_many_open_files(self):
|
||||
depth = 30
|
||||
base = os.path.join(self.tempdir, 'deep')
|
||||
|
|
|
@ -3042,7 +3042,6 @@ dummy_func(
|
|||
family(CALL, INLINE_CACHE_ENTRIES_CALL) = {
|
||||
CALL_BOUND_METHOD_EXACT_ARGS,
|
||||
CALL_PY_EXACT_ARGS,
|
||||
CALL_PY_WITH_DEFAULTS,
|
||||
CALL_TYPE_1,
|
||||
CALL_STR_1,
|
||||
CALL_TUPLE_1,
|
||||
|
@ -3058,6 +3057,9 @@ dummy_func(
|
|||
CALL_METHOD_DESCRIPTOR_NOARGS,
|
||||
CALL_METHOD_DESCRIPTOR_FAST,
|
||||
CALL_ALLOC_AND_ENTER_INIT,
|
||||
CALL_PY_GENERAL,
|
||||
CALL_BOUND_METHOD_GENERAL,
|
||||
CALL_NON_PY_GENERAL,
|
||||
};
|
||||
|
||||
specializing op(_SPECIALIZE_CALL, (counter/1, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) {
|
||||
|
@ -3147,9 +3149,108 @@ dummy_func(
|
|||
|
||||
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL + _CHECK_PERIODIC;
|
||||
|
||||
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _PyInterpreterFrame*)) {
|
||||
// oparg counts all of the args, but *not* self:
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
assert(Py_TYPE(callable) == &PyFunction_Type);
|
||||
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags;
|
||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
|
||||
new_frame = _PyEvalFramePushAndInit(
|
||||
tstate, (PyFunctionObject *)callable, locals,
|
||||
args, total_args, NULL
|
||||
);
|
||||
// The frame has stolen all the arguments from the stack,
|
||||
// so there is no need to clean them up.
|
||||
SYNC_SP();
|
||||
if (new_frame == NULL) {
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
}
|
||||
|
||||
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, unused, unused[oparg] -- callable, unused, unused[oparg])) {
|
||||
EXIT_IF(!PyFunction_Check(callable));
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
EXIT_IF(func->func_version != func_version);
|
||||
}
|
||||
|
||||
macro(CALL_PY_GENERAL) =
|
||||
unused/1 + // Skip over the counter
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_FUNCTION_VERSION +
|
||||
_PY_FRAME_GENERAL +
|
||||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
||||
op(_CHECK_METHOD_VERSION, (func_version/2, callable, null, unused[oparg] -- callable, null, unused[oparg])) {
|
||||
EXIT_IF(Py_TYPE(callable) != &PyMethod_Type);
|
||||
PyObject *func = ((PyMethodObject *)callable)->im_func;
|
||||
EXIT_IF(!PyFunction_Check(func));
|
||||
EXIT_IF(((PyFunctionObject *)func)->func_version != func_version);
|
||||
EXIT_IF(null != NULL);
|
||||
}
|
||||
|
||||
op(_EXPAND_METHOD, (callable, null, unused[oparg] -- method, self, unused[oparg])) {
|
||||
assert(null == NULL);
|
||||
assert(Py_TYPE(callable) == &PyMethod_Type);
|
||||
self = ((PyMethodObject *)callable)->im_self;
|
||||
Py_INCREF(self);
|
||||
stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _PY_FRAME_GENERAL
|
||||
method = ((PyMethodObject *)callable)->im_func;
|
||||
assert(PyFunction_Check(method));
|
||||
Py_INCREF(method);
|
||||
Py_DECREF(callable);
|
||||
}
|
||||
|
||||
macro(CALL_BOUND_METHOD_GENERAL) =
|
||||
unused/1 + // Skip over the counter
|
||||
_CHECK_PEP_523 +
|
||||
_CHECK_METHOD_VERSION +
|
||||
_EXPAND_METHOD +
|
||||
_PY_FRAME_GENERAL +
|
||||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
||||
op(_CHECK_IS_NOT_PY_CALLABLE, (callable, unused, unused[oparg] -- callable, unused, unused[oparg])) {
|
||||
EXIT_IF(PyFunction_Check(callable));
|
||||
EXIT_IF(Py_TYPE(callable) == &PyMethod_Type);
|
||||
}
|
||||
|
||||
op(_CALL_NON_PY_GENERAL, (callable, self_or_null, args[oparg] -- res)) {
|
||||
#if TIER_ONE
|
||||
assert(opcode != INSTRUMENTED_CALL);
|
||||
#endif
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
res = PyObject_Vectorcall(
|
||||
callable, args,
|
||||
total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||
NULL);
|
||||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||
Py_DECREF(callable);
|
||||
for (int i = 0; i < total_args; i++) {
|
||||
Py_DECREF(args[i]);
|
||||
}
|
||||
ERROR_IF(res == NULL, error);
|
||||
}
|
||||
|
||||
macro(CALL_NON_PY_GENERAL) =
|
||||
unused/1 + // Skip over the counter
|
||||
unused/2 +
|
||||
_CHECK_IS_NOT_PY_CALLABLE +
|
||||
_CALL_NON_PY_GENERAL +
|
||||
_CHECK_PERIODIC;
|
||||
|
||||
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
|
||||
DEOPT_IF(null != NULL);
|
||||
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type);
|
||||
EXIT_IF(null != NULL);
|
||||
EXIT_IF(Py_TYPE(callable) != &PyMethod_Type);
|
||||
}
|
||||
|
||||
op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- func, self, unused[oparg])) {
|
||||
|
@ -3227,40 +3328,6 @@ dummy_func(
|
|||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
||||
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) {
|
||||
DEOPT_IF(tstate->interp->eval_frame);
|
||||
int argcount = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
argcount++;
|
||||
}
|
||||
DEOPT_IF(!PyFunction_Check(callable));
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
DEOPT_IF(func->func_version != func_version);
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
assert(func->func_defaults);
|
||||
assert(PyTuple_CheckExact(func->func_defaults));
|
||||
int defcount = (int)PyTuple_GET_SIZE(func->func_defaults);
|
||||
assert(defcount <= code->co_argcount);
|
||||
int min_args = code->co_argcount - defcount;
|
||||
DEOPT_IF(argcount > code->co_argcount);
|
||||
DEOPT_IF(argcount < min_args);
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize));
|
||||
STAT_INC(CALL, hit);
|
||||
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount);
|
||||
for (int i = 0; i < argcount; i++) {
|
||||
new_frame->localsplus[i] = args[i];
|
||||
}
|
||||
for (int i = argcount; i < code->co_argcount; i++) {
|
||||
PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i - min_args);
|
||||
new_frame->localsplus[i] = Py_NewRef(def);
|
||||
}
|
||||
// Manipulate stack and cache directly since we leave using DISPATCH_INLINED().
|
||||
STACK_SHRINK(oparg + 2);
|
||||
frame->return_offset = (uint16_t)(next_instr - this_instr);
|
||||
DISPATCH_INLINED(new_frame);
|
||||
}
|
||||
|
||||
inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, arg -- res)) {
|
||||
assert(oparg == 1);
|
||||
DEOPT_IF(null != NULL);
|
||||
|
|
|
@ -247,10 +247,6 @@ static PyObject * import_name(PyThreadState *, _PyInterpreterFrame *,
|
|||
static PyObject * import_from(PyThreadState *, PyObject *, PyObject *);
|
||||
static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg);
|
||||
static int get_exception_handler(PyCodeObject *, int, int*, int*, int*);
|
||||
static _PyInterpreterFrame *
|
||||
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, PyObject* const* args,
|
||||
size_t argcount, PyObject *kwnames);
|
||||
static _PyInterpreterFrame *
|
||||
_PyEvalFramePushAndInit_Ex(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs);
|
||||
|
@ -1716,7 +1712,7 @@ _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame)
|
|||
}
|
||||
|
||||
/* Consumes references to func, locals and all the args */
|
||||
static _PyInterpreterFrame *
|
||||
_PyInterpreterFrame *
|
||||
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
|
||||
PyObject *locals, PyObject* const* args,
|
||||
size_t argcount, PyObject *kwnames)
|
||||
|
@ -1736,6 +1732,8 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
|
|||
return frame;
|
||||
fail:
|
||||
/* Consume the references */
|
||||
Py_DECREF(func);
|
||||
Py_XDECREF(locals);
|
||||
for (size_t i = 0; i < argcount; i++) {
|
||||
Py_DECREF(args[i]);
|
||||
}
|
||||
|
|
|
@ -3032,6 +3032,153 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _PY_FRAME_GENERAL: {
|
||||
PyObject **args;
|
||||
PyObject *self_or_null;
|
||||
PyObject *callable;
|
||||
_PyInterpreterFrame *new_frame;
|
||||
oparg = CURRENT_OPARG();
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
// oparg counts all of the args, but *not* self:
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
assert(Py_TYPE(callable) == &PyFunction_Type);
|
||||
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags;
|
||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
|
||||
new_frame = _PyEvalFramePushAndInit(
|
||||
tstate, (PyFunctionObject *)callable, locals,
|
||||
args, total_args, NULL
|
||||
);
|
||||
// The frame has stolen all the arguments from the stack,
|
||||
// so there is no need to clean them up.
|
||||
stack_pointer += -2 - oparg;
|
||||
if (new_frame == NULL) {
|
||||
JUMP_TO_ERROR();
|
||||
}
|
||||
stack_pointer[0] = (PyObject *)new_frame;
|
||||
stack_pointer += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_FUNCTION_VERSION: {
|
||||
PyObject *callable;
|
||||
oparg = CURRENT_OPARG();
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
uint32_t func_version = (uint32_t)CURRENT_OPERAND();
|
||||
if (!PyFunction_Check(callable)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
if (func->func_version != func_version) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_METHOD_VERSION: {
|
||||
PyObject *null;
|
||||
PyObject *callable;
|
||||
oparg = CURRENT_OPARG();
|
||||
null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
uint32_t func_version = (uint32_t)CURRENT_OPERAND();
|
||||
if (Py_TYPE(callable) != &PyMethod_Type) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
PyObject *func = ((PyMethodObject *)callable)->im_func;
|
||||
if (!PyFunction_Check(func)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (((PyFunctionObject *)func)->func_version != func_version) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (null != NULL) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _EXPAND_METHOD: {
|
||||
PyObject *null;
|
||||
PyObject *callable;
|
||||
PyObject *method;
|
||||
PyObject *self;
|
||||
oparg = CURRENT_OPARG();
|
||||
null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
assert(null == NULL);
|
||||
assert(Py_TYPE(callable) == &PyMethod_Type);
|
||||
self = ((PyMethodObject *)callable)->im_self;
|
||||
Py_INCREF(self);
|
||||
stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _PY_FRAME_GENERAL
|
||||
method = ((PyMethodObject *)callable)->im_func;
|
||||
assert(PyFunction_Check(method));
|
||||
Py_INCREF(method);
|
||||
Py_DECREF(callable);
|
||||
stack_pointer[-2 - oparg] = method;
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_IS_NOT_PY_CALLABLE: {
|
||||
PyObject *callable;
|
||||
oparg = CURRENT_OPARG();
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
if (PyFunction_Check(callable)) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
if (Py_TYPE(callable) == &PyMethod_Type) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case _CALL_NON_PY_GENERAL: {
|
||||
PyObject **args;
|
||||
PyObject *self_or_null;
|
||||
PyObject *callable;
|
||||
PyObject *res;
|
||||
oparg = CURRENT_OPARG();
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
#if TIER_ONE
|
||||
assert(opcode != INSTRUMENTED_CALL);
|
||||
#endif
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
res = PyObject_Vectorcall(
|
||||
callable, args,
|
||||
total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||
NULL);
|
||||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||
Py_DECREF(callable);
|
||||
for (int i = 0; i < total_args; i++) {
|
||||
Py_DECREF(args[i]);
|
||||
}
|
||||
if (res == NULL) JUMP_TO_ERROR();
|
||||
stack_pointer[-2 - oparg] = res;
|
||||
stack_pointer += -1 - oparg;
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: {
|
||||
PyObject *null;
|
||||
PyObject *callable;
|
||||
|
@ -3276,8 +3423,6 @@
|
|||
break;
|
||||
}
|
||||
|
||||
/* _CALL_PY_WITH_DEFAULTS is not a viable micro-op for tier 2 because it uses the 'this_instr' variable */
|
||||
|
||||
case _CALL_TYPE_1: {
|
||||
PyObject *arg;
|
||||
PyObject *null;
|
||||
|
|
|
@ -1002,6 +1002,97 @@
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(CALL_BOUND_METHOD_GENERAL) {
|
||||
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
|
||||
next_instr += 4;
|
||||
INSTRUCTION_STATS(CALL_BOUND_METHOD_GENERAL);
|
||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||
PyObject *null;
|
||||
PyObject *callable;
|
||||
PyObject *method;
|
||||
PyObject *self;
|
||||
PyObject **args;
|
||||
PyObject *self_or_null;
|
||||
_PyInterpreterFrame *new_frame;
|
||||
/* Skip 1 cache entry */
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
}
|
||||
// _CHECK_METHOD_VERSION
|
||||
null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
{
|
||||
uint32_t func_version = read_u32(&this_instr[2].cache);
|
||||
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
|
||||
PyObject *func = ((PyMethodObject *)callable)->im_func;
|
||||
DEOPT_IF(!PyFunction_Check(func), CALL);
|
||||
DEOPT_IF(((PyFunctionObject *)func)->func_version != func_version, CALL);
|
||||
DEOPT_IF(null != NULL, CALL);
|
||||
}
|
||||
// _EXPAND_METHOD
|
||||
{
|
||||
assert(null == NULL);
|
||||
assert(Py_TYPE(callable) == &PyMethod_Type);
|
||||
self = ((PyMethodObject *)callable)->im_self;
|
||||
Py_INCREF(self);
|
||||
stack_pointer[-1 - oparg] = self; // Patch stack as it is used by _PY_FRAME_GENERAL
|
||||
method = ((PyMethodObject *)callable)->im_func;
|
||||
assert(PyFunction_Check(method));
|
||||
Py_INCREF(method);
|
||||
Py_DECREF(callable);
|
||||
}
|
||||
// _PY_FRAME_GENERAL
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = self;
|
||||
callable = method;
|
||||
{
|
||||
// oparg counts all of the args, but *not* self:
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
assert(Py_TYPE(callable) == &PyFunction_Type);
|
||||
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags;
|
||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
|
||||
new_frame = _PyEvalFramePushAndInit(
|
||||
tstate, (PyFunctionObject *)callable, locals,
|
||||
args, total_args, NULL
|
||||
);
|
||||
// The frame has stolen all the arguments from the stack,
|
||||
// so there is no need to clean them up.
|
||||
stack_pointer += -2 - oparg;
|
||||
if (new_frame == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
// _SAVE_RETURN_OFFSET
|
||||
{
|
||||
#if TIER_ONE
|
||||
frame->return_offset = (uint16_t)(next_instr - this_instr);
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
frame->return_offset = oparg;
|
||||
#endif
|
||||
}
|
||||
// _PUSH_FRAME
|
||||
{
|
||||
// Write it out explicitly because it's subtly different.
|
||||
// Eventually this should be the only occurrence of this code.
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
new_frame->previous = frame;
|
||||
CALL_STAT_INC(inlined_py_calls);
|
||||
frame = tstate->current_frame = new_frame;
|
||||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP(0);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(CALL_BUILTIN_CLASS) {
|
||||
frame->instr_ptr = next_instr;
|
||||
next_instr += 4;
|
||||
|
@ -1713,6 +1804,56 @@
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(CALL_NON_PY_GENERAL) {
|
||||
frame->instr_ptr = next_instr;
|
||||
next_instr += 4;
|
||||
INSTRUCTION_STATS(CALL_NON_PY_GENERAL);
|
||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||
PyObject *callable;
|
||||
PyObject **args;
|
||||
PyObject *self_or_null;
|
||||
PyObject *res;
|
||||
/* Skip 1 cache entry */
|
||||
/* Skip 2 cache entries */
|
||||
// _CHECK_IS_NOT_PY_CALLABLE
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
{
|
||||
DEOPT_IF(PyFunction_Check(callable), CALL);
|
||||
DEOPT_IF(Py_TYPE(callable) == &PyMethod_Type, CALL);
|
||||
}
|
||||
// _CALL_NON_PY_GENERAL
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
{
|
||||
#if TIER_ONE
|
||||
assert(opcode != INSTRUMENTED_CALL);
|
||||
#endif
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
/* Callable is not a normal Python function */
|
||||
res = PyObject_Vectorcall(
|
||||
callable, args,
|
||||
total_args | PY_VECTORCALL_ARGUMENTS_OFFSET,
|
||||
NULL);
|
||||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||
Py_DECREF(callable);
|
||||
for (int i = 0; i < total_args; i++) {
|
||||
Py_DECREF(args[i]);
|
||||
}
|
||||
if (res == NULL) { stack_pointer += -2 - oparg; goto error; }
|
||||
}
|
||||
// _CHECK_PERIODIC
|
||||
{
|
||||
}
|
||||
stack_pointer[-2 - oparg] = res;
|
||||
stack_pointer += -1 - oparg;
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(CALL_PY_EXACT_ARGS) {
|
||||
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
|
||||
next_instr += 4;
|
||||
|
@ -1786,50 +1927,76 @@
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(CALL_PY_WITH_DEFAULTS) {
|
||||
TARGET(CALL_PY_GENERAL) {
|
||||
_Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr;
|
||||
next_instr += 4;
|
||||
INSTRUCTION_STATS(CALL_PY_WITH_DEFAULTS);
|
||||
INSTRUCTION_STATS(CALL_PY_GENERAL);
|
||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||
PyObject *callable;
|
||||
PyObject **args;
|
||||
PyObject *self_or_null;
|
||||
PyObject *callable;
|
||||
_PyInterpreterFrame *new_frame;
|
||||
/* Skip 1 cache entry */
|
||||
// _CHECK_PEP_523
|
||||
{
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
}
|
||||
// _CHECK_FUNCTION_VERSION
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
{
|
||||
uint32_t func_version = read_u32(&this_instr[2].cache);
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
}
|
||||
// _PY_FRAME_GENERAL
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
uint32_t func_version = read_u32(&this_instr[2].cache);
|
||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||
int argcount = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
argcount++;
|
||||
{
|
||||
// oparg counts all of the args, but *not* self:
|
||||
int total_args = oparg;
|
||||
if (self_or_null != NULL) {
|
||||
args--;
|
||||
total_args++;
|
||||
}
|
||||
assert(Py_TYPE(callable) == &PyFunction_Type);
|
||||
int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags;
|
||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable));
|
||||
new_frame = _PyEvalFramePushAndInit(
|
||||
tstate, (PyFunctionObject *)callable, locals,
|
||||
args, total_args, NULL
|
||||
);
|
||||
// The frame has stolen all the arguments from the stack,
|
||||
// so there is no need to clean them up.
|
||||
stack_pointer += -2 - oparg;
|
||||
if (new_frame == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||
DEOPT_IF(func->func_version != func_version, CALL);
|
||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||
assert(func->func_defaults);
|
||||
assert(PyTuple_CheckExact(func->func_defaults));
|
||||
int defcount = (int)PyTuple_GET_SIZE(func->func_defaults);
|
||||
assert(defcount <= code->co_argcount);
|
||||
int min_args = code->co_argcount - defcount;
|
||||
DEOPT_IF(argcount > code->co_argcount, CALL);
|
||||
DEOPT_IF(argcount < min_args, CALL);
|
||||
DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL);
|
||||
STAT_INC(CALL, hit);
|
||||
_PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount);
|
||||
for (int i = 0; i < argcount; i++) {
|
||||
new_frame->localsplus[i] = args[i];
|
||||
// _SAVE_RETURN_OFFSET
|
||||
{
|
||||
#if TIER_ONE
|
||||
frame->return_offset = (uint16_t)(next_instr - this_instr);
|
||||
#endif
|
||||
#if TIER_TWO
|
||||
frame->return_offset = oparg;
|
||||
#endif
|
||||
}
|
||||
for (int i = argcount; i < code->co_argcount; i++) {
|
||||
PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i - min_args);
|
||||
new_frame->localsplus[i] = Py_NewRef(def);
|
||||
// _PUSH_FRAME
|
||||
{
|
||||
// Write it out explicitly because it's subtly different.
|
||||
// Eventually this should be the only occurrence of this code.
|
||||
assert(tstate->interp->eval_frame == NULL);
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
new_frame->previous = frame;
|
||||
CALL_STAT_INC(inlined_py_calls);
|
||||
frame = tstate->current_frame = new_frame;
|
||||
tstate->py_recursion_remaining--;
|
||||
LOAD_SP();
|
||||
LOAD_IP(0);
|
||||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
// Manipulate stack and cache directly since we leave using DISPATCH_INLINED().
|
||||
STACK_SHRINK(oparg + 2);
|
||||
frame->return_offset = (uint16_t)(next_instr - this_instr);
|
||||
DISPATCH_INLINED(new_frame);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
TARGET(CALL_STR_1) {
|
||||
|
|
|
@ -163,6 +163,7 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_BINARY_SUBSCR_TUPLE_INT,
|
||||
&&TARGET_CALL_ALLOC_AND_ENTER_INIT,
|
||||
&&TARGET_CALL_BOUND_METHOD_EXACT_ARGS,
|
||||
&&TARGET_CALL_BOUND_METHOD_GENERAL,
|
||||
&&TARGET_CALL_BUILTIN_CLASS,
|
||||
&&TARGET_CALL_BUILTIN_FAST,
|
||||
&&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS,
|
||||
|
@ -174,8 +175,9 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS,
|
||||
&&TARGET_CALL_METHOD_DESCRIPTOR_NOARGS,
|
||||
&&TARGET_CALL_METHOD_DESCRIPTOR_O,
|
||||
&&TARGET_CALL_NON_PY_GENERAL,
|
||||
&&TARGET_CALL_PY_EXACT_ARGS,
|
||||
&&TARGET_CALL_PY_WITH_DEFAULTS,
|
||||
&&TARGET_CALL_PY_GENERAL,
|
||||
&&TARGET_CALL_STR_1,
|
||||
&&TARGET_CALL_TUPLE_1,
|
||||
&&TARGET_CALL_TYPE_1,
|
||||
|
@ -233,8 +235,6 @@ static void *opcode_targets[256] = {
|
|||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&_unknown_opcode,
|
||||
&&TARGET_INSTRUMENTED_RESUME,
|
||||
&&TARGET_INSTRUMENTED_END_FOR,
|
||||
&&TARGET_INSTRUMENTED_END_SEND,
|
||||
|
|
|
@ -987,6 +987,7 @@ static void make_exit(_PyUOpInstruction *inst, int opcode, int target)
|
|||
{
|
||||
inst->opcode = opcode;
|
||||
inst->oparg = 0;
|
||||
inst->operand = 0;
|
||||
inst->format = UOP_FORMAT_TARGET;
|
||||
inst->target = target;
|
||||
}
|
||||
|
|
|
@ -629,6 +629,15 @@ dummy_func(void) {
|
|||
frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0));
|
||||
}
|
||||
|
||||
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) {
|
||||
/* The _Py_UOpsAbstractFrame design assumes that we can copy arguments across directly */
|
||||
(void)callable;
|
||||
(void)self_or_null;
|
||||
(void)args;
|
||||
first_valid_check_stack = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
op(_POP_FRAME, (retval -- res)) {
|
||||
SYNC_SP();
|
||||
ctx->frame->stack_pointer = stack_pointer;
|
||||
|
@ -718,7 +727,7 @@ dummy_func(void) {
|
|||
if (first_valid_check_stack == NULL) {
|
||||
first_valid_check_stack = corresponding_check_stack;
|
||||
}
|
||||
else {
|
||||
else if (corresponding_check_stack) {
|
||||
// delete all but the first valid _CHECK_STACK_SPACE
|
||||
corresponding_check_stack->opcode = _NOP;
|
||||
}
|
||||
|
|
|
@ -1559,6 +1559,58 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _PY_FRAME_GENERAL: {
|
||||
_Py_UopsSymbol **args;
|
||||
_Py_UopsSymbol *self_or_null;
|
||||
_Py_UopsSymbol *callable;
|
||||
_Py_UOpsAbstractFrame *new_frame;
|
||||
args = &stack_pointer[-oparg];
|
||||
self_or_null = stack_pointer[-1 - oparg];
|
||||
callable = stack_pointer[-2 - oparg];
|
||||
/* The _Py_UOpsAbstractFrame design assumes that we can copy arguments across directly */
|
||||
(void)callable;
|
||||
(void)self_or_null;
|
||||
(void)args;
|
||||
first_valid_check_stack = NULL;
|
||||
goto done;
|
||||
stack_pointer[-2 - oparg] = (_Py_UopsSymbol *)new_frame;
|
||||
stack_pointer += -1 - oparg;
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_FUNCTION_VERSION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_METHOD_VERSION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _EXPAND_METHOD: {
|
||||
_Py_UopsSymbol *method;
|
||||
_Py_UopsSymbol *self;
|
||||
method = sym_new_not_null(ctx);
|
||||
if (method == NULL) goto out_of_space;
|
||||
self = sym_new_not_null(ctx);
|
||||
if (self == NULL) goto out_of_space;
|
||||
stack_pointer[-2 - oparg] = method;
|
||||
stack_pointer[-1 - oparg] = self;
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_IS_NOT_PY_CALLABLE: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _CALL_NON_PY_GENERAL: {
|
||||
_Py_UopsSymbol *res;
|
||||
res = sym_new_not_null(ctx);
|
||||
if (res == NULL) goto out_of_space;
|
||||
stack_pointer[-2 - oparg] = res;
|
||||
stack_pointer += -1 - oparg;
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_CALL_BOUND_METHOD_EXACT_ARGS: {
|
||||
_Py_UopsSymbol *null;
|
||||
_Py_UopsSymbol *callable;
|
||||
|
@ -1692,7 +1744,7 @@
|
|||
if (first_valid_check_stack == NULL) {
|
||||
first_valid_check_stack = corresponding_check_stack;
|
||||
}
|
||||
else {
|
||||
else if (corresponding_check_stack) {
|
||||
// delete all but the first valid _CHECK_STACK_SPACE
|
||||
corresponding_check_stack->opcode = _NOP;
|
||||
}
|
||||
|
@ -1700,8 +1752,6 @@
|
|||
break;
|
||||
}
|
||||
|
||||
/* _CALL_PY_WITH_DEFAULTS is not a viable micro-op for tier 2 */
|
||||
|
||||
case _CALL_TYPE_1: {
|
||||
_Py_UopsSymbol *res;
|
||||
res = sym_new_not_null(ctx);
|
||||
|
|
|
@ -1789,8 +1789,7 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
|||
return -1;
|
||||
}
|
||||
if (Py_TYPE(tp) != &PyType_Type) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_METACLASS);
|
||||
return -1;
|
||||
goto generic;
|
||||
}
|
||||
if (tp->tp_new == PyBaseObject_Type.tp_new) {
|
||||
PyFunctionObject *init = get_init_for_simple_managed_python_class(tp);
|
||||
|
@ -1807,59 +1806,12 @@ specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
|||
_Py_SET_OPCODE(*instr, CALL_ALLOC_AND_ENTER_INIT);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_CLASS_MUTABLE);
|
||||
return -1;
|
||||
generic:
|
||||
instr->op.code = CALL_NON_PY_GENERAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef Py_STATS
|
||||
static int
|
||||
builtin_call_fail_kind(int ml_flags)
|
||||
{
|
||||
switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
|
||||
METH_KEYWORDS | METH_METHOD)) {
|
||||
case METH_VARARGS:
|
||||
return SPEC_FAIL_CALL_CFUNC_VARARGS;
|
||||
case METH_VARARGS | METH_KEYWORDS:
|
||||
return SPEC_FAIL_CALL_CFUNC_VARARGS_KEYWORDS;
|
||||
case METH_NOARGS:
|
||||
return SPEC_FAIL_CALL_CFUNC_NOARGS;
|
||||
case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
|
||||
return SPEC_FAIL_CALL_CFUNC_METHOD_FASTCALL_KEYWORDS;
|
||||
/* These cases should be optimized, but return "other" just in case */
|
||||
case METH_O:
|
||||
case METH_FASTCALL:
|
||||
case METH_FASTCALL | METH_KEYWORDS:
|
||||
return SPEC_FAIL_OTHER;
|
||||
default:
|
||||
return SPEC_FAIL_CALL_BAD_CALL_FLAGS;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
meth_descr_call_fail_kind(int ml_flags)
|
||||
{
|
||||
switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O |
|
||||
METH_KEYWORDS | METH_METHOD)) {
|
||||
case METH_VARARGS:
|
||||
return SPEC_FAIL_CALL_METH_DESCR_VARARGS;
|
||||
case METH_VARARGS | METH_KEYWORDS:
|
||||
return SPEC_FAIL_CALL_METH_DESCR_VARARGS_KEYWORDS;
|
||||
case METH_METHOD | METH_FASTCALL | METH_KEYWORDS:
|
||||
return SPEC_FAIL_CALL_METH_DESCR_METHOD_FASTCALL_KEYWORDS;
|
||||
/* These cases should be optimized, but return "other" just in case */
|
||||
case METH_NOARGS:
|
||||
case METH_O:
|
||||
case METH_FASTCALL:
|
||||
case METH_FASTCALL | METH_KEYWORDS:
|
||||
return SPEC_FAIL_OTHER;
|
||||
default:
|
||||
return SPEC_FAIL_CALL_BAD_CALL_FLAGS;
|
||||
}
|
||||
}
|
||||
#endif // Py_STATS
|
||||
|
||||
static int
|
||||
specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
|
||||
int nargs)
|
||||
|
@ -1901,8 +1853,8 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
SPECIALIZATION_FAIL(CALL, meth_descr_call_fail_kind(descr->d_method->ml_flags));
|
||||
return -1;
|
||||
instr->op.code = CALL_NON_PY_GENERAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1917,36 +1869,25 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs,
|
|||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PEP_523);
|
||||
return -1;
|
||||
}
|
||||
if (kind != SIMPLE_FUNCTION) {
|
||||
SPECIALIZATION_FAIL(CALL, kind);
|
||||
int argcount = -1;
|
||||
if (kind == SPEC_FAIL_CODE_NOT_OPTIMIZED) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CODE_NOT_OPTIMIZED);
|
||||
return -1;
|
||||
}
|
||||
int argcount = code->co_argcount;
|
||||
int defcount = func->func_defaults == NULL ? 0 : (int)PyTuple_GET_SIZE(func->func_defaults);
|
||||
int min_args = argcount-defcount;
|
||||
// GH-105840: min_args is negative when somebody sets too many __defaults__!
|
||||
if (min_args < 0 || nargs > argcount || nargs < min_args) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS);
|
||||
return -1;
|
||||
if (kind == SIMPLE_FUNCTION) {
|
||||
argcount = code->co_argcount;
|
||||
}
|
||||
assert(nargs <= argcount && nargs >= min_args);
|
||||
assert(min_args >= 0 && defcount >= 0);
|
||||
assert(defcount == 0 || func->func_defaults != NULL);
|
||||
int version = _PyFunction_GetVersionForCurrentState(func);
|
||||
if (version == 0) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS);
|
||||
return -1;
|
||||
}
|
||||
write_u32(cache->func_version, version);
|
||||
if (argcount == nargs) {
|
||||
if (argcount == nargs + bound_method) {
|
||||
instr->op.code = bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS;
|
||||
}
|
||||
else if (bound_method) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
instr->op.code = CALL_PY_WITH_DEFAULTS;
|
||||
instr->op.code = bound_method ? CALL_BOUND_METHOD_GENERAL : CALL_PY_GENERAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1955,6 +1896,7 @@ static int
|
|||
specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
||||
{
|
||||
if (PyCFunction_GET_FUNCTION(callable) == NULL) {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OTHER);
|
||||
return 1;
|
||||
}
|
||||
switch (PyCFunction_GET_FLAGS(callable) &
|
||||
|
@ -1991,39 +1933,11 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
|||
return 0;
|
||||
}
|
||||
default:
|
||||
SPECIALIZATION_FAIL(CALL,
|
||||
builtin_call_fail_kind(PyCFunction_GET_FLAGS(callable)));
|
||||
return 1;
|
||||
instr->op.code = CALL_NON_PY_GENERAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Py_STATS
|
||||
static int
|
||||
call_fail_kind(PyObject *callable)
|
||||
{
|
||||
assert(!PyCFunction_CheckExact(callable));
|
||||
assert(!PyFunction_Check(callable));
|
||||
assert(!PyType_Check(callable));
|
||||
assert(!Py_IS_TYPE(callable, &PyMethodDescr_Type));
|
||||
assert(!PyMethod_Check(callable));
|
||||
if (PyInstanceMethod_Check(callable)) {
|
||||
return SPEC_FAIL_CALL_INSTANCE_METHOD;
|
||||
}
|
||||
// builtin method
|
||||
else if (PyCMethod_Check(callable)) {
|
||||
return SPEC_FAIL_CALL_CMETHOD;
|
||||
}
|
||||
else if (Py_TYPE(callable) == &PyWrapperDescr_Type) {
|
||||
return SPEC_FAIL_CALL_OPERATOR_WRAPPER;
|
||||
}
|
||||
else if (Py_TYPE(callable) == &_PyMethodWrapper_Type) {
|
||||
return SPEC_FAIL_CALL_METHOD_WRAPPER;
|
||||
}
|
||||
return SPEC_FAIL_OTHER;
|
||||
}
|
||||
#endif // Py_STATS
|
||||
|
||||
|
||||
void
|
||||
_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
||||
{
|
||||
|
@ -2047,7 +1961,7 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
|||
else if (PyMethod_Check(callable)) {
|
||||
PyObject *func = ((PyMethodObject *)callable)->im_func;
|
||||
if (PyFunction_Check(func)) {
|
||||
fail = specialize_py_call((PyFunctionObject *)func, instr, nargs+1, true);
|
||||
fail = specialize_py_call((PyFunctionObject *)func, instr, nargs, true);
|
||||
}
|
||||
else {
|
||||
SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD);
|
||||
|
@ -2055,8 +1969,8 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs)
|
|||
}
|
||||
}
|
||||
else {
|
||||
SPECIALIZATION_FAIL(CALL, call_fail_kind(callable));
|
||||
fail = -1;
|
||||
instr->op.code = CALL_NON_PY_GENERAL;
|
||||
fail = 0;
|
||||
}
|
||||
if (fail) {
|
||||
STAT_INC(CALL, failure);
|
||||
|
|
Loading…
Reference in New Issue