@@ -299,6 +299,89 @@ static inline void offset_map_insert(struct jit_state *state, block_t *block)
299
299
__builtin___clear_cache((char *) (addr), (char *) (addr) + (size));
300
300
#endif
301
301
302
+ /* JIT debug helpers - enable with ENABLE_JIT_DEBUG=1 to detect issues early */
303
+ #ifndef ENABLE_JIT_DEBUG
304
+ #define ENABLE_JIT_DEBUG 0
305
+ #endif
306
+
307
+ #if ENABLE_JIT_DEBUG
308
+ static void jit_dump_regmap (const char * ctx )
309
+ {
310
+ rv_log_debug ("JIT RegMap [%s]:" , ctx );
311
+ for (int i = 0 ; i < n_host_regs ; i ++ ) {
312
+ if (register_map [i ].vm_reg_idx >= 0 ) {
313
+ rv_log_debug (" Host R%d -> VM x%d (dirty=%d)" ,
314
+ register_map [i ].reg_idx , register_map [i ].vm_reg_idx ,
315
+ register_map [i ].dirty );
316
+ }
317
+ }
318
+ }
319
+
320
+ static void jit_check_regmap_conflict (int vm_reg ,
321
+ int host_reg ,
322
+ const char * insn )
323
+ {
324
+ int found_idx = -1 ;
325
+ /* Check if VM register is already mapped */
326
+ for (int i = 0 ; i < n_host_regs ; i ++ ) {
327
+ if (register_map [i ].vm_reg_idx == vm_reg ) {
328
+ if (found_idx >= 0 && found_idx != i ) {
329
+ /* VM register mapped to multiple host registers */
330
+ rv_log_error (
331
+ "JIT RegMap CONFLICT in %s: VM x%d mapped to "
332
+ "Host R%d (idx %d) and R%d (idx %d)" ,
333
+ insn , vm_reg , register_map [found_idx ].reg_idx , found_idx ,
334
+ register_map [i ].reg_idx , i );
335
+ jit_dump_regmap ("CONFLICT" );
336
+ assert (false);
337
+ }
338
+ found_idx = i ;
339
+ /* Verify the found mapping is correct */
340
+ if (register_map [i ].reg_idx != host_reg ) {
341
+ rv_log_error (
342
+ "JIT RegMap CONFLICT in %s: VM x%d expected at "
343
+ "Host R%d but found at R%d" ,
344
+ insn , vm_reg , host_reg , register_map [i ].reg_idx );
345
+ jit_dump_regmap ("CONFLICT" );
346
+ assert (false);
347
+ }
348
+ } else if (register_map [i ].reg_idx == host_reg &&
349
+ register_map [i ].vm_reg_idx >= 0 ) {
350
+ /* Host register holds different VM register */
351
+ rv_log_error (
352
+ "JIT RegMap CONFLICT in %s: Host R%d already holds "
353
+ "VM x%d, cannot map VM x%d" ,
354
+ insn , host_reg , register_map [i ].vm_reg_idx , vm_reg );
355
+ jit_dump_regmap ("CONFLICT" );
356
+ assert (false);
357
+ }
358
+ }
359
+ }
360
+
361
+ static void jit_verify_cache_coherency (struct jit_state * state , uint32_t pc )
362
+ UNUSED ;
363
+ static void jit_verify_cache_coherency (struct jit_state * state , uint32_t pc )
364
+ {
365
+ /* On ARM64, verify instruction cache was properly invalidated */
366
+ #if defined(__aarch64__ )
367
+ if (state -> offset > 0 ) {
368
+ rv_log_debug ("JIT: Cache coherency check at PC=0x%08x, offset=%u" , pc ,
369
+ state -> offset );
370
+ }
371
+ #endif
372
+ }
373
+ #else
374
+ #define jit_dump_regmap (ctx ) \
375
+ do { \
376
+ } while (0)
377
+ #define jit_check_regmap_conflict (vm_reg , host_reg , insn ) \
378
+ do { \
379
+ } while (0)
380
+ #define jit_verify_cache_coherency (state , pc ) \
381
+ do { \
382
+ } while (0)
383
+ #endif
384
+
302
385
static bool should_flush = false;
303
386
static void emit_bytes (struct jit_state * state , void * data , uint32_t len )
304
387
{
@@ -1890,6 +1973,7 @@ static inline int map_vm_reg(struct jit_state *state, int vm_reg_idx)
1890
1973
save_reg (state , idx );
1891
1974
unmap_vm_reg (idx );
1892
1975
set_vm_reg (idx , vm_reg_idx );
1976
+ jit_check_regmap_conflict (vm_reg_idx , target_reg , "map_vm_reg" );
1893
1977
return target_reg ;
1894
1978
}
1895
1979
@@ -1933,6 +2017,15 @@ static inline int map_vm_reg_reserved(struct jit_state *state,
1933
2017
save_reg (state , idx );
1934
2018
unmap_vm_reg (idx );
1935
2019
set_vm_reg (idx , vm_reg_idx );
2020
+ jit_check_regmap_conflict (vm_reg_idx , target_reg , "map_vm_reg_reserved" );
2021
+ /* Additional check: ensure we didn't allocate the reserved register */
2022
+ if (target_reg == reserved_reg_idx ) {
2023
+ rv_log_error (
2024
+ "JIT RegMap ERROR: map_vm_reg_reserved allocated reserved "
2025
+ "register R%d for VM x%d" ,
2026
+ reserved_reg_idx , vm_reg_idx );
2027
+ assert (false);
2028
+ }
1936
2029
return target_reg ;
1937
2030
}
1938
2031
0 commit comments