@@ -299,6 +299,89 @@ static inline void offset_map_insert(struct jit_state *state, block_t *block)
299299 __builtin___clear_cache((char *) (addr), (char *) (addr) + (size));
300300#endif
301301
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+
302385static bool should_flush = false;
303386static void emit_bytes (struct jit_state * state , void * data , uint32_t len )
304387{
@@ -1890,6 +1973,7 @@ static inline int map_vm_reg(struct jit_state *state, int vm_reg_idx)
18901973 save_reg (state , idx );
18911974 unmap_vm_reg (idx );
18921975 set_vm_reg (idx , vm_reg_idx );
1976+ jit_check_regmap_conflict (vm_reg_idx , target_reg , "map_vm_reg" );
18931977 return target_reg ;
18941978}
18951979
@@ -1933,6 +2017,15 @@ static inline int map_vm_reg_reserved(struct jit_state *state,
19332017 save_reg (state , idx );
19342018 unmap_vm_reg (idx );
19352019 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+ }
19362029 return target_reg ;
19372030}
19382031
0 commit comments