diff options
-rw-r--r-- | Include/cpython/optimizer.h | 2 | ||||
-rw-r--r-- | Python/bytecodes.c | 20 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 20 | ||||
-rw-r--r-- | Python/optimizer.c | 21 |
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 * |