mirror of
https://github.com/python/cpython.git
synced 2025-11-24 12:20:42 +00:00
[3.14] gh-140936: Fix JIT assertion crash at finalization if some generator is alive (GH-140969) (GH-141494)
gh-140936: Fix JIT assertion crash at finalization if some generator is alive (GH-140969)
This commit is contained in:
parent
425e423f9f
commit
48b7d75aaf
2 changed files with 28 additions and 1 deletions
|
|
@ -1972,6 +1972,26 @@ class TestUopsOptimization(unittest.TestCase):
|
||||||
assert ex is not None
|
assert ex is not None
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
def test_interpreter_finalization_with_generator_alive(self):
|
||||||
|
script_helper.assert_python_ok("-c", textwrap.dedent("""
|
||||||
|
import sys
|
||||||
|
t = tuple(range(%d))
|
||||||
|
def simple_for():
|
||||||
|
for x in t:
|
||||||
|
x
|
||||||
|
|
||||||
|
def gen():
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
except:
|
||||||
|
simple_for()
|
||||||
|
|
||||||
|
sys.settrace(lambda *args: None)
|
||||||
|
simple_for()
|
||||||
|
g = gen()
|
||||||
|
next(g)
|
||||||
|
""" % _testinternalcapi.SPECIALIZATION_THRESHOLD))
|
||||||
|
|
||||||
|
|
||||||
def global_identity(x):
|
def global_identity(x):
|
||||||
return x
|
return x
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,14 @@ _PyOptimizer_Optimize(
|
||||||
_PyExecutorObject **executor_ptr, int chain_depth)
|
_PyExecutorObject **executor_ptr, int chain_depth)
|
||||||
{
|
{
|
||||||
_PyStackRef *stack_pointer = frame->stackpointer;
|
_PyStackRef *stack_pointer = frame->stackpointer;
|
||||||
assert(_PyInterpreterState_GET()->jit);
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
if (!interp->jit) {
|
||||||
|
// gh-140936: It is possible that interp->jit will become false during
|
||||||
|
// interpreter finalization. However, the specialized JUMP_BACKWARD_JIT
|
||||||
|
// instruction may still be present. In this case, we should
|
||||||
|
// return immediately without optimization.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// The first executor in a chain and the MAX_CHAIN_DEPTH'th executor *must*
|
// The first executor in a chain and the MAX_CHAIN_DEPTH'th executor *must*
|
||||||
// make progress in order to avoid infinite loops or excessively-long
|
// make progress in order to avoid infinite loops or excessively-long
|
||||||
// side-exit chains. We can only insert the executor into the bytecode if
|
// side-exit chains. We can only insert the executor into the bytecode if
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue