Skip to content

Commit 6b4bc6e

Browse files
gh-134584: JIT: Borrow references for immortal promoted globals (GH-142921)
JIT: Borrow references for immortal promoted globals
1 parent 6a4f103 commit 6b4bc6e

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
@@ -3008,6 +3008,44 @@ class Obj:
30083008
for _ in range(TIER2_THRESHOLD+1):
30093009
obj.attr = EvilAttr(obj.__dict__)
30103010

3011+
def test_promoted_global_refcount_eliminated(self):
3012+
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
3013+
import _testinternalcapi
3014+
import opcode
3015+
import _opcode
3016+
3017+
def get_first_executor(func):
3018+
code = func.__code__
3019+
co_code = code.co_code
3020+
for i in range(0, len(co_code), 2):
3021+
try:
3022+
return _opcode.get_executor(code, i)
3023+
except ValueError:
3024+
pass
3025+
return None
3026+
3027+
def get_opnames(ex):
3028+
return {item[0] for item in ex}
3029+
3030+
3031+
def testfunc(n):
3032+
y = []
3033+
for i in range(n):
3034+
x = tuple(y)
3035+
return x
3036+
3037+
testfunc(_testinternalcapi.TIER2_THRESHOLD)
3038+
3039+
ex = get_first_executor(testfunc)
3040+
assert ex is not None
3041+
uops = get_opnames(ex)
3042+
assert "_LOAD_GLOBAL_BUILTIN" not in uops
3043+
assert "_LOAD_CONST_INLINE_BORROW" in uops
3044+
assert "_POP_TOP_NOP" in uops
3045+
assert "_POP_TOP" not in uops
3046+
"""), PYTHON_JIT="1")
3047+
self.assertEqual(result[0].rc, 0, result)
3048+
30113049
def test_constant_fold_tuple(self):
30123050
def testfunc(n):
30133051
for _ in range(n):

Python/optimizer_bytecodes.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,12 @@ dummy_func(void) {
13761376
res = sym_new_not_null(ctx);
13771377
}
13781378
else {
1379-
res = sym_new_const(ctx, cnst);
1379+
if (_Py_IsImmortal(cnst)) {
1380+
res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
1381+
}
1382+
else {
1383+
res = sym_new_const(ctx, cnst);
1384+
}
13801385
}
13811386
}
13821387

@@ -1411,7 +1416,12 @@ dummy_func(void) {
14111416
res = sym_new_not_null(ctx);
14121417
}
14131418
else {
1414-
res = sym_new_const(ctx, cnst);
1419+
if (_Py_IsImmortal(cnst)) {
1420+
res = PyJitRef_Borrow(sym_new_const(ctx, cnst));
1421+
}
1422+
else {
1423+
res = sym_new_const(ctx, cnst);
1424+
}
14151425
}
14161426
}
14171427

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)