diff options
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r-- | Python/bytecodes.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 7010042..d914f27 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2335,10 +2335,12 @@ dummy_func( JUMPBY(-oparg); #if ENABLE_SPECIALIZATION this_instr[1].cache += (1 << OPTIMIZER_BITS_IN_COUNTER); - if (this_instr[1].cache > tstate->interp->optimizer_backedge_threshold && - // Double-check that the opcode isn't instrumented or something: - this_instr->op.code == JUMP_BACKWARD) - { + /* We are using unsigned values, but we really want signed values, so + * do the 2s complement comparison manually */ + uint16_t ucounter = this_instr[1].cache + (1 << 15); + uint16_t threshold = tstate->interp->optimizer_backedge_threshold + (1 << 15); + // Double-check that the opcode isn't instrumented or something: + if (ucounter > threshold && this_instr->op.code == JUMP_BACKWARD) { OPT_STAT_INC(attempts); int optimized = _PyOptimizer_BackEdge(frame, this_instr, next_instr, stack_pointer); ERROR_IF(optimized < 0, error); @@ -2346,8 +2348,19 @@ dummy_func( // Rewind and enter the executor: assert(this_instr->op.code == ENTER_EXECUTOR); next_instr = this_instr; + this_instr[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); + } + else { + int backoff = this_instr[1].cache & ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); + if (backoff < MINIMUM_TIER2_BACKOFF) { + backoff = MINIMUM_TIER2_BACKOFF; + } + else if (backoff < 15 - OPTIMIZER_BITS_IN_COUNTER) { + backoff++; + } + assert(backoff <= 15 - OPTIMIZER_BITS_IN_COUNTER); + this_instr[1].cache = ((1 << 16) - ((1 << OPTIMIZER_BITS_IN_COUNTER) << backoff)) | backoff; } - this_instr[1].cache &= ((1 << OPTIMIZER_BITS_IN_COUNTER) - 1); } #endif /* ENABLE_SPECIALIZATION */ } |