@@ -1212,7 +1212,14 @@ void rv_step(void *arg)
12121212#if RV32_HAS (JIT )
12131213#if RV32_HAS (T2C )
12141214 /* executed through the tier-2 JIT compiler */
1215- if (block -> hot2 ) {
1215+ if (__atomic_load_n (& block -> hot2 , __ATOMIC_ACQUIRE )) {
1216+ /* Atomic load-acquire pairs with store-release in t2c_compile().
1217+ * Ensures we see the updated block->func after observing hot2=true.
1218+ */
1219+ #if defined(__aarch64__ )
1220+ /* Ensure instruction cache coherency before executing T2C code */
1221+ __asm__ volatile ("isb" ::: "memory" );
1222+ #endif
12161223 ((exec_t2c_func_t ) block -> func )(rv );
12171224 prev = NULL ;
12181225 continue ;
@@ -1240,6 +1247,10 @@ void rv_step(void *arg)
12401247 */
12411248 if (block -> hot ) {
12421249 block -> n_invoke ++ ;
1250+ #if defined(__aarch64__ )
1251+ /* Ensure instruction cache coherency before executing JIT code */
1252+ __asm__ volatile ("isb" ::: "memory" );
1253+ #endif
12431254 ((exec_block_func_t ) state -> buf )(
12441255 rv , (uintptr_t ) (state -> buf + block -> offset ));
12451256 prev = NULL ;
@@ -1251,6 +1262,10 @@ void rv_step(void *arg)
12511262#endif
12521263 ) {
12531264 jit_translate (rv , block );
1265+ #if defined(__aarch64__ )
1266+ /* Ensure instruction cache coherency before executing JIT code */
1267+ __asm__ volatile ("isb" ::: "memory" );
1268+ #endif
12541269 ((exec_block_func_t ) state -> buf )(
12551270 rv , (uintptr_t ) (state -> buf + block -> offset ));
12561271 prev = NULL ;
0 commit comments