@@ -562,7 +562,8 @@ _PyJIT_translate_single_bytecode_to_trace(
562562 if (Py_IsNone ((PyObject * )func )) {
563563 func = NULL ;
564564 }
565- int is_first_instr = tstate -> interp -> jit_tracer_initial_instr == this_instr ;
565+
566+ int is_first_instr = tstate -> interp -> jit_tracer_initial_instr == this_instr ;
566567 bool progress_needed = (tstate -> interp -> jit_tracer_initial_chain_depth % MAX_CHAIN_DEPTH ) == 0 && is_first_instr ;;
567568 _PyBloomFilter * dependencies = & tstate -> interp -> jit_tracer_dependencies ;
568569 _Py_BloomFilter_Add (dependencies , old_code );
@@ -583,7 +584,39 @@ _PyJIT_translate_single_bytecode_to_trace(
583584
584585 target = INSTR_IP (target_instr , old_code );
585586
586- DPRINTF (2 , "%d: %s(%d)\n" , target , _PyOpcode_OpName [opcode ], oparg );
587+ bool needs_guard_ip = _PyOpcode_NeedsGuardIp [opcode ] &&
588+ !(opcode == FOR_ITER_RANGE || opcode == FOR_ITER_LIST || opcode == FOR_ITER_TUPLE ) &&
589+ !(opcode == JUMP_BACKWARD_NO_INTERRUPT || opcode == JUMP_BACKWARD || opcode == JUMP_BACKWARD_JIT ) &&
590+ !(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_NONE || opcode == POP_JUMP_IF_NOT_NONE );
591+
592+ // Strange control-flow, unsupported opcode, etc.
593+ if (jump_taken ||
594+ // This happens when a recursive call happens that we can't trace. Such as Python -> C -> Python calls
595+ // If we haven't guarded the IP, then it's untraceable.
596+ (frame != tstate -> interp -> jit_tracer_current_frame && !needs_guard_ip ) ||
597+ // TODO handle extended args.
598+ oparg > 255 || opcode == EXTENDED_ARG ||
599+ opcode == WITH_EXCEPT_START || opcode == RERAISE || opcode == CLEANUP_THROW || opcode == PUSH_EXC_INFO ||
600+ frame -> owner >= FRAME_OWNED_BY_INTERPRETER ||
601+ // This can be supported, but requires a tracing shim frame.
602+ opcode == CALL_ALLOC_AND_ENTER_INIT ) {
603+ unsupported :
604+ {
605+ // Rewind to previous instruction and replace with _EXIT_TRACE.
606+ _PyUOpInstruction * curr = & trace [trace_length - 1 ];
607+ while (curr -> opcode != _SET_IP && trace_length > 1 ) {
608+ trace_length -- ;
609+ curr = & trace [trace_length - 1 ];
610+ }
611+ assert (curr -> opcode == _SET_IP || trace_length == 1 );
612+ curr -> opcode = _EXIT_TRACE ;
613+ goto done ;
614+ }
615+ }
616+
617+ tstate -> interp -> jit_tracer_current_frame = frame ;
618+
619+ DPRINTF (2 , "%p %d: %s(%d)\n" , old_code , target , _PyOpcode_OpName [opcode ], oparg );
587620
588621 if (opcode == NOP ) {
589622 return 1 ;
@@ -601,47 +634,18 @@ _PyJIT_translate_single_bytecode_to_trace(
601634 max_length -= 2 ;
602635
603636 if (opcode == ENTER_EXECUTOR ) {
604- ADD_TO_TRACE (_CHECK_VALIDITY , 0 , 0 , target );
605- ADD_TO_TRACE (_SET_IP , 0 , (uintptr_t )target_instr , target );
606- ADD_TO_TRACE (_EXIT_TRACE , 0 , 0 , target );
607637 goto full ;
608638 }
609639
610- bool needs_guard_ip = _PyOpcode_NeedsGuardIp [opcode ] &&
611- !(opcode == FOR_ITER_RANGE || opcode == FOR_ITER_LIST || opcode == FOR_ITER_TUPLE ) &&
612- !(opcode == JUMP_BACKWARD_NO_INTERRUPT || opcode == JUMP_BACKWARD || opcode == JUMP_BACKWARD_JIT ) &&
613- !(opcode == POP_JUMP_IF_TRUE || opcode == POP_JUMP_IF_FALSE || opcode == POP_JUMP_IF_NONE || opcode == POP_JUMP_IF_NOT_NONE );
614-
615- assert (opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG );
616-
617640 const struct opcode_macro_expansion * expansion = & _PyOpcode_macro_expansion [opcode ];
618641
619- // Strange control-flow, unsupported opcode, etc.
620- if (jump_taken ||
621- // TODO handle extended args.
622- oparg > 255 ||
623- opcode == EXTENDED_ARG ||
624- opcode == WITH_EXCEPT_START || opcode == RERAISE || opcode == CLEANUP_THROW || opcode == PUSH_EXC_INFO ||
625- frame -> owner >= FRAME_OWNED_BY_INTERPRETER ||
626- // This can be supported, but requires a tracing shim frame.
627- opcode == CALL_ALLOC_AND_ENTER_INIT ) {
628- unsupported :
629- {
630- // Rewind to previous instruction and replace with _EXIT_TRACE.
631- _PyUOpInstruction * curr = & trace [trace_length - 1 ];
632- while (curr -> opcode != _SET_IP && trace_length > 1 ) {
633- trace_length -- ;
634- curr = & trace [trace_length - 1 ];
635- }
636- assert (curr -> opcode == _SET_IP || trace_length == 1 );
637- curr -> opcode = _EXIT_TRACE ;
638- goto done ;
639- }
640- }
641642 RESERVE_RAW (expansion -> nuops + needs_guard_ip + 3 , "uop and various checks" );
642643
643644 ADD_TO_TRACE (_CHECK_VALIDITY , 0 , 0 , target );
644645
646+ assert (opcode != ENTER_EXECUTOR && opcode != EXTENDED_ARG );
647+ assert (!_PyErr_Occurred (tstate ));
648+
645649 if (!OPCODE_HAS_NO_SAVE_IP (opcode )) {
646650 ADD_TO_TRACE (_SET_IP , 0 , (uintptr_t )target_instr , target );
647651 }
@@ -851,9 +855,9 @@ _PyJIT_InitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_
851855 tstate -> interp -> jit_tracer_initial_func = (PyFunctionObject * )Py_NewRef (_PyFrame_GetFunction (frame ));
852856 tstate -> interp -> jit_tracer_previous_exit = exit ;
853857 memset (& tstate -> interp -> jit_tracer_dependencies .bits , 0 , sizeof (tstate -> interp -> jit_tracer_dependencies .bits ));
854- tstate -> interp -> jit_completed_loop = false;
855858 tstate -> interp -> jit_tracer_initial_stack_depth = curr_stackdepth ;
856859 tstate -> interp -> jit_tracer_initial_chain_depth = chain_depth ;
860+ tstate -> interp -> jit_tracer_current_frame = frame ;
857861}
858862
859863void
0 commit comments