@@ -102,7 +102,7 @@ insert_executor(PyCodeObject *code, _Py_CODEUNIT *instr, int index, _PyExecutorO
102102}
103103
104104static _PyExecutorObject *
105- make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies );
105+ make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies , int chain_depth );
106106
107107static int
108108uop_optimize (_PyInterpreterFrame * frame , PyThreadState * tstate ,
@@ -128,8 +128,7 @@ _PyOptimizer_Optimize(
128128 // make progress in order to avoid infinite loops or excessively-long
129129 // side-exit chains. We can only insert the executor into the bytecode if
130130 // this is true, since a deopt won't infinitely re-enter the executor:
131- chain_depth %= MAX_CHAIN_DEPTH ;
132- bool progress_needed = chain_depth == 0 ;
131+ bool progress_needed = (chain_depth % MAX_CHAIN_DEPTH ) == 0 ;
133132 PyCodeObject * code = (PyCodeObject * )tstate -> interp -> jit_tracer_initial_func -> func_code ;
134133 assert (PyCode_Check (code ));
135134 _Py_CODEUNIT * start = tstate -> interp -> jit_tracer_initial_instr ;
@@ -144,19 +143,24 @@ _PyOptimizer_Optimize(
144143 return err ;
145144 }
146145 assert (executor != NULL );
147- int index = get_index_for_executor (code , start );
148- if (index < 0 ) {
149- /* Out of memory. Don't raise and assume that the
150- * error will show up elsewhere.
151- *
152- * If an optimizer has already produced an executor,
153- * it might get confused by the executor disappearing,
154- * but there is not much we can do about that here. */
155- Py_DECREF (executor );
156- interp -> compiling = false;
157- return 0 ;
146+ if (progress_needed ) {
147+ int index = get_index_for_executor (code , start );
148+ if (index < 0 ) {
149+ /* Out of memory. Don't raise and assume that the
150+ * error will show up elsewhere.
151+ *
152+ * If an optimizer has already produced an executor,
153+ * it might get confused by the executor disappearing,
154+ * but there is not much we can do about that here. */
155+ Py_DECREF (executor );
156+ interp -> compiling = false;
157+ return 0 ;
158+ }
159+ insert_executor (code , start , index , executor );
160+ }
161+ else {
162+ executor -> vm_data .code = NULL ;
158163 }
159- insert_executor (code , start , index , executor );
160164 executor -> vm_data .chain_depth = chain_depth ;
161165 assert (executor -> vm_data .valid );
162166 interp -> compiling = false;
@@ -544,7 +548,8 @@ _PyJIT_translate_single_bytecode_to_trace(
544548 if (Py_IsNone ((PyObject * )func )) {
545549 func = NULL ;
546550 }
547- bool progress_needed = (tstate -> interp -> jit_tracer_initial_chain_depth % MAX_CHAIN_DEPTH ) == 0 ;;
551+ int is_first_instr = tstate -> interp -> jit_tracer_initial_instr == this_instr ;
552+ bool progress_needed = (tstate -> interp -> jit_tracer_initial_chain_depth % MAX_CHAIN_DEPTH ) == 0 && is_first_instr ;;
548553 _PyBloomFilter * dependencies = & tstate -> interp -> jit_tracer_dependencies ;
549554 _Py_BloomFilter_Add (dependencies , old_code );
550555 _Py_CODEUNIT * target_instr = this_instr ;
@@ -629,7 +634,7 @@ _PyJIT_translate_single_bytecode_to_trace(
629634
630635 /* Special case the first instruction,
631636 * so that we can guarantee forward progress */
632- if (progress_needed && tstate -> interp -> jit_tracer_initial_instr == this_instr && tstate -> interp -> jit_tracer_code_curr_size == 0 ) {
637+ if (progress_needed && is_first_instr && tstate -> interp -> jit_tracer_code_curr_size == 0 ) {
633638 if (OPCODE_HAS_EXIT (opcode ) || OPCODE_HAS_DEOPT (opcode )) {
634639 opcode = _PyOpcode_Deopt [opcode ];
635640 }
@@ -638,7 +643,7 @@ _PyJIT_translate_single_bytecode_to_trace(
638643 }
639644
640645 // Loop back to the start
641- if (tstate -> interp -> jit_tracer_initial_instr == this_instr && tstate -> interp -> jit_tracer_code_curr_size > 2 ) {
646+ if (is_first_instr && tstate -> interp -> jit_tracer_code_curr_size > 2 ) {
642647 // Undo the last few instructions.
643648 trace_length = tstate -> interp -> jit_tracer_code_curr_size ;
644649 ADD_TO_TRACE (_JUMP_TO_TOP , 0 , 0 , 0 );
@@ -1047,7 +1052,7 @@ sanity_check(_PyExecutorObject *executor)
10471052 * and not a NOP.
10481053 */
10491054static _PyExecutorObject *
1050- make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies )
1055+ make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies , int chain_depth )
10511056{
10521057 int exit_count = count_exits (buffer , length );
10531058 _PyExecutorObject * executor = allocate_executor (exit_count , length );
@@ -1057,6 +1062,8 @@ make_executor_from_uops(_PyUOpInstruction *buffer, int length, const _PyBloomFil
10571062
10581063 /* Initialize exits */
10591064 _PyExecutorObject * cold = _PyExecutor_GetColdExecutor ();
1065+ fprintf (stdout , "CHAIN DEPTH %d;\n" , chain_depth );
1066+ cold -> vm_data .chain_depth = chain_depth ;
10601067 for (int i = 0 ; i < exit_count ; i ++ ) {
10611068 executor -> exits [i ].index = i ;
10621069 executor -> exits [i ].temperature = initial_temperature_backoff_counter ();
@@ -1191,7 +1198,7 @@ uop_optimize(
11911198 OPT_HIST (effective_trace_length (buffer , length ), optimized_trace_length_hist );
11921199 length = prepare_for_execution (buffer , length );
11931200 assert (length <= UOP_MAX_TRACE_LENGTH );
1194- _PyExecutorObject * executor = make_executor_from_uops (buffer , length , & dependencies );
1201+ _PyExecutorObject * executor = make_executor_from_uops (buffer , length , & dependencies , tstate -> interp -> jit_tracer_initial_chain_depth );
11951202 if (executor == NULL ) {
11961203 return -1 ;
11971204 }
0 commit comments