8000 GH-104584: Don't call executors from JUMP_BACKWARD (GH-109347) · python/cpython@6c13e13 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6c13e13

Browse files
authored
GH-104584: Don't call executors from JUMP_BACKWARD (GH-109347)
1 parent 22e65ee commit 6c13e13

File tree

4 files changed

+23
-40
lines changed

4 files changed

+23
-40
lines changed

Include/cpython/optimizer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ PyAPI_FUNC(_PyOptimizerObject *) PyUnstable_GetOptimizer(void);
4040

4141
PyAPI_FUNC(_PyExecutorObject *) PyUnstable_GetExecutor(PyCodeObject *code, int offset);
4242

43-
struct _PyInterpreterFrame *
43+
int
4444
_PyOptimizer_BackEdge(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer);
4545

4646
extern _PyOptimizerObject _PyOptimizer_Default;

Python/bytecodes.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,21 +2242,17 @@ dummy_func(
22422242
here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
22432243
if (here[1].cache > tstate->interp->optimizer_backedge_threshold &&
22442244
// Double-check that the opcode isn't instrumented or something:
2245-
here->op.code == JUMP_BACKWARD &&
2246-
// _PyOptimizer_BackEdge is going to change frame->prev_instr,
2247-
// which breaks line event calculations:
2248-
next_instr->op.code != INSTRUMENTED_LINE
2249-
)
2245+
here->op.code == JUMP_BACKWARD)
22502246
{
22512247
OBJECT_STAT_INC(optimization_attempts);
2252-
frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
2253-
if (frame == NULL) {
2254-
frame = tstate->current_frame;
2255-
goto resume_with_error;
2248+
int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
2249+
ERROR_IF(optimized < 0, error);
2250+
if (optimized) {
2251+
// Rewind and enter the executor:
2252+
assert(here->op.code == ENTER_EXECUTOR);
2253+
next_instr = here;
22562254
}
2257-
assert(frame == tstate->current_frame);
2258-
here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1);
2259-
goto resume_frame;
2255+
here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
22602256
}
22612257
#endif /* ENABLE_SPECIALIZATION */
22622258
}

Python/generated_cases.c.h

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

Python/optimizer.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,26 +154,22 @@ PyUnstable_SetOptimizer(_PyOptimizerObject *optimizer)
154154
Py_DECREF(old);
155155
}
156156

157-
_PyInterpreterFrame *
157+
int
158158
_PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer)
159159
{
160160
assert(src->op.code == JUMP_BACKWARD);
161161
PyCodeObject *code = (PyCodeObject *)frame->f_executable;
162162
assert(PyCode_Check(code));
163163
PyInterpreterState *interp = _PyInterpreterState_GET();
164164
if (!has_space_for_executor(code, src)) {
165-
goto jump_to_destination;
165+
return 0;
166166
}
167167
_PyOptimizerObject *opt = interp->optimizer;
168168
_PyExecutorObject *executor = NULL;
169169
int err = opt->optimize(opt, code, dest, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame)));
170170
if (err <= 0) {
171171
assert(executor == NULL);
172-
if (err < 0) {
173-
_PyFrame_SetStackPointer(frame, stack_pointer);
174-
return NULL;
175-
}
176-
goto jump_to_destination;
172+
return err;
177173
}
178174
int index = get_index_for_executor(code, src);
179175
if (index < 0) {
@@ -184,16 +180,11 @@ _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNI
184180
* it might get confused by the executor disappearing,
185181
* but there is not much we can do about that here. */
186182
Py_DECREF(executor);
187-
goto jump_to_destination;
183+
return 0;
188184
}
189185
insert_executor(code, src, index, executor);
190-
assert(frame->prev_instr == src);
191-
frame->prev_instr = dest - 1;
192-
return executor->execute(executor, frame, stack_pointer);
193-
jump_to_destination:
194-
frame->prev_instr = dest - 1;
195-
_PyFrame_SetStackPointer(frame, stack_pointer);
196-
return frame;
186+
Py_DECREF(executor);
187+
return 1;
197188
}
198189

199190
_PyExecutorObject *

0 commit comments

Comments
 (0)
0