https://github.com/python/cpython/commit/6b4bc6e6a240966cfec488c25c83c40a101a94c8
commit: 6b4bc6e6a240966cfec488c25c83c40a101a94c8
branch: main
author: Ken Jin <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2025-12-19T19:06:34Z
summary:
gh-134584: JIT: Borrow references for immortal promoted globals (GH-142921)
JIT: Borrow references for immortal promoted globals
files:
M Lib/test/test_capi/test_opt.py
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py
index 9a822834c14f36..3ea93277dab295 100644
--- a/Lib/test/test_capi/test_opt.py
+++ b/Lib/test/test_capi/test_opt.py
@@ -3008,6 +3008,44 @@ class Obj:
for _ in range(TIER2_THRESHOLD+1):
obj.attr = EvilAttr(obj.__dict__)
+ def test_promoted_global_refcount_eliminated(self):
+ result = script_helper.run_python_until_end('-c', textwrap.dedent("""
+ import _testinternalcapi
+ import opcode
+ import _opcode
+
+ def get_first_executor(func):
+ code = func.__code__
+ co_code = code.co_code
+ for i in range(0, len(co_code), 2):
+ try:
+ return _opcode.get_executor(code, i)
+ except ValueError:
+ pass
+ return None
+
+ def get_opnames(ex):
+ return {item[0] for item in ex}
+
+
+ def testfunc(n):
+ y = []
+ for i in range(n):
+ x = tuple(y)
+ return x
+
+ testfunc(_testinternalcapi.TIER2_THRESHOLD)
+
+ ex = get_first_executor(testfunc)
+ assert ex is not None
+ uops = get_opnames(ex)
+ assert "_LOAD_GLOBAL_BUILTIN" not in uops
+ assert "_LOAD_CONST_INLINE_BORROW" in uops
+ assert "_POP_TOP_NOP" in uops
+ assert "_POP_TOP" not in uops
+ """), PYTHON_JIT="1")
+ self.assertEqual(result[0].rc, 0, result)
+
def test_constant_fold_tuple(self):
def testfunc(n):
for _ in range(n):
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index d2527fd85e3f12..cd789db1fe89d2 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -1376,7 +1376,12 @@ dummy_func(void) {
res = sym_new_not_null(ctx);
}
else {
- res = sym_new_const(ctx, cnst);
+ if (_Py_IsImmortal(cnst)) {
+ res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
+ }
+ else {
+ res = sym_new_const(ctx, cnst);
+ }
}
}
@@ -1411,7 +1416,12 @@ dummy_func(void) {
res = sym_new_not_null(ctx);
}
else {
- res = sym_new_const(ctx, cnst);
+ if (_Py_IsImmortal(cnst)) {
+ res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
+ }
+ else {
+ res = sym_new_const(ctx, cnst);
+ }
}
}
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 0389c6192e1cac..85d3d041215103 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -1330,7 +1330,12 @@
res = sym_new_not_null(ctx);
}
else {
- res = sym_new_const(ctx, cnst);
+ if (_Py_IsImmortal(cnst)) {
+ res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
+ }
+ else {
+ res = sym_new_const(ctx, cnst);
+ }
}
CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
@@ -1367,7 +1372,12 @@
res = sym_new_not_null(ctx);
}
else {
- res = sym_new_const(ctx, cnst);
+ if (_Py_IsImmortal(cnst)) {
+ res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
+ }
+ else {
+ res = sym_new_const(ctx, cnst);
+ }
}
CHECK_STACK_BOUNDS(1);
stack_pointer[0] = res;
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]