mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
GH-119476: Split _CHECK_FUNCTION_VERSION out of _CHECK_FUNCTION_EXACT_ARGS (GH-119510)
This commit is contained in:
parent
d87b015106
commit
cfcc054dee
6 changed files with 24 additions and 24 deletions
6
Include/internal/pycore_opcode_metadata.h
generated
6
Include/internal/pycore_opcode_metadata.h
generated
|
@ -1182,7 +1182,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[264] = {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_UOP_PER_EXPANSION 8
|
#define MAX_UOP_PER_EXPANSION 9
|
||||||
struct opcode_macro_expansion {
|
struct opcode_macro_expansion {
|
||||||
int nuops;
|
int nuops;
|
||||||
struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];
|
struct { int16_t uop; int8_t size; int8_t offset; } uops[MAX_UOP_PER_EXPANSION];
|
||||||
|
@ -1212,7 +1212,7 @@ _PyOpcode_macro_expansion[256] = {
|
||||||
[BUILD_SLICE] = { .nuops = 1, .uops = { { _BUILD_SLICE, 0, 0 } } },
|
[BUILD_SLICE] = { .nuops = 1, .uops = { { _BUILD_SLICE, 0, 0 } } },
|
||||||
[BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } },
|
[BUILD_STRING] = { .nuops = 1, .uops = { { _BUILD_STRING, 0, 0 } } },
|
||||||
[BUILD_TUPLE] = { .nuops = 1, .uops = { { _BUILD_TUPLE, 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_EXACT_ARGS] = { .nuops = 9, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _INIT_CALL_BOUND_METHOD_EXACT_ARGS, 0, 0 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, 0, 0 }, { _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_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_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] = { .nuops = 2, .uops = { { _CALL_BUILTIN_FAST, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||||
|
@ -1227,7 +1227,7 @@ _PyOpcode_macro_expansion[256] = {
|
||||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = { .nuops = 2, .uops = { { _CALL_METHOD_DESCRIPTOR_NOARGS, 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_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_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_EXACT_ARGS] = { .nuops = 7, .uops = { { _CHECK_PEP_523, 0, 0 }, { _CHECK_FUNCTION_VERSION, 2, 1 }, { _CHECK_FUNCTION_EXACT_ARGS, 0, 0 }, { _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_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_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_TUPLE_1] = { .nuops = 2, .uops = { { _CALL_TUPLE_1, 0, 0 }, { _CHECK_PERIODIC, 0, 0 } } },
|
||||||
|
|
|
@ -3261,10 +3261,9 @@ dummy_func(
|
||||||
DEOPT_IF(tstate->interp->eval_frame);
|
DEOPT_IF(tstate->interp->eval_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
||||||
EXIT_IF(!PyFunction_Check(callable));
|
assert(PyFunction_Check(callable));
|
||||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||||
EXIT_IF(func->func_version != func_version);
|
|
||||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||||
EXIT_IF(code->co_argcount != oparg + (self_or_null != NULL));
|
EXIT_IF(code->co_argcount != oparg + (self_or_null != NULL));
|
||||||
}
|
}
|
||||||
|
@ -3308,6 +3307,7 @@ dummy_func(
|
||||||
_CHECK_PEP_523 +
|
_CHECK_PEP_523 +
|
||||||
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS +
|
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS +
|
||||||
_INIT_CALL_BOUND_METHOD_EXACT_ARGS +
|
_INIT_CALL_BOUND_METHOD_EXACT_ARGS +
|
||||||
|
_CHECK_FUNCTION_VERSION +
|
||||||
_CHECK_FUNCTION_EXACT_ARGS +
|
_CHECK_FUNCTION_EXACT_ARGS +
|
||||||
_CHECK_STACK_SPACE +
|
_CHECK_STACK_SPACE +
|
||||||
_INIT_CALL_PY_EXACT_ARGS +
|
_INIT_CALL_PY_EXACT_ARGS +
|
||||||
|
@ -3317,6 +3317,7 @@ dummy_func(
|
||||||
macro(CALL_PY_EXACT_ARGS) =
|
macro(CALL_PY_EXACT_ARGS) =
|
||||||
unused/1 + // Skip over the counter
|
unused/1 + // Skip over the counter
|
||||||
_CHECK_PEP_523 +
|
_CHECK_PEP_523 +
|
||||||
|
_CHECK_FUNCTION_VERSION +
|
||||||
_CHECK_FUNCTION_EXACT_ARGS +
|
_CHECK_FUNCTION_EXACT_ARGS +
|
||||||
_CHECK_STACK_SPACE +
|
_CHECK_STACK_SPACE +
|
||||||
_INIT_CALL_PY_EXACT_ARGS +
|
_INIT_CALL_PY_EXACT_ARGS +
|
||||||
|
|
10
Python/executor_cases.c.h
generated
10
Python/executor_cases.c.h
generated
|
@ -3240,16 +3240,8 @@
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
self_or_null = stack_pointer[-1 - oparg];
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
uint32_t func_version = (uint32_t)CURRENT_OPERAND();
|
assert(PyFunction_Check(callable));
|
||||||
if (!PyFunction_Check(callable)) {
|
|
||||||
UOP_STAT_INC(uopcode, miss);
|
|
||||||
JUMP_TO_JUMP_TARGET();
|
|
||||||
}
|
|
||||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||||
if (func->func_version != func_version) {
|
|
||||||
UOP_STAT_INC(uopcode, miss);
|
|
||||||
JUMP_TO_JUMP_TARGET();
|
|
||||||
}
|
|
||||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||||
if (code->co_argcount != oparg + (self_or_null != NULL)) {
|
if (code->co_argcount != oparg + (self_or_null != NULL)) {
|
||||||
UOP_STAT_INC(uopcode, miss);
|
UOP_STAT_INC(uopcode, miss);
|
||||||
|
|
20
Python/generated_cases.c.h
generated
20
Python/generated_cases.c.h
generated
|
@ -943,14 +943,19 @@
|
||||||
stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization
|
stack_pointer[-2 - oparg] = func; // This is used by CALL, upon deoptimization
|
||||||
Py_DECREF(callable);
|
Py_DECREF(callable);
|
||||||
}
|
}
|
||||||
// _CHECK_FUNCTION_EXACT_ARGS
|
// _CHECK_FUNCTION_VERSION
|
||||||
self_or_null = self;
|
|
||||||
callable = func;
|
callable = func;
|
||||||
{
|
{
|
||||||
uint32_t func_version = read_u32(&this_instr[2].cache);
|
uint32_t func_version = read_u32(&this_instr[2].cache);
|
||||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||||
DEOPT_IF(func->func_version != func_version, CALL);
|
DEOPT_IF(func->func_version != func_version, CALL);
|
||||||
|
}
|
||||||
|
// _CHECK_FUNCTION_EXACT_ARGS
|
||||||
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
|
{
|
||||||
|
assert(PyFunction_Check(callable));
|
||||||
|
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||||
}
|
}
|
||||||
|
@ -1859,8 +1864,8 @@
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_PY_EXACT_ARGS);
|
INSTRUCTION_STATS(CALL_PY_EXACT_ARGS);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||||
PyObject *self_or_null;
|
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
|
PyObject *self_or_null;
|
||||||
PyObject **args;
|
PyObject **args;
|
||||||
_PyInterpreterFrame *new_frame;
|
_PyInterpreterFrame *new_frame;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
|
@ -1868,14 +1873,19 @@
|
||||||
{
|
{
|
||||||
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
DEOPT_IF(tstate->interp->eval_frame, CALL);
|
||||||
}
|
}
|
||||||
// _CHECK_FUNCTION_EXACT_ARGS
|
// _CHECK_FUNCTION_VERSION
|
||||||
self_or_null = stack_pointer[-1 - oparg];
|
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
{
|
{
|
||||||
uint32_t func_version = read_u32(&this_instr[2].cache);
|
uint32_t func_version = read_u32(&this_instr[2].cache);
|
||||||
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
DEOPT_IF(!PyFunction_Check(callable), CALL);
|
||||||
PyFunctionObject *func = (PyFunctionObject *)callable;
|
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||||
DEOPT_IF(func->func_version != func_version, CALL);
|
DEOPT_IF(func->func_version != func_version, CALL);
|
||||||
|
}
|
||||||
|
// _CHECK_FUNCTION_EXACT_ARGS
|
||||||
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
|
{
|
||||||
|
assert(PyFunction_Check(callable));
|
||||||
|
PyFunctionObject *func = (PyFunctionObject *)callable;
|
||||||
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
PyCodeObject *code = (PyCodeObject *)func->func_code;
|
||||||
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL), CALL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -519,10 +519,9 @@ dummy_func(void) {
|
||||||
self = sym_new_not_null(ctx);
|
self = sym_new_not_null(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
|
||||||
sym_set_type(callable, &PyFunction_Type);
|
sym_set_type(callable, &PyFunction_Type);
|
||||||
(void)self_or_null;
|
(void)self_or_null;
|
||||||
(void)func_version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
|
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
|
||||||
|
|
2
Python/optimizer_cases.c.h
generated
2
Python/optimizer_cases.c.h
generated
|
@ -1537,10 +1537,8 @@
|
||||||
_Py_UopsSymbol *callable;
|
_Py_UopsSymbol *callable;
|
||||||
self_or_null = stack_pointer[-1 - oparg];
|
self_or_null = stack_pointer[-1 - oparg];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-2 - oparg];
|
||||||
uint32_t func_version = (uint32_t)this_instr->operand;
|
|
||||||
sym_set_type(callable, &PyFunction_Type);
|
sym_set_type(callable, &PyFunction_Type);
|
||||||
(void)self_or_null;
|
(void)self_or_null;
|
||||||
(void)func_version;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue