class TestOptimizerAPI(unittest.TestCase):
- def test_get_counter_optimizer_dealloc(self):
+ def test_new_counter_optimizer_dealloc(self):
# See gh-108727
def f():
- _testinternalcapi.get_counter_optimizer()
+ _testinternalcapi.new_counter_optimizer()
f()
def test_get_set_optimizer(self):
old = _testinternalcapi.get_optimizer()
- opt = _testinternalcapi.get_counter_optimizer()
+ opt = _testinternalcapi.new_counter_optimizer()
try:
_testinternalcapi.set_optimizer(opt)
self.assertEqual(_testinternalcapi.get_optimizer(), opt)
loop = ns['loop']
for repeat in range(5):
- opt = _testinternalcapi.get_counter_optimizer()
+ opt = _testinternalcapi.new_counter_optimizer()
with temporary_optimizer(opt):
self.assertEqual(opt.get_count(), 0)
with clear_executors(loop):
"""), ns, ns)
long_loop = ns['long_loop']
- opt = _testinternalcapi.get_counter_optimizer()
+ opt = _testinternalcapi.new_counter_optimizer()
with temporary_optimizer(opt):
self.assertEqual(opt.get_count(), 0)
long_loop()
while i < x:
i += 1
- opt = _testinternalcapi.get_counter_optimizer()
+ opt = _testinternalcapi.new_counter_optimizer()
with temporary_optimizer(opt):
testfunc(1000)
code, replace_code = testfunc.__code__, testfunc.__code__.replace()
return None
+def iter_opnames(ex):
+ for item in ex:
+ yield item[0]
+
+
+def get_opnames(ex):
+ return set(iter_opnames(ex))
+
+
class TestExecutorInvalidation(unittest.TestCase):
def setUp(self):
self.old = _testinternalcapi.get_optimizer()
- self.opt = _testinternalcapi.get_counter_optimizer()
+ self.opt = _testinternalcapi.new_counter_optimizer()
_testinternalcapi.set_optimizer(self.opt)
def tearDown(self):
pass
"""), ns, ns)
f = ns['f']
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
f()
exe = get_first_executor(f)
def f():
for _ in range(1000):
pass
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
f()
exe = get_first_executor(f)
while i < x:
i += 1
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(1000)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_SET_IP", uops)
self.assertIn("_LOAD_FAST_0", uops)
"""), ns, ns)
many_vars = ns["many_vars"]
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
ex = get_first_executor(many_vars)
self.assertIsNone(ex)
ex = get_first_executor(many_vars)
self.assertIsNotNone(ex)
- self.assertIn(("_LOAD_FAST", 259, 0), list(ex))
+ self.assertTrue(any((opcode, oparg, operand) == ("_LOAD_FAST", 259, 0)
+ for opcode, oparg, _, operand in list(ex)))
def test_unspecialized_unpack(self):
# An example of an unspecialized opcode
while i < x:
i += 1
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_UNPACK_SEQUENCE", uops)
def test_pop_jump_if_false(self):
while i < n:
i += 1
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_IS_TRUE_POP", uops)
def test_pop_jump_if_none(self):
if x is None:
x = 0
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(range(20))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_IS_NOT_NONE_POP", uops)
def test_pop_jump_if_not_none(self):
if x is not None:
x = 0
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(range(20))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_IS_NONE_POP", uops)
def test_pop_jump_if_true(self):
while not i >= n:
i += 1
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_IS_FALSE_POP", uops)
def test_jump_backward(self):
while i < n:
i += 1
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_JUMP_TO_TOP", uops)
def test_jump_forward(self):
a += 1
return a
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
# Since there is no JUMP_FORWARD instruction,
# look for indirect evidence: the += operator
self.assertIn("_BINARY_OP_ADD_INT", uops)
total += i
return total
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
total = testfunc(20)
self.assertEqual(total, 190)
self.assertIsNotNone(ex)
# for i, (opname, oparg) in enumerate(ex):
# print(f"{i:4d}: {opname:<20s} {oparg:3d}")
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_NOT_EXHAUSTED_RANGE", uops)
# Verification that the jump goes past END_FOR
# is done by manual inspection of the output
total += i
return total
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
a = list(range(20))
total = testfunc(a)
self.assertIsNotNone(ex)
# for i, (opname, oparg) in enumerate(ex):
# print(f"{i:4d}: {opname:<20s} {oparg:3d}")
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_NOT_EXHAUSTED_LIST", uops)
# Verification that the jump goes past END_FOR
# is done by manual inspection of the output
total += i
return total
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
a = tuple(range(20))
total = testfunc(a)
self.assertIsNotNone(ex)
# for i, (opname, oparg) in enumerate(ex):
# print(f"{i:4d}: {opname:<20s} {oparg:3d}")
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_NOT_EXHAUSTED_TUPLE", uops)
# Verification that the jump goes past END_FOR
# is done by manual inspection of the output
for x in it:
pass
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
a = [1, 2, 3]
it = iter(a)
for i in range(n):
dummy(i)
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_PUSH_FRAME", uops)
self.assertIn("_BINARY_OP_ADD_INT", uops)
else:
i = 1
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_IS_FALSE_POP", uops)
def test_for_iter_tier_two(self):
x += 1000*i + j
return x
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
x = testfunc(10, 10)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_FOR_ITER_TIER_TWO", uops)
def test_confidence_score(self):
bits += 1
return bits
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
x = testfunc(20)
self.assertEqual(x, 40)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
- ops = [opname for opname, _, _ in ex]
+ ops = list(iter_opnames(ex))
#Since branch is 50/50 the trace could go either way.
count = ops.count("_GUARD_IS_TRUE_POP") + ops.count("_GUARD_IS_FALSE_POP")
self.assertLessEqual(count, 2)
def _run_with_optimizer(self, testfunc, arg):
res = None
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
with temporary_optimizer(opt):
res = testfunc(arg)
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertIsNotNone(ex)
self.assertEqual(res, 63)
- binop_count = [opname for opname, _, _ in ex if opname == "_BINARY_OP_ADD_INT"]
- guard_both_int_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_INT"]
+ binop_count = [opname for opname in iter_opnames(ex) if opname == "_BINARY_OP_ADD_INT"]
+ guard_both_int_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_INT"]
self.assertGreaterEqual(len(binop_count), 3)
self.assertLessEqual(len(guard_both_int_count), 1)
num += 1
return a
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
res = None
with temporary_optimizer(opt):
res = testfunc(32)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
self.assertEqual(res, 124)
- binop_count = [opname for opname, _, _ in ex if opname == "_BINARY_OP_ADD_INT"]
- guard_both_int_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_INT"]
+ binop_count = [opname for opname in iter_opnames(ex) if opname == "_BINARY_OP_ADD_INT"]
+ guard_both_int_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_INT"]
self.assertGreaterEqual(len(binop_count), 3)
self.assertLessEqual(len(guard_both_int_count), 1)
num += 1
return x
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
res = None
with temporary_optimizer(opt):
res = testfunc(32)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
self.assertEqual(res, 124)
- binop_count = [opname for opname, _, _ in ex if opname == "_BINARY_OP_ADD_INT"]
- guard_both_int_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_INT"]
+ binop_count = [opname for opname in iter_opnames(ex) if opname == "_BINARY_OP_ADD_INT"]
+ guard_both_int_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_INT"]
self.assertGreaterEqual(len(binop_count), 3)
self.assertLessEqual(len(guard_both_int_count), 1)
res, ex = self._run_with_optimizer(testfunc, 64)
self.assertIsNotNone(ex)
- binop_count = [opname for opname, _, _ in ex if opname == "_BINARY_OP_ADD_INT"]
+ binop_count = [opname for opname in iter_opnames(ex) if opname == "_BINARY_OP_ADD_INT"]
self.assertGreaterEqual(len(binop_count), 3)
def test_call_py_exact_args(self):
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_PUSH_FRAME", uops)
self.assertIn("_BINARY_OP_ADD_INT", uops)
self.assertNotIn("_CHECK_PEP_523", uops)
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertEqual(res, 62)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertNotIn("_GUARD_BOTH_INT", uops)
def test_int_value_numbering(self):
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertEqual(res, 4)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertIn("_GUARD_BOTH_INT", uops)
- guard_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_INT"]
+ guard_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_INT"]
self.assertEqual(len(guard_count), 1)
def test_comprehension(self):
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertEqual(res, list(range(32)))
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
self.assertNotIn("_BINARY_OP_ADD_INT", uops)
def test_call_py_exact_args_disappearing(self):
for i in range(n):
dummy(i)
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
# Trigger specialization
testfunc(8)
with temporary_optimizer(opt):
pass
return None
+ def get_opnames(ex):
+ return {item[0] for item in ex}
+
def testfunc(n):
for i in range(n):
x = range(i)
return x
- opt = _testinternalcapi.get_uop_optimizer()
+ opt = _testinternalcapi.new_uop_optimizer()
_testinternalcapi.set_optimizer(opt)
testfunc(64)
ex = get_first_executor(testfunc)
assert ex is not None
- uops = {opname for opname, _, _ in ex}
+ uops = get_opnames(ex)
assert "_LOAD_GLOBAL_BUILTINS" not in uops
assert "_LOAD_CONST_INLINE_BORROW_WITH_NULL" in uops
"""))
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertAlmostEqual(res, 4.2)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
- guard_both_float_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_FLOAT"]
+ uops = get_opnames(ex)
+ guard_both_float_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_FLOAT"]
self.assertLessEqual(len(guard_both_float_count), 1)
# TODO gh-115506: this assertion may change after propagating constants.
# We'll also need to verify that propagation actually occurs.
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertAlmostEqual(res, -2.2)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
- guard_both_float_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_FLOAT"]
+ uops = get_opnames(ex)
+ guard_both_float_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_FLOAT"]
self.assertLessEqual(len(guard_both_float_count), 1)
# TODO gh-115506: this assertion may change after propagating constants.
# We'll also need to verify that propagation actually occurs.
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertAlmostEqual(res, 2 ** 32)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
- guard_both_float_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_FLOAT"]
+ uops = get_opnames(ex)
+ guard_both_float_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_FLOAT"]
self.assertLessEqual(len(guard_both_float_count), 1)
# TODO gh-115506: this assertion may change after propagating constants.
# We'll also need to verify that propagation actually occurs.
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertTrue(res)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
- guard_both_float_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_FLOAT"]
+ uops = get_opnames(ex)
+ guard_both_float_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_FLOAT"]
self.assertLessEqual(len(guard_both_float_count), 1)
self.assertIn("_COMPARE_OP_FLOAT", uops)
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertTrue(res)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
- guard_both_float_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_INT"]
+ uops = get_opnames(ex)
+ guard_both_float_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_INT"]
self.assertLessEqual(len(guard_both_float_count), 1)
self.assertIn("_COMPARE_OP_INT", uops)
res, ex = self._run_with_optimizer(testfunc, 32)
self.assertTrue(res)
self.assertIsNotNone(ex)
- uops = {opname for opname, _, _ in ex}
- guard_both_float_count = [opname for opname, _, _ in ex if opname == "_GUARD_BOTH_UNICODE"]
+ uops = get_opnames(ex)
+ guard_both_float_count = [opname for opname in iter_opnames(ex) if opname == "_GUARD_BOTH_UNICODE"]
self.assertLessEqual(len(guard_both_float_count), 1)
self.assertIn("_COMPARE_OP_STR", uops)
extern const struct _PyCode_DEF(8) _Py_InitCleanup;
-extern const char *_PyUOpName(int index);
+#ifdef Py_DEBUG
+extern void _PyUOpPrint(const _PyUOpInstruction *uop);
+#endif
+
/* Disable unused label warnings. They are handy for debugging, even
if computed gotos aren't used. */
assert(next_uop->opcode == _START_EXECUTOR || next_uop->opcode == _COLD_EXIT);
for (;;) {
uopcode = next_uop->opcode;
- DPRINTF(3,
- "%4d: uop %s, oparg %d, operand %" PRIu64 ", target %d, stack_level %d\n",
- (int)(next_uop - (current_executor == NULL ? next_uop : current_executor->trace)),
- _PyUOpName(uopcode),
- next_uop->oparg,
- next_uop->operand,
- next_uop->target,
+#ifdef Py_DEBUG
+ if (lltrace >= 3) {
+ printf("%4d uop: ", (int)(next_uop - (current_executor == NULL ? next_uop : current_executor->trace)));
+ _PyUOpPrint(next_uop);
+ printf(" stack_level=%d\n",
(int)(stack_pointer - _PyFrame_Stackbase(frame)));
+ }
+#endif
next_uop++;
OPT_STAT_INC(uops_executed);
UOP_STAT_INC(uopcode, execution_count);
default:
#ifdef Py_DEBUG
{
- fprintf(stderr, "Unknown uop %d, oparg %d, operand %" PRIu64 " @ %d\n",
- next_uop[-1].opcode, next_uop[-1].oparg, next_uop[-1].operand,
- (int)(next_uop - (current_executor == NULL ? next_uop : current_executor->trace) - 1));
+ printf("Unknown uop: ");
+ _PyUOpPrint(&next_uop[-1]);
+ printf(" @ %d\n", (int)(next_uop - current_executor->trace - 1));
Py_FatalError("Unknown uop");
}
#else
pop_1_error_tier_two:
STACK_SHRINK(1);
error_tier_two:
- DPRINTF(2, "Error: [UOp %d (%s), oparg %d, operand %" PRIu64 ", target %d @ %d -> %s]\n",
- uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target,
- (int)(next_uop - current_executor->trace - 1),
- _PyOpcode_OpName[frame->instr_ptr->op.code]);
+#ifdef Py_DEBUG
+ if (lltrace >= 2) {
+ printf("Error: [UOp ");
+ _PyUOpPrint(&next_uop[-1]);
+ printf(" @ %d -> %s]\n",
+ (int)(next_uop - current_executor->trace - 1),
+ _PyOpcode_OpName[frame->instr_ptr->op.code]);
+ }
+#endif
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
frame->return_offset = 0; // Don't leave this random
_PyFrame_SetStackPointer(frame, stack_pointer);
// Jump here from DEOPT_IF()
deoptimize:
next_instr = next_uop[-1].target + _PyCode_CODE(_PyFrame_GetCode(frame));
- DPRINTF(2, "DEOPT: [UOp %d (%s), oparg %d, operand %" PRIu64 ", target %d -> %s]\n",
- uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, next_uop[-1].target,
- _PyOpcode_OpName[next_instr->op.code]);
+#ifdef Py_DEBUG
+ if (lltrace >= 2) {
+ printf("DEOPT: [UOp ");
+ _PyUOpPrint(&next_uop[-1]);
+ printf(" -> %s]\n",
+ _PyOpcode_OpName[frame->instr_ptr->op.code]);
+ }
+#endif
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
UOP_STAT_INC(uopcode, miss);
Py_DECREF(current_executor);
uint32_t exit_index = next_uop[-1].exit_index;
assert(exit_index < current_executor->exit_count);
_PyExitData *exit = ¤t_executor->exits[exit_index];
- DPRINTF(2, "SIDE EXIT: [UOp %d (%s), oparg %d, operand %" PRIu64 ", exit %u, temp %d, target %d -> %s]\n",
- uopcode, _PyUOpName(uopcode), next_uop[-1].oparg, next_uop[-1].operand, exit_index, exit->temperature,
- exit->target, _PyOpcode_OpName[_PyCode_CODE(_PyFrame_GetCode(frame))[exit->target].op.code]);
+#ifdef Py_DEBUG
+ if (lltrace >= 2) {
+ printf("SIDE EXIT: [UOp ");
+ _PyUOpPrint(&next_uop[-1]);
+ printf(", exit %u, temp %d, target %d -> %s]\n",
+ exit_index, exit->temperature, exit->target,
+ _PyOpcode_OpName[frame->instr_ptr->op.code]);
+ }
+#endif
Py_INCREF(exit->executor);
tstate->previous_executor = (PyObject *)current_executor;
GOTO_TIER_TWO(exit->executor);