gh-146261: JIT: protect against function version changes (#146300)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Ken Jin 2026-04-13 02:23:47 +08:00 committed by GitHub
parent 1e79bf6c05
commit 6f7bb297db
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 64 additions and 189 deletions

View file

@ -1001,12 +1001,15 @@ dummy_func(void) {
}
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
if (sym_get_func_version(callable) == func_version) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
else {
sym_set_func_version(ctx, callable, func_version);
PyObject *func = sym_get_probable_value(callable);
if (func == NULL || !PyFunction_Check(func) || ((PyFunctionObject *)func)->func_version != func_version) {
ctx->contradiction = true;
ctx->done = true;
break;
}
// Guarded on this, so it can be promoted.
sym_set_const(callable, func);
_Py_BloomFilter_Add(dependencies, func);
}
op(_CHECK_METHOD_VERSION, (func_version/2, callable, null, unused[oparg] -- callable, null, unused[oparg])) {
@ -2229,7 +2232,8 @@ dummy_func(void) {
if (co->co_version == version) {
_Py_BloomFilter_Add(dependencies, co);
// Functions derive their version from code objects.
if (sym_get_func_version(ctx->frame->callable) == version) {
PyFunctionObject *func = (PyFunctionObject *)sym_get_const(ctx, ctx->frame->callable);
if (func != NULL && func->func_version == version) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
}
@ -2262,7 +2266,8 @@ dummy_func(void) {
op(_GUARD_IP__PUSH_FRAME, (ip/4 --)) {
(void)ip;
stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer);
if (sym_get_func_version(ctx->frame->callable) != 0 &&
PyFunctionObject *func = (PyFunctionObject *)sym_get_const(ctx, ctx->frame->callable);
if (func != NULL && func->func_version != 0 &&
// We can remove this guard for simple function call targets.
(((PyCodeObject *)ctx->frame->func->func_code)->co_flags &
(CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) == 0) {