From 4b401a7e61ab3e14524695f64d4c1645167d4cef Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Thu, 26 Mar 2026 11:42:11 +0530 Subject: [PATCH 1/4] optimize jit attribute loads on immutable types --- Python/optimizer_analysis.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 520420e9878575..73b76acdba435c 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -367,7 +367,10 @@ lookup_attr(JitOptContext *ctx, _PyBloomFilter *dependencies, _PyUOpInstruction if (type && PyType_Check(type)) { PyObject *lookup = _PyType_Lookup(type, name); if (lookup) { - int opcode = _Py_IsImmortal(lookup) ? immortal : mortal; + int opcode = mortal; + if (_Py_IsImmortal(lookup) || (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE)) { + opcode = immortal; + } ADD_OP(opcode, 0, (uintptr_t)lookup); PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type); _Py_BloomFilter_Add(dependencies, type); From 65cae767901682c5bd69824c6ef567deb87fcfe5 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Thu, 26 Mar 2026 14:39:27 +0530 Subject: [PATCH 2/4] add comment --- Python/optimizer_analysis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 73b76acdba435c..0c25c0c9bc0d1c 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -368,6 +368,7 @@ lookup_attr(JitOptContext *ctx, _PyBloomFilter *dependencies, _PyUOpInstruction PyObject *lookup = _PyType_Lookup(type, name); if (lookup) { int opcode = mortal; + // if the object is immortal or the type is immutable, borrowing is safe if (_Py_IsImmortal(lookup) || (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE)) { opcode = immortal; } From 8f860c9ccc1bea2d6798257d3ed6c826413b88ee Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Thu, 26 Mar 2026 14:45:47 +0530 Subject: [PATCH 3/4] improve test --- Lib/test/test_capi/test_opt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 1456296a13398b..bf9861468dc539 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3030,6 +3030,8 @@ def f(n): self.assertEqual(res, TIER2_THRESHOLD) uops = get_opnames(ex) self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops) + self.assertNotIn("_LOAD_CONST_UNDER_INLINE", uops) + self.assertIn("_LOAD_CONST_UNDER_INLINE_BORROW", uops) def test_store_fast_refcount_elimination(self): def foo(x): From 92658e4d2cf1e4287a2e0c4a9e6380b4b9917e17 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Thu, 26 Mar 2026 15:11:58 +0530 Subject: [PATCH 4/4] fix test_call_list_append --- Lib/test/test_capi/test_opt.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index bf9861468dc539..8aece4394c27d6 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -2792,9 +2792,6 @@ def testfunc(n): self.assertEqual(res, sum(range(TIER2_THRESHOLD))) uops = get_opnames(ex) self.assertIn("_CALL_LIST_APPEND", uops) - # We should remove these in the future - self.assertIn("_GUARD_NOS_LIST", uops) - self.assertIn("_GUARD_CALLABLE_LIST_APPEND", uops) def test_call_list_append_pop_top(self): def testfunc(n):