Skip to content

Commit a9d68f3

Browse files
[3.13] pythonGH-123545: Remove duplicate Py_DECREF when handling _PyOptimizer_Optimize errors (pythonGH-123546)
(cherry picked from commit 1fbc118) Co-authored-by: Savannah Ostrowski <[email protected]>
1 parent 8ed77c1 commit a9d68f3

File tree

3 files changed

+100
-6
lines changed

3 files changed

+100
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a double decref in rare cases on experimental JIT builds.

Python/bytecodes.c

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4224,8 +4224,54 @@ dummy_func(
42244224
#endif
42254225
}
42264226

4227-
tier2 op(_EXIT_TRACE, (--)) {
4228-
EXIT_TO_TRACE();
4227+
tier2 op(_EXIT_TRACE, (exit_p/4 --)) {
4228+
_PyExitData *exit = (_PyExitData *)exit_p;
4229+
PyCodeObject *code = _PyFrame_GetCode(frame);
4230+
_Py_CODEUNIT *target = _PyCode_CODE(code) + exit->target;
4231+
#if defined(Py_DEBUG) && !defined(_Py_JIT)
4232+
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
4233+
if (lltrace >= 2) {
4234+
printf("SIDE EXIT: [UOp ");
4235+
_PyUOpPrint(&next_uop[-1]);
4236+
printf(", exit %u, temp %d, target %d -> %s]\n",
4237+
exit - current_executor->exits, exit->temperature.as_counter,
4238+
(int)(target - _PyCode_CODE(code)),
4239+
_PyOpcode_OpName[target->op.code]);
4240+
}
4241+
#endif
4242+
if (exit->executor && !exit->executor->vm_data.valid) {
4243+
exit->temperature = initial_temperature_backoff_counter();
4244+
Py_CLEAR(exit->executor);
4245+
}
4246+
if (exit->executor == NULL) {
4247+
_Py_BackoffCounter temperature = exit->temperature;
4248+
if (!backoff_counter_triggers(temperature)) {
4249+
exit->temperature = advance_backoff_counter(temperature);
4250+
tstate->previous_executor = (PyObject *)current_executor;
4251+
GOTO_TIER_ONE(target);
4252+
}
4253+
_PyExecutorObject *executor;
4254+
if (target->op.code == ENTER_EXECUTOR) {
4255+
executor = code->co_executors->executors[target->op.arg];
4256+
Py_INCREF(executor);
4257+
}
4258+
else {
4259+
int chain_depth = current_executor->vm_data.chain_depth + 1;
4260+
int optimized = _PyOptimizer_Optimize(frame, target, stack_pointer, &executor, chain_depth);
4261+
if (optimized <= 0) {
4262+
exit->temperature = restart_backoff_counter(temperature);
4263+
if (optimized < 0) {
4264+
GOTO_UNWIND();
4265+
}
4266+
tstate->previous_executor = (PyObject *)current_executor;
4267+
GOTO_TIER_ONE(target);
4268+
}
4269+
}
4270+
exit->executor = executor;
4271+
}
4272+
Py_INCREF(exit->executor);
4273+
tstate->previous_executor = (PyObject *)current_executor;
4274+
GOTO_TIER_TWO(exit->executor);
42294275
}
42304276

42314277
tier2 op(_CHECK_VALIDITY, (--)) {
@@ -4322,8 +4368,6 @@ dummy_func(
43224368
if (optimized <= 0) {
43234369
exit->temperature = restart_backoff_counter(exit->temperature);
43244370
if (optimized < 0) {
4325-
Py_DECREF(current_executor);
4326-
tstate->previous_executor = Py_None;
43274371
GOTO_UNWIND();
43284372
}
43294373
GOTO_TIER_ONE(target);

Python/executor_cases.c.h

Lines changed: 51 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)