@@ -299,6 +299,79 @@ 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 ,
315+ register_map [i ].vm_reg_idx ,
316+ register_map [i ].dirty );
317+ }
318+ }
319+ }
320+
321+ static void jit_check_regmap_conflict (int vm_reg , int host_reg , const char * insn )
322+ {
323+ int found_idx = -1 ;
324+ /* Check if VM register is already mapped */
325+ for (int i = 0 ; i < n_host_regs ; i ++ ) {
326+ if (register_map [i ].vm_reg_idx == vm_reg ) {
327+ if (found_idx >= 0 && found_idx != i ) {
328+ /* VM register mapped to multiple host registers */
329+ rv_log_error ("JIT RegMap CONFLICT in %s: VM x%d mapped to "
330+ "Host R%d (idx %d) and R%d (idx %d)" ,
331+ insn , vm_reg ,
332+ register_map [found_idx ].reg_idx , found_idx ,
333+ register_map [i ].reg_idx , i );
334+ jit_dump_regmap ("CONFLICT" );
335+ assert (false);
336+ }
337+ found_idx = i ;
338+ /* Verify the found mapping is correct */
339+ if (register_map [i ].reg_idx != host_reg ) {
340+ rv_log_error ("JIT RegMap CONFLICT in %s: VM x%d expected at "
341+ "Host R%d but found at R%d" ,
342+ insn , vm_reg , host_reg , register_map [i ].reg_idx );
343+ jit_dump_regmap ("CONFLICT" );
344+ assert (false);
345+ }
346+ } else if (register_map [i ].reg_idx == host_reg &&
347+ register_map [i ].vm_reg_idx >= 0 ) {
348+ /* Host register holds different VM register */
349+ rv_log_error ("JIT RegMap CONFLICT in %s: Host R%d already holds "
350+ "VM x%d, cannot map VM x%d" ,
351+ insn , host_reg , register_map [i ].vm_reg_idx , vm_reg );
352+ jit_dump_regmap ("CONFLICT" );
353+ assert (false);
354+ }
355+ }
356+ }
357+
358+ static void jit_verify_cache_coherency (struct jit_state * state , uint32_t pc ) UNUSED ;
359+ static void jit_verify_cache_coherency (struct jit_state * state , uint32_t pc )
360+ {
361+ /* On ARM64, verify instruction cache was properly invalidated */
362+ #if defined(__aarch64__ )
363+ if (state -> offset > 0 ) {
364+ rv_log_debug ("JIT: Cache coherency check at PC=0x%08x, offset=%u" ,
365+ pc , state -> offset );
366+ }
367+ #endif
368+ }
369+ #else
370+ #define jit_dump_regmap (ctx ) do { } while (0)
371+ #define jit_check_regmap_conflict (vm_reg , host_reg , insn ) do { } while (0)
372+ #define jit_verify_cache_coherency (state , pc ) do { } while (0)
373+ #endif
374+
302375static bool should_flush = false;
303376static void emit_bytes (struct jit_state * state , void * data , uint32_t len )
304377{
@@ -1890,6 +1963,7 @@ static inline int map_vm_reg(struct jit_state *state, int vm_reg_idx)
18901963 save_reg (state , idx );
18911964 unmap_vm_reg (idx );
18921965 set_vm_reg (idx , vm_reg_idx );
1966+ jit_check_regmap_conflict (vm_reg_idx , target_reg , "map_vm_reg" );
18931967 return target_reg ;
18941968}
18951969
@@ -1933,6 +2007,14 @@ static inline int map_vm_reg_reserved(struct jit_state *state,
19332007 save_reg (state , idx );
19342008 unmap_vm_reg (idx );
19352009 set_vm_reg (idx , vm_reg_idx );
2010+ jit_check_regmap_conflict (vm_reg_idx , target_reg , "map_vm_reg_reserved" );
2011+ /* Additional check: ensure we didn't allocate the reserved register */
2012+ if (target_reg == reserved_reg_idx ) {
2013+ rv_log_error ("JIT RegMap ERROR: map_vm_reg_reserved allocated reserved "
2014+ "register R%d for VM x%d" ,
2015+ reserved_reg_idx , vm_reg_idx );
2016+ assert (false);
2017+ }
19362018 return target_reg ;
19372019}
19382020
0 commit comments