@@ -1312,7 +1312,7 @@ emit_logical_branch(_PyTier2TypeContext *type_context, _Py_CODEUNIT *write_curr,
1312
1312
// we can't handle are in IS_FORBIDDEN_OPCODE
1313
1313
#if BB_DEBUG
1314
1314
fprintf (stderr ,
1315
- "emit_logical_branch unreachable opcode %d\n" , _Py_OPCODE ( branch ) );
1315
+ "emit_logical_branch unreachable opcode %d\n" , branch . op . code );
1316
1316
#endif
1317
1317
Py_UNREACHABLE ();
1318
1318
}
@@ -1373,9 +1373,9 @@ emit_logical_branch(_PyTier2TypeContext *type_context, _Py_CODEUNIT *write_curr,
1373
1373
return write_curr ;
1374
1374
}
1375
1375
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 ] );
1379
1379
#endif
1380
1380
_py_set_opcode (write_curr , requires_extended_arg ? EXTENDED_ARG : NOP );
1381
1381
write_curr -> op .arg = (oparg >> 8 ) & 0xFF ;
@@ -1519,6 +1519,9 @@ add_metadata_to_jump_2d_array(_PyTier2Info *t2_info, _PyTier2BBMetadata *meta,
1519
1519
int backwards_jump_target , _PyTier2TypeContext * starting_context ,
1520
1520
_Py_CODEUNIT * tier1_start )
1521
1521
{
1522
+ #if BB_DEBUG
1523
+ fprintf (stderr , "Attempting to add jump id %d as jump target\n" , meta -> id );
1524
+ #endif
1522
1525
// Locate where to insert the BB ID
1523
1526
int backward_jump_offset_index = 0 ;
1524
1527
bool found = false;
@@ -1536,6 +1539,9 @@ add_metadata_to_jump_2d_array(_PyTier2Info *t2_info, _PyTier2BBMetadata *meta,
1536
1539
for (; jump_i < MAX_BB_VERSIONS ; jump_i ++ ) {
1537
1540
if (t2_info -> backward_jump_target_bb_pairs [backward_jump_offset_index ][jump_i ].id ==
1538
1541
-1 ) {
1542
+ #if BB_DEBUG
1543
+ fprintf (stderr , "Added jump id %d as jump target\n" , meta -> id );
1544
+ #endif
1539
1545
t2_info -> backward_jump_target_bb_pairs [backward_jump_offset_index ][jump_i ].id =
1540
1546
meta -> id ;
1541
1547
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(
1811
1817
#define DISPATCH_GOTO () goto dispatch_opcode;
1812
1818
#define TYPECONST_GET_RAWTYPE (idx ) Py_TYPE(PyTuple_GET_ITEM(consts, idx))
1813
1819
#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; \
1814
1827
1815
1828
assert (co -> _tier2_info != NULL );
1816
1829
// There are only two cases that a BB ends.
@@ -1834,6 +1847,8 @@ _PyTier2_Code_DetectAndEmitBB(
1834
1847
bool virtual_start = false;
1835
1848
_PyTier2TypeContext * start_type_context_copy = NULL ;
1836
1849
_Py_CODEUNIT * virtual_tier1_start = NULL ;
1850
+ bool from_another_opcode = false;
1851
+ bool checked_jump_target = false;
1837
1852
1838
1853
// A meta-interpreter for types.
1839
1854
Py_ssize_t i = (tier1_start - _PyCode_CODE (co ));
@@ -1854,9 +1869,11 @@ _PyTier2_Code_DetectAndEmitBB(
1854
1869
#endif
1855
1870
switch (opcode ) {
1856
1871
case RESUME :
1872
+ CHECK_BACKWARDS_JUMP_TARGET ();
1857
1873
opcode = specop = RESUME_QUICK ;
1858
1874
DISPATCH ();
1859
1875
case END_FOR :
1876
+ CHECK_BACKWARDS_JUMP_TARGET ();
1860
1877
// Assert that we are the start of a BB
1861
1878
assert (t2_start == write_i );
1862
1879
@@ -1869,6 +1886,7 @@ _PyTier2_Code_DetectAndEmitBB(
1869
1886
// Else, we do want to execute this.
1870
1887
DISPATCH ();
1871
1888
case POP_TOP : {
1889
+ CHECK_BACKWARDS_JUMP_TARGET ();
1872
1890
// Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
1873
1891
// ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
1874
1892
_Py_TYPENODE_t * * type_stackptr = & starting_type_context -> type_stack_ptr ;
@@ -1879,6 +1897,7 @@ _PyTier2_Code_DetectAndEmitBB(
1879
1897
DISPATCH ();
1880
1898
}
1881
1899
case COPY : {
1900
+ CHECK_BACKWARDS_JUMP_TARGET ();
1882
1901
// Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
1883
1902
// ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
1884
1903
_Py_TYPENODE_t * * type_stackptr = & starting_type_context -> type_stack_ptr ;
@@ -1889,6 +1908,7 @@ _PyTier2_Code_DetectAndEmitBB(
1889
1908
DISPATCH ();
1890
1909
}
1891
1910
case LOAD_CONST : {
1911
+ CHECK_BACKWARDS_JUMP_TARGET ();
1892
1912
PyTypeObject * typ = TYPECONST_GET_RAWTYPE (oparg );
1893
1913
if (typ == & PyFloat_Type ) {
1894
1914
write_i = emit_i (write_i , LOAD_CONST , curr -> op .arg );
@@ -1916,6 +1936,7 @@ _PyTier2_Code_DetectAndEmitBB(
1916
1936
DISPATCH ();
1917
1937
}
1918
1938
case LOAD_FAST : {
1939
+ CHECK_BACKWARDS_JUMP_TARGET ();
1919
1940
// Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
1920
1941
// ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
1921
1942
_Py_TYPENODE_t * type_locals = starting_type_context -> type_locals ;
@@ -1944,6 +1965,7 @@ _PyTier2_Code_DetectAndEmitBB(
1944
1965
DISPATCH ();
1945
1966
}
1946
1967
case LOAD_FAST_CHECK : {
1968
+ CHECK_BACKWARDS_JUMP_TARGET ();
1947
1969
// Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
1948
1970
// ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
1949
1971
_Py_TYPENODE_t * type_locals = starting_type_context -> type_locals ;
@@ -1972,6 +1994,7 @@ _PyTier2_Code_DetectAndEmitBB(
1972
1994
DISPATCH ();
1973
1995
}
1974
1996
case STORE_FAST : {
1997
+ CHECK_BACKWARDS_JUMP_TARGET ();
1975
1998
// Read-only, only for us to inspect the types. DO NOT MODIFY HERE.
1976
1999
// ONLY THE TYPES PROPAGATOR SHOULD MODIFY THEIR INTERNAL VALUES.
1977
2000
_Py_TYPENODE_t * type_locals = starting_type_context -> type_locals ;
@@ -1999,13 +2022,17 @@ _PyTier2_Code_DetectAndEmitBB(
1999
2022
}
2000
2023
// Need to handle reboxing at these boundaries.
2001
2024
case CALL :
2025
+ CHECK_BACKWARDS_JUMP_TARGET ();
2002
2026
DISPATCH_REBOX (oparg + 2 );
2003
2027
case BUILD_MAP :
2028
+ CHECK_BACKWARDS_JUMP_TARGET ();
2004
2029
DISPATCH_REBOX (oparg * 2 );
2005
2030
case BUILD_STRING :
2006
2031
case BUILD_LIST :
2032
+ CHECK_BACKWARDS_JUMP_TARGET ();
2007
2033
DISPATCH_REBOX (oparg );
2008
2034
case BINARY_OP :
2035
+ CHECK_BACKWARDS_JUMP_TARGET ();
2009
2036
if (oparg == NB_ADD || oparg == NB_SUBTRACT || oparg == NB_MULTIPLY ) {
2010
2037
// Add operation. Need to check if we can infer types.
2011
2038
_Py_CODEUNIT * possible_next = infer_BINARY_OP (t2_start ,
@@ -2029,6 +2056,7 @@ _PyTier2_Code_DetectAndEmitBB(
2029
2056
}
2030
2057
DISPATCH_REBOX (2 );
2031
2058
case BINARY_SUBSCR : {
2059
+ CHECK_BACKWARDS_JUMP_TARGET ();
2032
2060
_Py_CODEUNIT * possible_next = infer_BINARY_SUBSCR (
2033
2061
t2_start , oparg , & needs_guard ,
2034
2062
* curr ,
@@ -2049,6 +2077,7 @@ _PyTier2_Code_DetectAndEmitBB(
2049
2077
continue ;
2050
2078
}
2051
2079
case STORE_SUBSCR : {
2080
+ CHECK_BACKWARDS_JUMP_TARGET ();
2052
2081
_Py_CODEUNIT * possible_next = infer_BINARY_SUBSCR (
2053
2082
t2_start , oparg , & needs_guard ,
2054
2083
* curr ,
@@ -2075,31 +2104,53 @@ _PyTier2_Code_DetectAndEmitBB(
2075
2104
case UNARY_INVERT :
2076
2105
case GET_LEN :
2077
2106
case UNPACK_SEQUENCE :
2107
+ CHECK_BACKWARDS_JUMP_TARGET ();
2078
2108
DISPATCH_REBOX (1 );
2079
2109
case CALL_INTRINSIC_2 :
2080
2110
case BINARY_SLICE :
2111
+ CHECK_BACKWARDS_JUMP_TARGET ();
2081
2112
DISPATCH_REBOX (2 );
2082
2113
case STORE_SLICE :
2114
+ CHECK_BACKWARDS_JUMP_TARGET ();
2083
2115
DISPATCH_REBOX (4 );
2084
2116
default :
2085
2117
#if BB_DEBUG && !TYPEPROP_DEBUG
2086
2118
fprintf (stderr , "offset: %Id\n" , curr - _PyCode_CODE (co ));
2087
2119
#endif
2088
2120
// This should be the end of another basic block, or the start of a new.
2089
2121
// Start of a new basic block, just ignore and continue.
2122
+ start_virtual_bb :
2090
2123
if (virtual_start ) {
2124
+ checked_jump_target = true;
2091
2125
#if BB_DEBUG
2092
2126
fprintf (stderr , "Emitted virtual start of basic block\n" );
2093
2127
#endif
2094
- starts_with_backwards_jump_target = true;
2095
2128
virtual_start = false;
2096
2129
start_type_context_copy = _PyTier2TypeContext_Copy (starting_type_context );
2097
2130
if (start_type_context_copy == NULL ) {
2098
2131
_PyTier2TypeContext_Free (starting_type_context );
2099
2132
return NULL ;
2100
2133
}
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
+ }
2101
2150
goto fall_through ;
2102
2151
}
2152
+ check_backwards_jump_target :
2153
+ checked_jump_target = true;
2103
2154
if (IS_BACKWARDS_JUMP_TARGET (co , curr )) {
2104
2155
#if BB_DEBUG
2105
2156
fprintf (stderr , "Encountered a backward jump target\n" );
@@ -2142,6 +2193,10 @@ _PyTier2_Code_DetectAndEmitBB(
2142
2193
DISPATCH_GOTO ();
2143
2194
}
2144
2195
// 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;
2145
2200
DISPATCH_GOTO ();
2146
2201
}
2147
2202
fall_through :
@@ -2203,21 +2258,6 @@ _PyTier2_Code_DetectAndEmitBB(
2203
2258
if (meta == NULL ) {
2204
2259
meta = temp_meta ;
2205
2260
}
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
- }
2221
2261
// Tell BB space the number of bytes we wrote.
2222
2262
// -1 becaues write_i points to the instruction AFTER the end
2223
2263
bb_space -> water_level += (write_i - t2_start ) * sizeof (_Py_CODEUNIT );
@@ -3025,6 +3065,9 @@ _PyTier2_LocateJumpBackwardsBB(_PyInterpreterFrame *frame, uint16_t bb_id_tagged
3025
3065
jump_offset_id = i ;
3026
3066
for (int x = 0 ; x < MAX_BB_VERSIONS ; x ++ ) {
3027
3067
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
3028
3071
if (target_bb_id >= 0 ) {
3029
3072
candidate_bb_id = target_bb_id ;
3030
3073
candidate_bb_tier1_start = t2_info -> backward_jump_target_bb_pairs [i ][x ].tier1_start ;
0 commit comments