Skip to content

Commit baf8971

Browse files
JIT: Borrow references for immortal promoted globals
1 parent 8b64dd8 commit baf8971

File tree

3 files changed

+62
-4
lines changed

3 files changed

+62
-4
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,6 +2972,44 @@ class Obj:
29722972
for _ in range(TIER2_THRESHOLD+1):
29732973
obj.attr = EvilAttr(obj.__dict__)
29742974

2975+
def test_promoted_global_refcount_eliminated(self):
2976+
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
2977+
import _testinternalcapi
2978+
import opcode
2979+
import _opcode
2980+
2981+
def get_first_executor(func):
2982+
code = func.__code__
2983+
co_code = code.co_code
2984+
for i in range(0, len(co_code), 2):
2985+
try:
2986+
return _opcode.get_executor(code, i)
2987+
except ValueError:
2988+
pass
2989+
return None
2990+
2991+
def get_opnames(ex):
2992+
return {item[0] for item in ex}
2993+
2994+
2995+
def testfunc(n):
2996+
y = []
2997+
for i in range(n):
2998+
x = tuple(y)
2999+
return x
3000+
3001+
testfunc(_testinternalcapi.TIER2_THRESHOLD)
3002+
3003+
ex = get_first_executor(testfunc)
3004+
assert ex is not None
3005+
uops = get_opnames(ex)
3006+
assert "_LOAD_GLOBAL_BUILTIN" not in uops
3007+
assert "_LOAD_CONST_INLINE_BORROW" in uops
3008+
assert "_POP_TOP_NOP" in uops
3009+
assert "_POP_TOP" not in uops
3010+
"""), PYTHON_JIT="1")
3011+
self.assertEqual(result[0].rc, 0, result)
3012+
29753013

29763014
def global_identity(x):
29773015
return x

Python/optimizer_bytecodes.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,12 @@ dummy_func(void) {
13701370
res = sym_new_not_null(ctx);
13711371
}
13721372
else {
1373-
res = sym_new_const(ctx, cnst);
1373+
if (_Py_IsImmortal(cnst)) {
1374+
res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
1375+
}
1376+
else {
1377+
res = sym_new_const(ctx, cnst);
1378+
}
13741379
}
13751380
}
13761381

@@ -1405,7 +1410,12 @@ dummy_func(void) {
14051410
res = sym_new_not_null(ctx);
14061411
}
14071412
else {
1408-
res = sym_new_const(ctx, cnst);
1413+
if (_Py_IsImmortal(cnst)) {
1414+
res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
1415+
}
1416+
else {
1417+
res = sym_new_const(ctx, cnst);
1418+
}
14091419
}
14101420
}
14111421

Python/optimizer_cases.c.h

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)