Files
ARMSX3/Utilities
Zulux91 c2b5f0c400 Add missing ARM64 instruction-cache maintenance to the JIT
While chasing an unrelated SPURS hang I noticed the JIT publishes
freshly written code on ARM64 with no instruction-cache maintenance at
all. A grep for clear_cache or flushInstructionCache over the JIT layer
comes back empty. The branch-rewrite sites only issue ISB; DSB ISH,
which performs no D-cache clean or I-cache invalidation and is ordered
backwards for self-modifying code besides. On ARMv8 a correct
publication needs the DC CVAU / IC IVAU broadcast sequence; x86 has a
coherent instruction cache, so none of this was ever visible there.
All sites use the bundled asmjit::VirtMem::flushInstructionCache(),
which emits that sequence portably across toolchains.

This covers every publication path I could find:

- MemoryManager1::finalizeMemory() and MemoryManager2::finalizeMemory()
  were both no-ops. RuntimeDyld calls finalizeMemory() after writing
  code and relies on it for cache maintenance, so LLVM emitted PPU and
  SPU code was never flushed. MemoryManager1 serves the primary PPU
  JIT, MemoryManager2 the SPU JIT and auxiliary engines. Both managers
  now record code section allocations and flush them on finalize. I
  confirmed at runtime that the MemoryManager2 path executes (about
  12800 calls per cold boot).
- jit_runtime_base::_add() copies asmjit output into executable memory
  with no flush.
- jit_runtime::finalize() restores an executable code snapshot in place
  during emulator restart with only the ISB/DSB pair.
- spu_runtime::rebuild_ubertrampoline() publishes a hand-written
  trampoline via CAS with no flush; the flush now happens before the
  publication.
- spu_runtime::make_branch_patchpoint() writes a patchpoint byte by
  byte and returns it with only the ISB/DSB pair.
- Both 16-byte branch-site rewrites (dispatch and branch) atomically
  overwrite live code and only issued the ISB/DSB pair.

The ISB/DSB pairs adjacent to the new flushes are removed along with
their misleading "flush all cache lines" comments: the flush helper
already issues the trailing barriers, and the pairs never performed
any cache maintenance in the first place.

I want to be upfront that this was not the cause of the hang I was
debugging (a same-item compilation race, fixed separately), and I have
not observed a failure that this change alone fixes. It is a latent
correctness issue on any ARM64 host: nothing prevents another core
from fetching stale instruction bytes for freshly published code.
2026-08-09 22:19:32 -04:00
..
2026-03-01 09:20:32 +02:00
2025-02-11 20:38:35 +01:00
2026-06-16 01:28:35 +02:00
2025-02-11 20:38:35 +01:00
2026-06-14 17:41:33 +02:00
2026-05-08 21:42:29 +02:00
2026-07-15 15:19:36 +02:00
2025-02-11 20:38:35 +01:00
2026-04-22 15:06:02 +02:00
2026-04-22 15:06:02 +02:00
2026-06-13 19:08:16 +02:00
2026-06-16 12:07:57 +02:00
2026-05-13 11:43:32 +03:00
2026-04-30 20:41:35 +02:00
2026-06-13 19:08:16 +02:00
2026-06-18 21:16:12 +02:00
2026-06-18 21:16:12 +02:00