summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/bytecodes.c9
-rw-r--r--Python/executor_cases.c.h8
-rw-r--r--Python/generated_cases.c.h9
-rw-r--r--Python/optimizer.c1
-rw-r--r--Python/pylifecycle.c4
5 files changed, 29 insertions, 2 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index ea136a3..81d6f80 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2182,7 +2182,14 @@ dummy_func(
JUMPBY(1-oparg);
#if ENABLE_SPECIALIZATION
here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
- if (here[1].cache > tstate->interp->optimizer_backedge_threshold) {
+ 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
+ )
+ {
OBJECT_STAT_INC(optimization_attempts);
frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
if (frame == NULL) {
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index e1f8b9f..90607e8 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -2017,6 +2017,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2038,6 +2039,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2089,6 +2091,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2131,6 +2134,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2243,6 +2247,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2281,6 +2286,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2318,6 +2324,7 @@
STACK_SHRINK(oparg);
STACK_SHRINK(1);
stack_pointer[-1] = res;
+ CHECK_EVAL_BREAKER();
break;
}
@@ -2496,6 +2503,7 @@
case JUMP_TO_TOP: {
pc = 0;
+ CHECK_EVAL_BREAKER();
break;
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index b2b0aa6..c35b81a 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -2758,7 +2758,14 @@
JUMPBY(1-oparg);
#if ENABLE_SPECIALIZATION
here[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER);
- if (here[1].cache > tstate->interp->optimizer_backedge_threshold) {
+ 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
+ )
+ {
OBJECT_STAT_INC(optimization_attempts);
frame = _PyOptimizer_BackEdge(frame, here, next_instr, stack_pointer);
if (frame == NULL) {
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 3d385a1..09120c3 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -155,6 +155,7 @@ PyUnstable_SetOptimizer(_PyOptimizerObject *optimizer)
_PyInterpreterFrame *
_PyOptimizer_BackEdge(_PyInterpreterFrame *frame, _Py_CODEUNIT *src, _Py_CODEUNIT *dest, PyObject **stack_pointer)
{
+ assert(src->op.code == JUMP_BACKWARD);
PyCodeObject *code = (PyCodeObject *)frame->f_executable;
assert(PyCode_Check(code));
PyInterpreterState *interp = _PyInterpreterState_GET();
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index cf8b437..f91fac9 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1192,7 +1192,11 @@ init_interp_main(PyThreadState *tstate)
}
if (enabled) {
PyObject *opt = PyUnstable_Optimizer_NewUOpOptimizer();
+ if (opt == NULL) {
+ return _PyStatus_ERR("can't initialize optimizer");
+ }
PyUnstable_SetOptimizer((_PyOptimizerObject *)opt);
+ Py_DECREF(opt);
}
}