From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Sat, 8 Nov 2025 02:20:14 +0000 (+0000) Subject: Fix a few perf regressions due to tracing thru optimizer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f547880dc785dd6a02a33c0a789f53fd9245cf1f;p=thirdparty%2FPython%2Fcpython.git Fix a few perf regressions due to tracing thru optimizer --- diff --git a/Python/optimizer.c b/Python/optimizer.c index f1d0ca811c7e..e73753ca8305 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -865,7 +865,9 @@ _PyJit_translate_single_bytecode_to_trace( operand = 0; if (frame->owner < FRAME_OWNED_BY_INTERPRETER) { - if (new_func != NULL) { + // Don't add nested code objects to the dependency. + // It causes endless re-traces. + if (new_func != NULL && !(new_code->co_flags & CO_NESTED)) { operand = (uintptr_t)new_func; DPRINTF(2, "Adding %p func to op\n", (void *)operand); _Py_BloomFilter_Add(dependencies, new_func); diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 16bb8b85a390..a8b58dbaa1e6 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -752,8 +752,14 @@ dummy_func(void) { } op(_PY_FRAME_KW, (callable, self_or_null, args[oparg], kwnames -- new_frame)) { - new_frame = PyJitRef_NULL; - ctx->done = true; + assert((this_instr + 2)->opcode == _PUSH_FRAME); + PyCodeObject *co = get_code_with_logging((this_instr + 2)); + if (co == NULL) { + ctx->done = true; + break; + } + + new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0)); } op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, args[oparg] -- callable, self_or_null, args[oparg])) { @@ -882,16 +888,16 @@ dummy_func(void) { ctx->curr_frame_depth++; stack_pointer = ctx->frame->stack_pointer; uint64_t operand = this_instr->operand0; - if (operand == 0 || (operand & 1)) { - // It's either a code object or NULL + if (operand == 0) { ctx->done = true; break; } - PyFunctionObject *func = (PyFunctionObject *)operand; - PyCodeObject *co = (PyCodeObject *)func->func_code; - _Py_BloomFilter_Add(dependencies, co); - assert(PyFunction_Check(func)); - ctx->frame->func = func; + if (!(operand & 1)) { + PyFunctionObject *func = (PyFunctionObject *)operand; + PyCodeObject *co = (PyCodeObject *)func->func_code; + _Py_BloomFilter_Add(dependencies, co); + ctx->frame->func = func; + } } op(_UNPACK_SEQUENCE, (seq -- values[oparg], top[0])) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 74c824e7bc90..879758e3e4fb 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2629,15 +2629,16 @@ ctx->curr_frame_depth++; stack_pointer = ctx->frame->stack_pointer; uint64_t operand = this_instr->operand0; - if (operand == 0 || (operand & 1)) { + if (operand == 0) { ctx->done = true; break; } - PyFunctionObject *func = (PyFunctionObject *)operand; - PyCodeObject *co = (PyCodeObject *)func->func_code; - _Py_BloomFilter_Add(dependencies, co); - assert(PyFunction_Check(func)); - ctx->frame->func = func; + if (!(operand & 1)) { + PyFunctionObject *func = (PyFunctionObject *)operand; + PyCodeObject *co = (PyCodeObject *)func->func_code; + _Py_BloomFilter_Add(dependencies, co); + ctx->frame->func = func; + } break; } @@ -2972,8 +2973,13 @@ case _PY_FRAME_KW: { JitOptRef new_frame; - new_frame = PyJitRef_NULL; - ctx->done = true; + assert((this_instr + 2)->opcode == _PUSH_FRAME); + PyCodeObject *co = get_code_with_logging((this_instr + 2)); + if (co == NULL) { + ctx->done = true; + break; + } + new_frame = PyJitRef_Wrap((JitOptSymbol *)frame_new(ctx, co, 0, NULL, 0)); stack_pointer[-3 - oparg] = new_frame; stack_pointer += -2 - oparg; assert(WITHIN_STACK_BOUNDS());