@@ -1312,7 +1312,7 @@ emit_logical_branch(_PyTier2TypeContext *type_context, _Py_CODEUNIT *write_curr,
13121312 // we can't handle are in IS_FORBIDDEN_OPCODE
13131313#if BB_DEBUG
13141314 fprintf (stderr ,
1315- "emit_logical_branch unreachable opcode %d\n" , _Py_OPCODE ( branch ) );
1315+ "emit_logical_branch unreachable opcode %d\n" , branch . op . code );
13161316#endif
13171317 Py_UNREACHABLE ();
13181318 }
@@ -1373,9 +1373,9 @@ emit_logical_branch(_PyTier2TypeContext *type_context, _Py_CODEUNIT *write_curr,
13731373 return write_curr ;
13741374 }
13751375 else {
1376- #if BB_DEBUG
1377- fprintf (stderr , "emitted logical branch %p %d \n" , write_curr ,
1378- _Py_OPCODE ( branch ) );
1376+ #if BB_DEBUG && defined Py_DEBUG
1377+ fprintf (stderr , "emitted logical branch %p %s from original opcode %s \n" , write_curr ,
1378+ _PyOpcode_OpName [ opcode ], _PyOpcode_OpName [ branch . op . code ] );
13791379#endif
13801380 _py_set_opcode (write_curr , requires_extended_arg ? EXTENDED_ARG : NOP );
13811381 write_curr -> op .arg = (oparg >> 8 ) & 0xFF ;
@@ -1519,6 +1519,9 @@ add_metadata_to_jump_2d_array(_PyTier2Info *t2_info, _PyTier2BBMetadata *meta,
15191519 int backwards_jump_target , _PyTier2TypeContext * starting_context ,
15201520 _Py_CODEUNIT * tier1_start )
15211521{
1522+ #if BB_DEBUG
1523+ fprintf (stderr , "Attempting to add jump id %d as jump target\n" , meta -> id );
1524+ #endif
15221525 // Locate where to insert the BB ID
15231526 int backward_jump_offset_index = 0 ;
15241527 bool found = false;
@@ -1536,6 +1539,9 @@ add_metadata_to_jump_2d_array(_PyTier2Info *t2_info, _PyTier2BBMetadata *meta,
15361539 for (; jump_i < MAX_BB_VERSIONS ; jump_i ++ ) {
15371540 if (t2_info -> backward_jump_target_bb_pairs [backward_jump_offset_index ][jump_i ].id ==
15381541 -1 ) {
1542+ #if BB_DEBUG
1543+ fprintf (stderr , "Added jump id %d as jump target\n" , meta -> id );
1544+ #endif
15391545 t2_info -> backward_jump_target_bb_pairs [backward_jump_offset_index ][jump_i ].id =
15401546 meta -> id ;
15411547 t2_info -> backward_jump_target_bb_pairs [backward_jump_offset_index ][jump_i ].start_type_context = starting_context ;
@@ -1811,6 +1817,13 @@ _PyTier2_Code_DetectAndEmitBB(
18111817#define DISPATCH_GOTO () goto dispatch_opcode;
18121818#define TYPECONST_GET_RAWTYPE (idx ) Py_TYPE(PyTuple_GET_ITEM(consts, idx))
18131819#define GET_CONST (idx ) PyTuple_GET_ITEM(consts, idx)
1820+ #define CHECK_BACKWARDS_JUMP_TARGET () \
1821+ if (!checked_jump_target) { \
1822+ from_another_opcode = true;\
1823+ goto check_backwards_jump_target;\
1824+ }\
1825+ checked_jump_target = false; \
1826+ from_another_opcode = false; \
18141827
18151828 assert (co -> _tier2_info != NULL );
18161829 // There are only two cases that a BB ends.
@@ -1834,6 +1847,8 @@ _PyTier2_Code_DetectAndEmitBB(
18341847 bool virtual_start = false;
18351848 _PyTier2TypeContext * start_type_context_copy = NULL ;
18361849 _Py_CODEUNIT * virtual_tier1_start = NULL ;
1850+ bool from_another_opcode = false;
1851+ bool checked_jump_target = false;
18371852
18381853 // A meta-interpreter for types.
18391854 Py_ssize_t i = (tier1_start - _PyCode_CODE (co ));
@@ -1854,9 +1869,11 @@ _PyTier2_Code_DetectAndEmitBB(
18541869#endif
18551870 switch (opcode ) {
18561871 case RESUME :
1872+ CHECK_BACKWARDS_JUMP_TARGET ();
18571873 opcode = specop = RESUME_QUICK ;
18581874 DISPATCH ();
18591875 case END_FOR :
1876+ CHECK_BACKWARDS_JUMP_TARGET ();
18601877 // Assert that we are the start of a BB
18611878 assert (t2_start == write_i );
18621879
@@ -1869,6 +1886,7 @@ _PyTier2_Code_DetectAndEmitBB(
18691886 // Else, we do want to execute this.
18701887 DISPATCH ();
18711888 case POP_TOP : {
1889+ CHECK_BACKWARDS_JUMP_TARGET ();
18721890 // Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
18731891 // ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
18741892 _Py_TYPENODE_t * * type_stackptr = & starting_type_context -> type_stack_ptr ;
@@ -1879,6 +1897,7 @@ _PyTier2_Code_DetectAndEmitBB(
18791897 DISPATCH ();
18801898 }
18811899 case COPY : {
1900+ CHECK_BACKWARDS_JUMP_TARGET ();
18821901 // Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
18831902 // ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
18841903 _Py_TYPENODE_t * * type_stackptr = & starting_type_context -> type_stack_ptr ;
@@ -1889,6 +1908,7 @@ _PyTier2_Code_DetectAndEmitBB(
18891908 DISPATCH ();
18901909 }
18911910 case LOAD_CONST : {
1911+ CHECK_BACKWARDS_JUMP_TARGET ();
18921912 PyTypeObject * typ = TYPECONST_GET_RAWTYPE (oparg );
18931913 if (typ == & PyFloat_Type ) {
18941914 write_i = emit_i (write_i , LOAD_CONST , curr -> op .arg );
@@ -1916,6 +1936,7 @@ _PyTier2_Code_DetectAndEmitBB(
19161936 DISPATCH ();
19171937 }
19181938 case LOAD_FAST : {
1939+ CHECK_BACKWARDS_JUMP_TARGET ();
19191940 // Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
19201941 // ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
19211942 _Py_TYPENODE_t * type_locals = starting_type_context -> type_locals ;
@@ -1944,6 +1965,7 @@ _PyTier2_Code_DetectAndEmitBB(
19441965 DISPATCH ();
19451966 }
19461967 case LOAD_FAST_CHECK : {
1968+ CHECK_BACKWARDS_JUMP_TARGET ();
19471969 // Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
19481970 // ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
19491971 _Py_TYPENODE_t * type_locals = starting_type_context -> type_locals ;
@@ -1972,6 +1994,7 @@ _PyTier2_Code_DetectAndEmitBB(
19721994 DISPATCH ();
19731995 }
19741996 case STORE_FAST : {
1997+ CHECK_BACKWARDS_JUMP_TARGET ();
19751998 // Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
19761999 // ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
19772000 _Py_TYPENODE_t * type_locals = starting_type_context -> type_locals ;
@@ -1999,13 +2022,17 @@ _PyTier2_Code_DetectAndEmitBB(
19992022 }
20002023 // Need to handle reboxing at these boundaries.
20012024 case CALL :
2025+ CHECK_BACKWARDS_JUMP_TARGET ();
20022026 DISPATCH_REBOX (oparg + 2 );
20032027 case BUILD_MAP :
2028+ CHECK_BACKWARDS_JUMP_TARGET ();
20042029 DISPATCH_REBOX (oparg * 2 );
20052030 case BUILD_STRING :
20062031 case BUILD_LIST :
2032+ CHECK_BACKWARDS_JUMP_TARGET ();
20072033 DISPATCH_REBOX (oparg );
20082034 case BINARY_OP :
2035+ CHECK_BACKWARDS_JUMP_TARGET ();
20092036 if (oparg == NB_ADD || oparg == NB_SUBTRACT || oparg == NB_MULTIPLY ) {
20102037 // Add operation. Need to check if we can infer types.
20112038 _Py_CODEUNIT * possible_next = infer_BINARY_OP (t2_start ,
@@ -2029,6 +2056,7 @@ _PyTier2_Code_DetectAndEmitBB(
20292056 }
20302057 DISPATCH_REBOX (2 );
20312058 case BINARY_SUBSCR : {
2059+ CHECK_BACKWARDS_JUMP_TARGET ();
20322060 _Py_CODEUNIT * possible_next = infer_BINARY_SUBSCR (
20332061 t2_start , oparg , & needs_guard ,
20342062 * curr ,
@@ -2049,6 +2077,7 @@ _PyTier2_Code_DetectAndEmitBB(
20492077 continue ;
20502078 }
20512079 case STORE_SUBSCR : {
2080+ CHECK_BACKWARDS_JUMP_TARGET ();
20522081 _Py_CODEUNIT * possible_next = infer_BINARY_SUBSCR (
20532082 t2_start , oparg , & needs_guard ,
20542083 * curr ,
@@ -2075,31 +2104,53 @@ _PyTier2_Code_DetectAndEmitBB(
20752104 case UNARY_INVERT :
20762105 case GET_LEN :
20772106 case UNPACK_SEQUENCE :
2107+ CHECK_BACKWARDS_JUMP_TARGET ();
20782108 DISPATCH_REBOX (1 );
20792109 case CALL_INTRINSIC_2 :
20802110 case BINARY_SLICE :
2111+ CHECK_BACKWARDS_JUMP_TARGET ();
20812112 DISPATCH_REBOX (2 );
20822113 case STORE_SLICE :
2114+ CHECK_BACKWARDS_JUMP_TARGET ();
20832115 DISPATCH_REBOX (4 );
20842116 default :
20852117#if BB_DEBUG && !TYPEPROP_DEBUG
20862118 fprintf (stderr , "offset: %Id\n" , curr - _PyCode_CODE (co ));
20872119#endif
20882120 // This should be the end of another basic block, or the start of a new.
20892121 // Start of a new basic block, just ignore and continue.
2122+ start_virtual_bb :
20902123 if (virtual_start ) {
2124+ checked_jump_target = true;
20912125#if BB_DEBUG
20922126 fprintf (stderr , "Emitted virtual start of basic block\n" );
20932127#endif
2094- starts_with_backwards_jump_target = true;
20952128 virtual_start = false;
20962129 start_type_context_copy = _PyTier2TypeContext_Copy (starting_type_context );
20972130 if (start_type_context_copy == NULL ) {
20982131 _PyTier2TypeContext_Free (starting_type_context );
20992132 return NULL ;
21002133 }
2134+ // Add the basic block to the jump ids
2135+ assert (start_type_context_copy != NULL );
2136+ assert (virtual_tier1_start != NULL );
2137+ if (add_metadata_to_jump_2d_array (t2_info , meta ,
2138+ backwards_jump_target_offset , start_type_context_copy ,
2139+ virtual_tier1_start ) < 0 ) {
2140+ PyMem_Free (meta );
2141+ if (meta != temp_meta ) {
2142+ PyMem_Free (temp_meta );
2143+ }
2144+ _PyTier2TypeContext_Free (starting_type_context );
2145+ return NULL ;
2146+ }
2147+ if (from_another_opcode ) {
2148+ DISPATCH_GOTO ();
2149+ }
21012150 goto fall_through ;
21022151 }
2152+ check_backwards_jump_target :
2153+ checked_jump_target = true;
21032154 if (IS_BACKWARDS_JUMP_TARGET (co , curr )) {
21042155#if BB_DEBUG
21052156 fprintf (stderr , "Encountered a backward jump target\n" );
@@ -2142,6 +2193,10 @@ _PyTier2_Code_DetectAndEmitBB(
21422193 DISPATCH_GOTO ();
21432194 }
21442195 // Don't change opcode or oparg, let us handle it again.
2196+ goto start_virtual_bb ;
2197+ }
2198+ if (from_another_opcode ) {
2199+ from_another_opcode = false;
21452200 DISPATCH_GOTO ();
21462201 }
21472202 fall_through :
@@ -2203,21 +2258,6 @@ _PyTier2_Code_DetectAndEmitBB(
22032258 if (meta == NULL ) {
22042259 meta = temp_meta ;
22052260 }
2206- if (starts_with_backwards_jump_target ) {
2207- // Add the basic block to the jump ids
2208- assert (start_type_context_copy != NULL );
2209- assert (virtual_tier1_start != NULL );
2210- if (add_metadata_to_jump_2d_array (t2_info , temp_meta ,
2211- backwards_jump_target_offset , start_type_context_copy ,
2212- virtual_tier1_start ) < 0 ) {
2213- PyMem_Free (meta );
2214- if (meta != temp_meta ) {
2215- PyMem_Free (temp_meta );
2216- }
2217- _PyTier2TypeContext_Free (starting_type_context );
2218- return NULL ;
2219- }
2220- }
22212261 // Tell BB space the number of bytes we wrote.
22222262 // -1 becaues write_i points to the instruction AFTER the end
22232263 bb_space -> water_level += (write_i - t2_start ) * sizeof (_Py_CODEUNIT );
@@ -3025,6 +3065,9 @@ _PyTier2_LocateJumpBackwardsBB(_PyInterpreterFrame *frame, uint16_t bb_id_tagged
30253065 jump_offset_id = i ;
30263066 for (int x = 0 ; x < MAX_BB_VERSIONS ; x ++ ) {
30273067 int target_bb_id = t2_info -> backward_jump_target_bb_pairs [i ][x ].id ;
3068+ #if BB_DEBUG
3069+ fprintf (stderr , "jump offset bb id considered: %d\n" , target_bb_id );
3070+ #endif
30283071 if (target_bb_id >= 0 ) {
30293072 candidate_bb_id = target_bb_id ;
30303073 candidate_bb_tier1_start = t2_info -> backward_jump_target_bb_pairs [i ][x ].tier1_start ;
0 commit comments