summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/cpython/optimizer.h2
-rw-r--r--Python/bytecodes.c20
-rw-r--r--Python/generated_cases.c.h20
-rw-r--r--Python/optimizer.c21
4 files changed, 23 insertions, 40 deletions
diff --git a/Include/cpython/optimizer.h b/Include/cpython/optimizer.h
index 10457af..4753610 100644
--- a/Include/cpython/optimizer.h
+++ b/Include/cpython/optimizer.h
@@ -40,7 +40,7 @@ PyAPI_FUNC(_PyOptimizerObject *) PyUnstable_GetOptimizer(void);
PyAPI_FUNC(_PyExecutorObject *) PyUnstable_GetExecutor(PyCodeObject *code, int offset);
-struct _PyInterpreterFrame *
+int
_PyOptimizer_BackEdge(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer);
extern _PyOptimizerObject _PyOptimizer_Default;
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index e5be62c..402b271 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2242,21 +2242,17 @@ dummy_func(
here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
if (here[1].cache > tstate->interp->optimizer_backedge_threshold &&
// Double-check that the opcode isn't instrumented or something:
- here->op.code == JUMP_BACKWARD &&
- // _PyOptimizer_BackEdge is going to change frame->prev_instr,
- // which breaks line event calculations:
- next_instr->op.code != INSTRUMENTED_LINE
- )
+ here->op.code == JUMP_BACKWARD)
{
OBJECT_STAT_INC(optimization_attempts);
- frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
- if (frame == NULL) {
- frame = tstate->current_frame;
- goto resume_with_error;
+ int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
+ ERROR_IF(optimized < 0, error);
+ if (optimized) {
+ // Rewind and enter the executor:
+ assert(here->op.code == ENTER_EXECUTOR);
+ next_instr = here;
}
- assert(frame == tstate->current_frame);
- here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1);
- goto resume_frame;
+ here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
}
#endif /* ENABLE_SPECIALIZATION */
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index fff47a1..ebb87a8 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -2945,21 +2945,17 @@
here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
if (here[1].cache > tstate->interp->optimizer_backedge_threshold &&
// Double-check that the opcode isn't instrumented or something:
- here->op.code == JUMP_BACKWARD &&
- // _PyOptimizer_BackEdge is going to change frame->prev_instr,
- // which breaks line event calculations:
- next_instr->op.code != INSTRUMENTED_LINE
- )
+ here->op.code == JUMP_BACKWARD)
{
OBJECT_STAT_INC(optimization_attempts);
- frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
- if (frame == NULL) {
- frame = tstate->current_frame;
- goto resume_with_error;
+ int optimized = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
+ if (optimized < 0) goto error;
+ if (optimized) {
+ // Rewind and enter the executor:
+ assert(here->op.code == ENTER_EXECUTOR);
+ next_instr = here;
}
- assert(frame == tstate->current_frame);
- here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) -1);
- goto resume_frame;
+ here[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1);
}
#endif /* ENABLE_SPECIALIZATION */
DISPATCH();
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 453e3e8..fbdbf72 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -154,7 +154,7 @@ PyUnstable_SetOptimizer(_PyOptimizerObject *optimizer)
Py_DECREF(old);
}
-_PyInterpreterFrame *
+int
_PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer)
{
assert(src->op.code == JUMP_BACKWARD);
@@ -162,18 +162,14 @@ _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNI
assert(PyCode_Check(code));
PyInterpreterState *interp = _PyInterpreterState_GET();
if (!has_space_for_executor(code, src)) {
- goto jump_to_destination;
+ return 0;
}
_PyOptimizerObject *opt = interp->optimizer;
_PyExecutorObject *executor = NULL;
int err = opt->optimize(opt, code, dest, &executor, (int)(stack_pointer - _PyFrame_Stackbase(frame)));
if (err <= 0) {
assert(executor == NULL);
- if (err < 0) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- return NULL;
- }
- goto jump_to_destination;
+ return err;
}
int index = get_index_for_executor(code, src);
if (index < 0) {
@@ -184,16 +180,11 @@ _PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNI
* it might get confused by the executor disappearing,
* but there is not much we can do about that here. */
Py_DECREF(executor);
- goto jump_to_destination;
+ return 0;
}
insert_executor(code, src, index, executor);
- assert(frame->prev_instr == src);
- frame->prev_instr = dest - 1;
- return executor->execute(executor, frame, stack_pointer);
-jump_to_destination:
- frame->prev_instr = dest - 1;
- _PyFrame_SetStackPointer(frame, stack_pointer);
- return frame;
+ Py_DECREF(executor);
+ return 1;
}
_PyExecutorObject *