gh-146099: Optimize _GUARD_CODE_VERSION+IP via function version symbols (GH-146101)

This commit is contained in:
Ken Jin 2026-03-20 20:26:41 +08:00 committed by GitHub
parent 4507d496b4
commit acfb4528de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 279 additions and 40 deletions

View file

@ -864,12 +864,12 @@ dummy_func(void) {
}
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
if (sym_is_const(ctx, callable) && sym_matches_type(callable, &PyFunction_Type)) {
assert(PyFunction_Check(sym_get_const(ctx, callable)));
ADD_OP(_CHECK_FUNCTION_VERSION_INLINE, 0, func_version);
uop_buffer_last(&ctx->out_buffer)->operand1 = (uintptr_t)sym_get_const(ctx, callable);
if (sym_get_func_version(callable) == func_version) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
else {
sym_set_func_version(ctx, callable, func_version);
}
sym_set_type(callable, &PyFunction_Type);
}
op(_CHECK_METHOD_VERSION, (func_version/2, callable, null, unused[oparg] -- callable, null, unused[oparg])) {
@ -1779,12 +1779,47 @@ dummy_func(void) {
sym_set_recorded_gen_func(nos, func);
}
op(_GUARD_CODE_VERSION__PUSH_FRAME, (version/2 -- )) {
PyCodeObject *co = get_current_code_object(ctx);
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) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
}
else {
ctx->done = true;
}
}
op(_GUARD_CODE_VERSION_RETURN_VALUE, (version/2 -- )) {
if (ctx->frame->caller) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
}
op(_GUARD_CODE_VERSION_YIELD_VALUE, (version/2 -- )) {
if (ctx->frame->caller) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
}
op(_GUARD_CODE_VERSION_RETURN_GENERATOR, (version/2 -- )) {
if (ctx->frame->caller) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
}
op(_GUARD_IP__PUSH_FRAME, (ip/4 --)) {
(void)ip;
stack_pointer = sym_set_stack_depth((int)this_instr->operand1, stack_pointer);
// TO DO
// Normal function calls to known functions
// do not need an IP guard.
if (sym_get_func_version(ctx->frame->callable) != 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) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
}
op(_GUARD_IP_YIELD_VALUE, (ip/4 --)) {