@@ -1106,11 +1106,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11061106 }
11071107
11081108 // Increment and check side exit counter.
1109+ // (Even though we only need it for certain opcodes.)
11091110 next_instr = frame -> instr_ptr ;
11101111 uint16_t * pcounter = current_executor -> counters + pc ;
1111- * pcounter += 1 ;
1112- if (* pcounter != 32 || // TODO: use resume_threshold
1113- tstate -> interp -> optimizer == & _PyOptimizer_Default )
1112+ * pcounter += 1 << OPTIMIZER_BITS_IN_COUNTER ;
1113+ /* We are using unsigned values, but we really want signed values, so
1114+ * do the 2s complement comparison manually */
1115+ uint16_t ucounter = * pcounter + (1 << 15 );
1116+ uint16_t threshold = tstate -> interp -> optimizer_resume_threshold + (1 << 15 );
1117+ if (ucounter <= threshold )
11141118 {
11151119 goto resume_frame ;
11161120 }
@@ -1160,6 +1164,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11601164 jump_opcode = current_executor -> trace [1 ].opcode ;
11611165 }
11621166 if (jump_opcode != uopcode ) {
1167+ * pcounter &= ((1 << OPTIMIZER_BITS_IN_COUNTER ) - 1 );
11631168 Py_INCREF (current_executor );
11641169 goto enter_tier_two ; // All systems go!
11651170 }
@@ -1171,6 +1176,18 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11711176 // It will be decref'ed below.
11721177 }
11731178 }
1179+
1180+ // Exponential backoff if we didn't optimize.
1181+ int backoff = * pcounter & ((1 << OPTIMIZER_BITS_IN_COUNTER ) - 1 );
1182+ if (backoff < MINIMUM_TIER2_BACKOFF ) {
1183+ backoff = MINIMUM_TIER2_BACKOFF ;
1184+ }
1185+ else if (backoff < 15 - OPTIMIZER_BITS_IN_COUNTER ) {
1186+ backoff ++ ;
1187+ }
1188+ assert (backoff <= 15 - OPTIMIZER_BITS_IN_COUNTER );
1189+ * pcounter = ((1 << 16 ) - ((1 << OPTIMIZER_BITS_IN_COUNTER ) << backoff )) | backoff ;
1190+
11741191 Py_DECREF (current_executor );
11751192 goto resume_frame ;
11761193}
0 commit comments