Skip to content

Commit 786e15e

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 786e15e

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,6 +2167,7 @@ static void code_cache_flush(struct jit_state *state, riscv_t *rv)
21672167
should_flush = false;
21682168
state->offset = state->org_size;
21692169
state->n_blocks = 0;
2170+
state->n_jumps = 0; /* Reset jump count when flushing */
21702171
set_reset(&state->set);
21712172
clear_cache_hot(rv->block_cache, (clear_func_t) clear_hot);
21722173
#if RV32_HAS(T2C)
@@ -2320,6 +2321,9 @@ void jit_translate(riscv_t *rv, block_t *block)
23202321
block->offset = state->offset;
23212322
translate_chained_block(state, rv, block);
23222323
if (unlikely(should_flush)) {
2324+
/* Mark block as not translated since translation was incomplete */
2325+
block->hot = false;
2326+
/* Don't reset offset - it will be set correctly on restart */
23232327
code_cache_flush(state, rv);
23242328
goto restart;
23252329
}

0 commit comments

Comments
 (0)