It happens because the slot residency gets moved from ebx to edi in move_slot_to_reg, and then evict_register moves it back to ebx to protect it from the function call emitted by native_mem_read_32. It should instead remember that there is still a copy of the slot in ebx and update the residency to point to that without emitting a mov instruction.
Before function calls, the jit often emits code with redundant register moves:
in this case, emit_read_32_slot is creating the move, but there are several other implementations in the JIT with similar logic.
It happens because the slot residency gets moved from ebx to edi in move_slot_to_reg, and then evict_register moves it back to ebx to protect it from the function call emitted by native_mem_read_32. It should instead remember that there is still a copy of the slot in ebx and update the residency to point to that without emitting a mov instruction.