]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Fix a few perf regressions due to tracing thru optimizer
authorKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Sat, 8 Nov 2025 02:20:14 +0000 (02:20 +0000)
committerKen Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Sat, 8 Nov 2025 02:20:14 +0000 (02:20 +0000)
Python/optimizer.c
Python/optimizer_bytecodes.c
Python/optimizer_cases.c.h

index f1d0ca811c7e00bcff0bb3e1e89ec1cfe08629f7..e73753ca830558efafe347da45778f51e6c4acfe 100644 (file)
@@ -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);
index 16bb8b85a39081577c7dba026d0a5d320111ebf9..a8b58dbaa1e684808b614936f1379ea17353fec5 100644 (file)
@@ -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])) {
index 74c824e7bc905b7243deb392547d0181966886fb..879758e3e4fb6dfbd5af168a2278262c08041535 100644 (file)
             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;
         }
 
 
         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());