Skip to content

Commit 3443edb

Browse files
committed
prevent executor self-links in JIT cold exits
1 parent d2f4649 commit 3443edb

4 files changed

Lines changed: 36 additions & 2 deletions

File tree

Include/internal/pycore_uop_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_capi/test_opt.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from test.support import (script_helper, requires_specialization,
1414
import_helper, Py_GIL_DISABLED, requires_jit_enabled,
15-
reset_code)
15+
reset_code, SHORT_TIMEOUT, isolation)
1616

1717
_testinternalcapi = import_helper.import_module("_testinternalcapi")
1818

@@ -6225,6 +6225,28 @@ def __exit__(self, e, v, t): ...
62256225
f1()
62266226
"""), PYTHON_JIT="1")
62276227

6228+
@isolation.runInSubprocess(timeout=SHORT_TIMEOUT)
6229+
def test_for_iter_side_exit_does_not_self_link(self):
6230+
def exhaust(iterator):
6231+
for _ in iterator:
6232+
pass
6233+
6234+
values = range(TIER2_THRESHOLD)
6235+
# After the initial trace, MAX_CHAIN_DEPTH side exits cause the final
6236+
# executor to be installed at FOR_ITER.
6237+
warmup_iterators = (
6238+
iter(set(values)),
6239+
iter(dict.fromkeys(values)),
6240+
iter(values),
6241+
enumerate(values),
6242+
zip(values, values),
6243+
)
6244+
for iterator in warmup_iterators:
6245+
exhaust(iterator)
6246+
6247+
# A different iterator type must not link that executor to itself.
6248+
exhaust(map(bool, values))
6249+
62286250
def global_identity(x):
62296251
return x
62306252

Python/bytecodes.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6262,6 +6262,10 @@ dummy_func(
62626262
if (target->op.code == ENTER_EXECUTOR) {
62636263
PyCodeObject *code = _PyFrame_GetCode(frame);
62646264
executor = code->co_executors->executors[target->op.arg];
6265+
if (executor == _PyExecutor_FromExit(exit)) {
6266+
_Py_ExecutorDetach(executor);
6267+
GOTO_TIER_ONE(target);
6268+
}
62656269
Py_INCREF(executor);
62666270
assert(tstate->jit_exit == exit);
62676271
exit->executor = executor;

Python/executor_cases.c.h

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

0 commit comments

Comments
 (0)