@@ -1852,6 +1852,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
1852
1852
1853
1853
/* -- GC handling --------------------------------------------------------- */
1854
1854
1855
+ /* Marker to prevent patching the GC check exit. */
1856
+ #define PPC_NOPATCH_GC_CHECK PPCI_ORIS
1857
+
1855
1858
/* Check GC threshold and do one or more GC steps. */
1856
1859
static void asm_gc_check (ASMState * as )
1857
1860
{
@@ -1863,6 +1866,7 @@ static void asm_gc_check(ASMState *as)
1863
1866
l_end = emit_label (as );
1864
1867
/* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
1865
1868
asm_guardcc (as , CC_NE ); /* Assumes asm_snap_prep() already done. */
1869
+ * -- as -> mcp = PPC_NOPATCH_GC_CHECK ;
1866
1870
emit_ai (as , PPCI_CMPWI , RID_RET , 0 );
1867
1871
args [0 ] = ASMREF_TMP1 ; /* global_State *g */
1868
1872
args [1 ] = ASMREF_TMP2 ; /* MSize steps */
@@ -2124,7 +2128,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2124
2128
MCode * px = exitstub_trace_addr (T , exitno );
2125
2129
MCode * cstart = NULL ;
2126
2130
MCode * mcarea = lj_mcode_patch (J , p , 0 );
2127
- int clearso = 0 ;
2131
+ int clearso = 0 , patchlong = 1 ;
2128
2132
for (; p < pe ; p ++ ) {
2129
2133
/* Look for exitstub branch, try to replace with branch to target. */
2130
2134
uint32_t ins = * p ;
@@ -2136,7 +2140,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2136
2140
delta -= sizeof (MCode );
2137
2141
}
2138
2142
/* Many, but not all short-range branches can be patched directly. */
2139
- if (((delta + 0x8000 ) >> 16 ) == 0 ) {
2143
+ if (p [-1 ] == PPC_NOPATCH_GC_CHECK ) {
2144
+ patchlong = 0 ;
2145
+ } else if (((delta + 0x8000 ) >> 16 ) == 0 ) {
2140
2146
* p = (ins & 0xffdf0000u ) | ((uint32_t )delta & 0xffffu ) |
2141
2147
((delta & 0x8000 ) * (PPCF_Y /0x8000 ));
2142
2148
if (!cstart ) cstart = p ;
@@ -2149,7 +2155,8 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2149
2155
if (!cstart ) cstart = p ;
2150
2156
}
2151
2157
}
2152
- { /* Always patch long-range branch in exit stub itself. */
2158
+ /* Always patch long-range branch in exit stub itself. Except, if we can't. */
2159
+ if (patchlong ) {
2153
2160
ptrdiff_t delta = (char * )target - (char * )px - clearso ;
2154
2161
lua_assert (((delta + 0x02000000 ) >> 26 ) == 0 );
2155
2162
* px = PPCI_B | ((uint32_t )delta & 0x03ffffffu );
0 commit comments