@@ -503,8 +503,7 @@ add_to_trace(
503503 if (trace_stack_depth >= TRACE_STACK_SIZE) { \
504504 DPRINTF(2, "Trace stack overflow\n"); \
505505 OPT_STAT_INC(trace_stack_overflow); \
506- trace_length = 0; \
507- goto done; \
506+ return 0; \
508507 } \
509508 assert(func == NULL || func->func_code == (PyObject *)code); \
510509 trace_stack[trace_stack_depth].func = func; \
@@ -550,6 +549,7 @@ translate_bytecode_to_trace(
550549 }trace_stack [TRACE_STACK_SIZE ];
551550int trace_stack_depth = 0 ;
552551int confidence = CONFIDENCE_RANGE ;// Adjusted by branch instructions
552+ bool jump_seen = false;
553553
554554#ifdef Py_DEBUG
555555char * python_lltrace = Py_GETENV ("PYTHON_LLTRACE" );
@@ -568,7 +568,6 @@ translate_bytecode_to_trace(
568568ADD_TO_TRACE (_START_EXECUTOR ,0 , (uintptr_t )instr ,INSTR_IP (instr ,code ));
569569uint32_t target = 0 ;
570570
571- top :// Jump here after _PUSH_FRAME or likely branches
572571for (;;) {
573572target = INSTR_IP (instr ,code );
574573// Need space for _DEOPT
@@ -577,6 +576,13 @@ translate_bytecode_to_trace(
577576uint32_t opcode = instr -> op .code ;
578577uint32_t oparg = instr -> op .arg ;
579578
579+ if (!progress_needed && instr == initial_instr ) {
580+ // We have looped around to the start:
581+ RESERVE (1 );
582+ ADD_TO_TRACE (_JUMP_TO_TOP ,0 ,0 ,0 );
583+ gotodone ;
584+ }
585+
580586DPRINTF (2 ,"%d: %s(%d)\n" ,target ,_PyOpcode_OpName [opcode ],oparg );
581587
582588if (opcode == ENTER_EXECUTOR ) {
@@ -603,30 +609,21 @@ translate_bytecode_to_trace(
603609/* Special case the first instruction,
604610 * so that we can guarantee forward progress */
605611if (progress_needed ) {
606- progress_needed = false;
607- if (opcode == JUMP_BACKWARD || opcode == JUMP_BACKWARD_NO_INTERRUPT ) {
608- instr += 1 + _PyOpcode_Caches [opcode ]- (int32_t )oparg ;
609- initial_instr = instr ;
610- if (opcode == JUMP_BACKWARD ) {
611- ADD_TO_TRACE (_TIER2_RESUME_CHECK ,0 ,0 ,target );
612- }
613- continue ;
614- }
615- else {
616- if (OPCODE_HAS_EXIT (opcode )|| OPCODE_HAS_DEOPT (opcode )) {
617- opcode = _PyOpcode_Deopt [opcode ];
618- }
619- assert (!OPCODE_HAS_EXIT (opcode ));
620- assert (!OPCODE_HAS_DEOPT (opcode ));
612+ if (OPCODE_HAS_EXIT (opcode )|| OPCODE_HAS_DEOPT (opcode )) {
613+ opcode = _PyOpcode_Deopt [opcode ];
621614 }
615+ assert (!OPCODE_HAS_EXIT (opcode ));
616+ assert (!OPCODE_HAS_DEOPT (opcode ));
622617 }
623618
624619if (OPCODE_HAS_EXIT (opcode )) {
625- // Make space for exit code
620+ // Make space for side exit and final _EXIT_TRACE:
621+ RESERVE_RAW (2 ,"_EXIT_TRACE" );
626622max_length -- ;
627623 }
628624if (OPCODE_HAS_ERROR (opcode )) {
629- // Make space for error code
625+ // Make space for error stub and final _EXIT_TRACE:
626+ RESERVE_RAW (2 ,"_ERROR_POP_N" );
630627max_length -- ;
631628 }
632629switch (opcode ) {
@@ -672,19 +669,18 @@ translate_bytecode_to_trace(
672669 }
673670
674671case JUMP_BACKWARD :
672+ ADD_TO_TRACE (_CHECK_PERIODIC ,0 ,0 ,target );
673+ _Py_FALLTHROUGH ;
675674case JUMP_BACKWARD_NO_INTERRUPT :
676675 {
677- _Py_CODEUNIT * target = instr + 1 + _PyOpcode_Caches [opcode ]- (int )oparg ;
678- if (target == initial_instr ) {
679- /* We have looped round to the start */
680- RESERVE (1 );
681- ADD_TO_TRACE (_JUMP_TO_TOP ,0 ,0 ,0 );
682- }
683- else {
676+ instr += 1 + _PyOpcode_Caches [_PyOpcode_Deopt [opcode ]]- (int )oparg ;
677+ if (jump_seen ) {
684678OPT_STAT_INC (inner_loop );
685679DPRINTF (2 ,"JUMP_BACKWARD not to top ends trace\n" );
680+ gotodone ;
686681 }
687- gotodone ;
682+ jump_seen = true;
683+ gototop ;
688684 }
689685
690686case JUMP_FORWARD :
@@ -904,23 +900,25 @@ translate_bytecode_to_trace(
904900assert (instr -> op .code == POP_TOP );
905901instr ++ ;
906902 }
903+ top :
904+ // Jump here after _PUSH_FRAME or likely branches.
905+ progress_needed = false;
907906 }// End for (;;)
908907
909908done :
910909while (trace_stack_depth > 0 ) {
911910TRACE_STACK_POP ();
912911 }
913912assert (code == initial_code );
914- // Skip short traceslike _SET_IP, LOAD_FAST, _SET_IP, _EXIT_TRACE
915- if (progress_needed || trace_length < 5 ) {
913+ // Skip short traceswhere we can't even translate a single instruction:
914+ if (progress_needed ) {
916915OPT_STAT_INC (trace_too_short );
917916DPRINTF (2 ,
918- "No trace for %s (%s:%d) at byte offset %d (%s )\n" ,
917+ "No trace for %s (%s:%d) at byte offset %d (no progress )\n" ,
919918PyUnicode_AsUTF8 (code -> co_qualname ),
920919PyUnicode_AsUTF8 (code -> co_filename ),
921920code -> co_firstlineno ,
922- 2 * INSTR_IP (initial_instr ,code ),
923- progress_needed ?"no progress" :"too short" );
921+ 2 * INSTR_IP (initial_instr ,code ));
924922return 0 ;
925923 }
926924if (trace [trace_length - 1 ].opcode != _JUMP_TO_TOP ) {