Skip to content

Commit 9ba5553

Browse files
committed
Fix JIT regression when code cache flushes during translation
This addresses critical issues in the JIT compiler that caused failures, particularly noticeable when ENABLE_EXT_F=0: 1. Check translation success before execution: The emulator now verifies that jit_translate() successfully marked a block as "hot" before attempting to execute the JIT-compiled code. This prevents execution of incomplete or failed translations. 2. Reset jump count on cache flush: The state->n_jumps counter was not being reset during code_cache_flush(), causing stale jump entries to persist and corrupt subsequent translations. 3. Mark incomplete translations properly: When a cache flush occurs mid-translation, the block is now correctly marked as not hot, ensuring it won't be mistakenly executed as valid JIT code. These fixes resolve the non-deterministic test failures observed in the pi calculation test and other compute-intensive benchmarks.
1 parent 4b61b26 commit 9ba5553

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

src/emulate.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,10 +1155,14 @@ void rv_step(void *arg)
11551155
#endif
11561156
) {
11571157
jit_translate(rv, block);
1158-
((exec_block_func_t) state->buf)(
1159-
rv, (uintptr_t) (state->buf + block->offset));
1160-
prev = NULL;
1161-
continue;
1158+
/* Only execute if translation succeeded (block is hot) */
1159+
if (block->hot) {
1160+
((exec_block_func_t) state->buf)(
1161+
rv, (uintptr_t) (state->buf + block->offset));
1162+
prev = NULL;
1163+
continue;
1164+
}
1165+
/* Fall through to interpreter if translation failed */
11621166
}
11631167
set_reset(&pc_set);
11641168
has_loops = false;

src/jit.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ static void update_branch_imm(struct jit_state *state,
611611
pthread_jit_write_protect_np(false);
612612
#endif
613613
memcpy(state->buf + offset, &insn, sizeof(uint32_t));
614+
sys_icache_invalidate(state->buf + offset, sizeof(uint32_t));
614615
#if defined(__APPLE__) && defined(__aarch64__)
615616
pthread_jit_write_protect_np(true);
616617
#endif
@@ -2167,6 +2168,7 @@ static void code_cache_flush(struct jit_state *state, riscv_t *rv)
21672168
should_flush = false;
21682169
state->offset = state->org_size;
21692170
state->n_blocks = 0;
2171+
state->n_jumps = 0; /* Reset jump count when flushing */
21702172
set_reset(&state->set);
21712173
clear_cache_hot(rv->block_cache, (clear_func_t) clear_hot);
21722174
#if RV32_HAS(T2C)
@@ -2320,6 +2322,9 @@ void jit_translate(riscv_t *rv, block_t *block)
23202322
block->offset = state->offset;
23212323
translate_chained_block(state, rv, block);
23222324
if (unlikely(should_flush)) {
2325+
/* Mark block as not translated since translation was incomplete */
2326+
block->hot = false;
2327+
/* Don't reset offset - it will be set correctly on restart */
23232328
code_cache_flush(state, rv);
23242329
goto restart;
23252330
}

0 commit comments

Comments
 (0)