https://github.com/python/cpython/commit/cfcc054dee87a5a3f18c99d83a2957bf3487de1d
commit: cfcc054dee87a5a3f18c99d83a2957bf3487de1d
branch: main
author: Brandt Bucher <[email protected]>
committer: brandtbucher <[email protected]>
date: 2024-05-28T12:45:11-07:00
summary:
GH-119476: Split _CHECK_FUNCTION_VERSION out of _CHECK_FUNCTION_EXACT_ARGS
(GH-119510)
files:
M Include/internal/pycore_opcode_metadata.h
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
diff --git a/Include/internal/pycore_opcode_metadata.h
b/Include/internal/pycore_opcode_metadata.h
index 4aedfa89e906ea..7f18b07a9eacc3 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1182,7 +1182,7 @@ const struct opcode_metadata
_PyOpcode_opcode_metadata[264] = {
};
#endif
-#define MAX_UOP_PER_EXPANSION 8
+#define MAX_UOP_PER_EXPANSION 9
struct opcode_macro_expansion {
int nuops;
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_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_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_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 } } },
@@ -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_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_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_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 } } },
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 025fed35686ca6..8b12da0918520b 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -3261,10 +3261,9 @@ dummy_func(
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])) {
- EXIT_IF(!PyFunction_Check(callable));
+ op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg]
-- callable, self_or_null, unused[oparg])) {
+ assert(PyFunction_Check(callable));
PyFunctionObject *func = (PyFunctionObject *)callable;
- EXIT_IF(func->func_version != func_version);
PyCodeObject *code = (PyCodeObject *)func->func_code;
EXIT_IF(code->co_argcount != oparg + (self_or_null != NULL));
}
@@ -3308,6 +3307,7 @@ dummy_func(
_CHECK_PEP_523 +
_CHECK_CALL_BOUND_METHOD_EXACT_ARGS +
_INIT_CALL_BOUND_METHOD_EXACT_ARGS +
+ _CHECK_FUNCTION_VERSION +
_CHECK_FUNCTION_EXACT_ARGS +
_CHECK_STACK_SPACE +
_INIT_CALL_PY_EXACT_ARGS +
@@ -3317,6 +3317,7 @@ dummy_func(
macro(CALL_PY_EXACT_ARGS) =
unused/1 + // Skip over the counter
_CHECK_PEP_523 +
+ _CHECK_FUNCTION_VERSION +
_CHECK_FUNCTION_EXACT_ARGS +
_CHECK_STACK_SPACE +
_INIT_CALL_PY_EXACT_ARGS +
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index a3d7af250316e3..a00b3821912394 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -3240,16 +3240,8 @@
oparg = CURRENT_OPARG();
self_or_null = stack_pointer[-1 - 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();
- }
+ assert(PyFunction_Check(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;
if (code->co_argcount != oparg + (self_or_null != NULL)) {
UOP_STAT_INC(uopcode, miss);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 07d9965b299e12..b897c38cc474b2 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -943,14 +943,19 @@
stack_pointer[-2 - oparg] = func; // This is used by CALL,
upon deoptimization
Py_DECREF(callable);
}
- // _CHECK_FUNCTION_EXACT_ARGS
- self_or_null = self;
+ // _CHECK_FUNCTION_VERSION
callable = func;
{
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);
+ }
+ // _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;
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL),
CALL);
}
@@ -1859,8 +1864,8 @@
next_instr += 4;
INSTRUCTION_STATS(CALL_PY_EXACT_ARGS);
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache
size");
- PyObject *self_or_null;
PyObject *callable;
+ PyObject *self_or_null;
PyObject **args;
_PyInterpreterFrame *new_frame;
/* Skip 1 cache entry */
@@ -1868,14 +1873,19 @@
{
DEOPT_IF(tstate->interp->eval_frame, CALL);
}
- // _CHECK_FUNCTION_EXACT_ARGS
- self_or_null = stack_pointer[-1 - oparg];
+ // _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);
+ }
+ // _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;
DEOPT_IF(code->co_argcount != oparg + (self_or_null != NULL),
CALL);
}
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index e5c982befb2411..a2cb4c0b2c5192 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -519,10 +519,9 @@ dummy_func(void) {
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);
(void)self_or_null;
- (void)func_version;
}
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] --
callable, null, unused[oparg])) {
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 30ed011a83eb6e..4d5c8032cb33cf 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -1537,10 +1537,8 @@
_Py_UopsSymbol *callable;
self_or_null = stack_pointer[-1 - oparg];
callable = stack_pointer[-2 - oparg];
- uint32_t func_version = (uint32_t)this_instr->operand;
sym_set_type(callable, &PyFunction_Type);
(void)self_or_null;
- (void)func_version;
break;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]