mirror of
https://github.com/python/cpython.git
synced 2026-01-04 22:42:14 +00:00
gh-106581: Project through calls (#108067)
This finishes the work begun in gh-107760. When, while projecting a superblock, we encounter a call to a short, simple function, the superblock will now enter the function using `_PUSH_FRAME`, continue through it, and leave it using `_POP_FRAME`, and then continue through the original code. Multiple frame pushes and pops are even possible. It is also possible to stop appending to the superblock in the middle of a called function, when running out of space or encountering an unsupported bytecode.
This commit is contained in:
parent
292a22bdc2
commit
61c7249759
16 changed files with 409 additions and 109 deletions
|
|
@ -171,6 +171,7 @@ void _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *
|
|||
PyObject *_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs);
|
||||
PyObject *_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys);
|
||||
int _PyEval_UnpackIterable(PyThreadState *tstate, PyObject *v, int argcnt, int argcntafter, PyObject **sp);
|
||||
void _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -16,13 +16,22 @@ extern PyObject* _PyFunction_Vectorcall(
|
|||
|
||||
#define FUNC_MAX_WATCHERS 8
|
||||
|
||||
#define FUNC_VERSION_CACHE_SIZE (1<<12) /* Must be a power of 2 */
|
||||
struct _py_func_state {
|
||||
uint32_t next_version;
|
||||
// Borrowed references to function objects whose
|
||||
// func_version % FUNC_VERSION_CACHE_SIZE
|
||||
// once was equal to the index in the table.
|
||||
// They are cleared when the function is deallocated.
|
||||
PyFunctionObject *func_version_cache[FUNC_VERSION_CACHE_SIZE];
|
||||
};
|
||||
|
||||
extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr);
|
||||
|
||||
extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func);
|
||||
extern void _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version);
|
||||
PyFunctionObject *_PyFunction_LookupByVersion(uint32_t version);
|
||||
|
||||
extern PyObject *_Py_set_function_type_params(
|
||||
PyThreadState* unused, PyObject *func, PyObject *type_params);
|
||||
|
||||
|
|
|
|||
87
Include/internal/pycore_opcode_metadata.h
generated
87
Include/internal/pycore_opcode_metadata.h
generated
|
|
@ -33,35 +33,36 @@
|
|||
#define _BINARY_OP_SUBTRACT_FLOAT 309
|
||||
#define _GUARD_BOTH_UNICODE 310
|
||||
#define _BINARY_OP_ADD_UNICODE 311
|
||||
#define _LOAD_LOCALS 312
|
||||
#define _LOAD_FROM_DICT_OR_GLOBALS 313
|
||||
#define _GUARD_GLOBALS_VERSION 314
|
||||
#define _GUARD_BUILTINS_VERSION 315
|
||||
#define _LOAD_GLOBAL_MODULE 316
|
||||
#define _LOAD_GLOBAL_BUILTINS 317
|
||||
#define _GUARD_TYPE_VERSION 318
|
||||
#define _CHECK_MANAGED_OBJECT_HAS_VALUES 319
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE 320
|
||||
#define IS_NONE 321
|
||||
#define _ITER_CHECK_LIST 322
|
||||
#define _IS_ITER_EXHAUSTED_LIST 323
|
||||
#define _ITER_NEXT_LIST 324
|
||||
#define _ITER_CHECK_TUPLE 325
|
||||
#define _IS_ITER_EXHAUSTED_TUPLE 326
|
||||
#define _ITER_NEXT_TUPLE 327
|
||||
#define _ITER_CHECK_RANGE 328
|
||||
#define _IS_ITER_EXHAUSTED_RANGE 329
|
||||
#define _ITER_NEXT_RANGE 330
|
||||
#define _CHECK_PEP_523 331
|
||||
#define _CHECK_FUNCTION_EXACT_ARGS 332
|
||||
#define _CHECK_STACK_SPACE 333
|
||||
#define _INIT_CALL_PY_EXACT_ARGS 334
|
||||
#define _PUSH_FRAME 335
|
||||
#define _POP_JUMP_IF_FALSE 336
|
||||
#define _POP_JUMP_IF_TRUE 337
|
||||
#define JUMP_TO_TOP 338
|
||||
#define SAVE_CURRENT_IP 339
|
||||
#define INSERT 340
|
||||
#define _POP_FRAME 312
|
||||
#define _LOAD_LOCALS 313
|
||||
#define _LOAD_FROM_DICT_OR_GLOBALS 314
|
||||
#define _GUARD_GLOBALS_VERSION 315
|
||||
#define _GUARD_BUILTINS_VERSION 316
|
||||
#define _LOAD_GLOBAL_MODULE 317
|
||||
#define _LOAD_GLOBAL_BUILTINS 318
|
||||
#define _GUARD_TYPE_VERSION 319
|
||||
#define _CHECK_MANAGED_OBJECT_HAS_VALUES 320
|
||||
#define _LOAD_ATTR_INSTANCE_VALUE 321
|
||||
#define IS_NONE 322
|
||||
#define _ITER_CHECK_LIST 323
|
||||
#define _IS_ITER_EXHAUSTED_LIST 324
|
||||
#define _ITER_NEXT_LIST 325
|
||||
#define _ITER_CHECK_TUPLE 326
|
||||
#define _IS_ITER_EXHAUSTED_TUPLE 327
|
||||
#define _ITER_NEXT_TUPLE 328
|
||||
#define _ITER_CHECK_RANGE 329
|
||||
#define _IS_ITER_EXHAUSTED_RANGE 330
|
||||
#define _ITER_NEXT_RANGE 331
|
||||
#define _CHECK_PEP_523 332
|
||||
#define _CHECK_FUNCTION_EXACT_ARGS 333
|
||||
#define _CHECK_STACK_SPACE 334
|
||||
#define _INIT_CALL_PY_EXACT_ARGS 335
|
||||
#define _PUSH_FRAME 336
|
||||
#define _POP_JUMP_IF_FALSE 337
|
||||
#define _POP_JUMP_IF_TRUE 338
|
||||
#define JUMP_TO_TOP 339
|
||||
#define SAVE_CURRENT_IP 340
|
||||
#define INSERT 341
|
||||
|
||||
extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump);
|
||||
#ifdef NEED_OPCODE_METADATA
|
||||
|
|
@ -197,6 +198,8 @@ int _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
|
|||
return oparg;
|
||||
case INTERPRETER_EXIT:
|
||||
return 1;
|
||||
case _POP_FRAME:
|
||||
return 1;
|
||||
case RETURN_VALUE:
|
||||
return 1;
|
||||
case INSTRUMENTED_RETURN_VALUE:
|
||||
|
|
@ -723,6 +726,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
|
|||
return 0;
|
||||
case INTERPRETER_EXIT:
|
||||
return 0;
|
||||
case _POP_FRAME:
|
||||
return 0;
|
||||
case RETURN_VALUE:
|
||||
return 0;
|
||||
case INSTRUMENTED_RETURN_VALUE:
|
||||
|
|
@ -1191,7 +1196,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
|||
[STORE_FAST_STORE_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG },
|
||||
[POP_TOP] = { true, INSTR_FMT_IX, 0 },
|
||||
[PUSH_NULL] = { true, INSTR_FMT_IX, 0 },
|
||||
[END_FOR] = { true, INSTR_FMT_IB, 0 },
|
||||
[END_FOR] = { true, INSTR_FMT_IX, 0 },
|
||||
[INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX, 0 },
|
||||
[END_SEND] = { true, INSTR_FMT_IX, 0 },
|
||||
[INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX, 0 },
|
||||
|
|
@ -1205,14 +1210,14 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
|||
[TO_BOOL_STR] = { true, INSTR_FMT_IXC00, 0 },
|
||||
[TO_BOOL_ALWAYS_TRUE] = { true, INSTR_FMT_IXC00, 0 },
|
||||
[UNARY_INVERT] = { true, INSTR_FMT_IX, 0 },
|
||||
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IBC, 0 },
|
||||
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IB, HAS_LOCAL_FLAG },
|
||||
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX, HAS_LOCAL_FLAG },
|
||||
[BINARY_SUBSCR] = { true, INSTR_FMT_IXC, 0 },
|
||||
[BINARY_SLICE] = { true, INSTR_FMT_IX, 0 },
|
||||
[STORE_SLICE] = { true, INSTR_FMT_IX, 0 },
|
||||
|
|
@ -1259,7 +1264,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
|
|||
[DELETE_ATTR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG },
|
||||
[STORE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG },
|
||||
[DELETE_GLOBAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG },
|
||||
[LOAD_LOCALS] = { true, INSTR_FMT_IB, 0 },
|
||||
[LOAD_LOCALS] = { true, INSTR_FMT_IX, 0 },
|
||||
[LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG },
|
||||
[LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG },
|
||||
[LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG },
|
||||
|
|
@ -1400,6 +1405,7 @@ extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACR
|
|||
#ifdef NEED_OPCODE_METADATA
|
||||
const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPANSION_SIZE] = {
|
||||
[NOP] = { .nuops = 1, .uops = { { NOP, 0, 0 } } },
|
||||
[RESUME] = { .nuops = 1, .uops = { { RESUME, 0, 0 } } },
|
||||
[LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { LOAD_FAST_CHECK, 0, 0 } } },
|
||||
[LOAD_FAST] = { .nuops = 1, .uops = { { LOAD_FAST, 0, 0 } } },
|
||||
[LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { LOAD_FAST_AND_CLEAR, 0, 0 } } },
|
||||
|
|
@ -1444,6 +1450,8 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[OPCODE_MACRO_EXPAN
|
|||
[DELETE_SUBSCR] = { .nuops = 1, .uops = { { DELETE_SUBSCR, 0, 0 } } },
|
||||
[CALL_INTRINSIC_1] = { .nuops = 1, .uops = { { CALL_INTRINSIC_1, 0, 0 } } },
|
||||
[CALL_INTRINSIC_2] = { .nuops = 1, .uops = { { CALL_INTRINSIC_2, 0, 0 } } },
|
||||
[RETURN_VALUE] = { .nuops = 3, .uops = { { SAVE_IP, 7, 0 }, { SAVE_CURRENT_IP, 0, 0 }, { _POP_FRAME, 0, 0 } } },
|
||||
[RETURN_CONST] = { .nuops = 4, .uops = { { LOAD_CONST, 0, 0 }, { SAVE_IP, 7, 0 }, { SAVE_CURRENT_IP, 0, 0 }, { _POP_FRAME, 0, 0 } } },
|
||||
[GET_AITER] = { .nuops = 1, .uops = { { GET_AITER, 0, 0 } } },
|
||||
[GET_ANEXT] = { .nuops = 1, .uops = { { GET_ANEXT, 0, 0 } } },
|
||||
[GET_AWAITABLE] = { .nuops = 1, .uops = { { GET_AWAITABLE, 0, 0 } } },
|
||||
|
|
@ -1545,6 +1553,7 @@ const char * const _PyOpcode_uop_name[OPCODE_UOP_NAME_SIZE] = {
|
|||
[_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
|
||||
[_GUARD_BOTH_UNICODE] = "_GUARD_BOTH_UNICODE",
|
||||
[_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
|
||||
[_POP_FRAME] = "_POP_FRAME",
|
||||
[_LOAD_LOCALS] = "_LOAD_LOCALS",
|
||||
[_LOAD_FROM_DICT_OR_GLOBALS] = "_LOAD_FROM_DICT_OR_GLOBALS",
|
||||
[_GUARD_GLOBALS_VERSION] = "_GUARD_GLOBALS_VERSION",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue