@@ -1030,11 +1030,11 @@ _PyJit_TryInitializeTracing(
10301030 // Don't error, just go to next instruction.
10311031 return 0 ;
10321032 }
1033+ _tstate -> jit_tracer_state -> is_tracing = false;
10331034 }
10341035 _PyJitTracerState * tracer = _tstate -> jit_tracer_state ;
10351036 // A recursive trace.
1036- // Don't trace into the inner call because it will stomp on the previous trace, causing endless retraces.
1037- if (tracer -> prev_state .code_curr_size > CODE_SIZE_EMPTY ) {
1037+ if (tracer -> is_tracing ) {
10381038 return 0 ;
10391039 }
10401040 if (oparg > 0xFFFF ) {
@@ -1086,20 +1086,45 @@ _PyJit_TryInitializeTracing(
10861086 close_loop_instr [1 ].counter = trigger_backoff_counter ();
10871087 }
10881088 _Py_BloomFilter_Init (& tracer -> prev_state .dependencies );
1089+ tracer -> is_tracing = true;
10891090 return 1 ;
10901091}
10911092
10921093Py_NO_INLINE void
1093- _PyJit_FinalizeTracing (PyThreadState * tstate )
1094+ _PyJit_FinalizeTracing (PyThreadState * tstate , int err )
10941095{
10951096 _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
10961097 _PyJitTracerState * tracer = _tstate -> jit_tracer_state ;
1098+ // Deal with backoffs
1099+ assert (tracer != NULL );
1100+ _PyExitData * exit = tracer -> initial_state .exit ;
1101+ if (exit == NULL ) {
1102+ // We hold a strong reference to the code object, so the instruction won't be freed.
1103+ if (err <= 0 ) {
1104+ _Py_BackoffCounter counter = tracer -> initial_state .jump_backward_instr [1 ].counter ;
1105+ tracer -> initial_state .jump_backward_instr [1 ].counter = restart_backoff_counter (counter );
1106+ }
1107+ else {
1108+ tracer -> initial_state .jump_backward_instr [1 ].counter = initial_jump_backoff_counter (& _tstate -> policy );
1109+ }
1110+ }
1111+ else if (tracer -> initial_state .executor -> vm_data .valid ) {
1112+ // Likewise, we hold a strong reference to the executor containing this exit, so the exit is guaranteed
1113+ // to be valid to access.
1114+ if (err <= 0 ) {
1115+ exit -> temperature = restart_backoff_counter (exit -> temperature );
1116+ }
1117+ else {
1118+ exit -> temperature = initial_temperature_backoff_counter (& _tstate -> policy );
1119+ }
1120+ }
10971121 Py_CLEAR (tracer -> initial_state .code );
10981122 Py_CLEAR (tracer -> initial_state .func );
10991123 Py_CLEAR (tracer -> initial_state .executor );
11001124 Py_CLEAR (tracer -> prev_state .instr_code );
11011125 tracer -> prev_state .code_curr_size = CODE_SIZE_EMPTY ;
11021126 tracer -> prev_state .code_max_size = UOP_MAX_TRACE_LENGTH /2 - 1 ;
1127+ tracer -> is_tracing = false;
11031128}
11041129
11051130void
0 commit comments