Commit Graph
250 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5.5 48973c83c6 Debugger: Show replacement hooks in the disassembly again
Memory no longer holds the hooks, so the disassembly fetches the op the CPU runs, which is the
CallRepl pseudo-op at a hooked address. That lookup can come from the Win32 debugger's UI thread,
so the CPU thread now changes the hook map under a lock (and reads it without, being the only
writer).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:33:30 +02:00
Henrik RydgårdandClaude Opus 5.5 6d122f416e Keep JIT block entries and replacement hooks out of PSP memory
The JITs used to find a block by overwriting its first instruction with an "emuhack" holding
the offset into the code space, and replacement functions installed their own emuhack the same
way. Anything that read code (savestates, the debugger, memory dumps, cheats, the function
hasher, games reading their own code) had to translate them back.

Blocks now live in a block shadow: one u32 per guest instruction, indexed by the PC masked with
BLOCK_SHADOW_MASK (1GB on 64-bit, folding the kernel and uncached mirrors; 256MB on 32-bit, iOS
and Switch, where address space is short), with the low bits cleared so a misaligned PC can't
read across two entries. Only the ranges under memory views are committed, so a bad PC still
faults in the dispatcher, and the shadow is reserved before the memory map so it can't land in
a gap of the 4GB window. Entries hold full 32-bit offsets, lifting the 16MB limit. The
dispatchers on every backend, and the IR interpreter's loop, look blocks up there.

A hooked instruction without a compiled block gets the JIT's hook value in its entry: the offset
of the dispatcher's compile path (1 for the interpreters, the IR arena keeping that offset
empty), so dispatching there compiles a block, and the frontends substitute the hook. Compiling
replaces the entry with the block's, and destroying the block puts the hook value back. The hook
value is rewritten when the JIT changes or regenerates its dispatcher.

Hooks live in a map keyed by the masked address, and are dropped when the game overwrites the
hooked instruction, or when an icache invalidation finds the function's hash (immediates masked,
as when matching it) changed. Those checks run when queued invalidations are processed, since
cheats and the debugger queue them before writing. Installing and removing hooks invalidates
deferred, as it happens in HLE calls that can run inside a block. The cache instruction goes
through MIPSState, so it drops changed hooks too.

With clean memory, the save/clear/restore around savestates, memory reads and dumps goes away,
as do the source-range invalidations in the memcpy replacements, sceDmac and the cheats.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 10:33:30 +02:00
Henrik RydgårdandClaude Opus 5.5 a4ce937f81 Savestate: Bounds-check BufferQueue and Atrac pending output, fix dummy JIT prefix
An interpreter state always claimed an uneaten VFPU prefix, which made a
JIT loading it run in unknown-prefix mode for the rest of the session.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 11:32:07 -06:00
Henrik Rydgård 7a9a354e50 Add a MIPSState context pointer to the JitAt call 2026-09-21 17:34:10 -06:00
Henrik RydgårdandClaude Opus 5 6c7fc8df37 JitBlockCache: fix the invalidation margin, and unlink destroyed blocks
InvalidateICache widened its search by MAX_BLOCK_INSTRUCTIONS, but
block_map_ is keyed by byte addresses - a block can span four times that
many bytes. A block longer than 0x4000 bytes starting just below the end
of the invalidated range could therefore be missed and left behind after
the code under it changed. Multiply by 4.

DestroyBlock's "invalid original address" safety check returned after
setting b->invalid but before UnlinkBlock() and the checkedEntry
poisoning, so other blocks kept jumping directly into a block the cache
had already written off. The check is there to guard the memory access
that restores the original opcode, so only guard that.

Also: codeSize is a byte count assigned from a full pointer difference,
so a block over 64KB truncated it (affecting GetAddressFromBlockPtr and
the disassembly view); widen it to u32. The RAMTOP range check missed a
block sitting exactly on the user-memory midpoint, since the RAMBOTTOM
check next to it is strict. And GetBlockDebugInfo disassembled one
instruction past the end of the block.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 11:32:24 -06:00
Henrik Rydgård 4fb5d5965c MMIO: Simplest possible kernel-mode permission check, start work on supporting in JIT 2026-08-21 10:32:22 +02:00
Henrik Rydgård a49f4523cb Correct when we process the stepping queue. Also, the jitLock mutex is no longer needed. 2026-08-16 13:33:26 +02:00
Henrik Rydgård 3bd41376da More memory cleanup 2026-08-11 20:12:10 +02:00
Henrik Rydgård 1e57d8110f Minor blockcache improvement 2026-02-25 00:52:25 +01:00
Henrik Rydgård 1c049b63d5 Throw in a safety check in JitBlockCache::DestroyBlock. 2026-02-19 00:30:39 +01:00
Henrik Rydgård 8897b5914a Improve integrity checks in JIT (trying to catch an elusive crash) 2026-02-17 22:42:04 +01:00
Henrik Rydgård 1b0e701c87 Expose some more pointers in the ImDebugger UI 2026-02-17 22:40:00 +01:00
Henrik Rydgård f0ba391a4e Remove the whole concept of proxy blocks from the block cache, and experimental uses of it. 2026-02-17 09:40:27 +01:00
Henrik Rydgård 2797cfca56 Remove more vestiges of old experiments 2026-02-12 01:23:48 +01:00
Henrik Rydgård 44a2585753 Rename some function, remove an unused return value 2026-02-12 01:23:45 +01:00
Henrik Rydgård d5444a7f46 Remove old rudimentary start at a MIPS->MIPS jit 2026-02-11 23:33:41 +01:00
Henrik Rydgård b999c51a1a Code cleanup. Don't use gpr.SetRegImm where all we do is write to a scratch register 2026-02-10 19:28:53 +01:00
Henrik Rydgård 4a8aeac38a Jit: Remove unused x86-only feature continueBranches. 2026-01-29 17:41:57 +01:00
Henrik Rydgård ed5a052258 Remove unused initial work for adding NEON support to ARM JITs.
Our SIMD strategy for ARM is the JitUsingIR.
2026-01-29 17:41:57 +01:00
Henrik Rydgård 8631e77db2 Delete some outdated profiler integrations 2026-01-01 13:55:30 +01:00
Henrik Rydgård 1facc4d485 Remove obsolete hidden setting Browse 2025-11-04 23:39:56 +01:00
Henrik Rydgård a170f40927 Qt buildfix 2025-10-10 08:45:09 -06:00
Henrik Rydgård a72fc6f79c Support showing (and sorting by) IR profiler info in the JIT viewer
This will help future work on #19143 .
2025-10-09 17:02:52 -06:00
Henrik Rydgård 5751e202a5 Remove redundant .c_str() 2025-08-31 13:37:43 +02:00
Lin Runze 1d910b81ff loongarch: Add emitter, JIT and disassembler support for LoongArch64 2025-07-12 03:21:23 +08:00
Henrik Rydgård ffb1e01e7e Fix shutdown performance regression 2025-06-26 11:06:21 +02:00
Henrik Rydgård 6df9e513c1 Logging, comments and debugger fixes, plus simple dumping of the first block of streaming Atrac3 2025-06-25 01:08:47 +02:00
Henrik Rydgård b51c5da003 Fix order of operations when clearing JitBlockCaches. 2025-06-12 10:05:19 +02:00
Henrik Rydgård ba148e5ec7 JIT/IRJit: Delete an old "function preloading" experiment
This caused some confusion while trying to debug #20502
2025-06-11 15:45:18 +02:00
Henrik Rydgård 0e3c1df9b3 Add a way to access the ImDebugger from the DevMenu 2024-11-21 15:48:18 +01:00
Henrik Rydgård cf678a1aa6 JIT: Allow more blocks to be stored in the cache. Also, add margin to the IsFull check. 2024-10-28 17:02:03 +01:00
Henrik Rydgård c1d6b62625 Add a couple of asserts to the JitBlockCache. 2024-10-23 13:23:38 +02:00
Henrik Rydgård e01ca5b057 Logging API change (refactor) (#19324)
* Rename LogType to Log

* Explicitly use the Log:: enum when logging. Allows for autocomplete when editing.

* Mac/ARM64 buildfix

* Do the same with the hle result log macros

* Rename the log names to mixed case while at it.

* iOS buildfix

* Qt buildfix attempt, ARM32 buildfix
2024-07-14 14:42:59 +02:00
Henrik Rydgård 0ea9120ca5 Add a stats view 2024-06-06 19:21:50 +02:00
Henrik Rydgård 294593f741 Fix IR profiling 2024-06-05 19:12:08 +02:00
Henrik Rydgård 3bb74ea9ad Rework the JitCompare window to hold a list of blocks, and allow some filtering and browsing 2024-06-05 18:16:33 +02:00
Henrik Rydgård ba1ced77c3 IRJit block profiling basics 2024-06-05 13:02:40 +02:00
Henrik Rydgård f2837e3b55 JIT compare screen with IR blocks - fix some crashing issues 2024-05-26 14:10:50 +02:00
Henrik Rydgård e75e7a0e43 Add an optimizeForInterpreter flag 2024-05-26 13:41:31 +02:00
Herman Semenov 17ecee1715 Fixed return copies from functions and const ref params 2024-04-02 18:37:00 +03:00
Henrik Rydgård 7e427e41d1 Remove a bunch of dead code from CoreTiming ("threadsafe" events)
We haven't used these "threadsafe" events since we removed our first attempt
at GPU threading, so like 10 years, and maybe some experimentation in the
networking code according to some comments. It's unlikely that any
savestates that used these events would load anyway.
2024-01-16 09:06:03 +01:00
Henrik Rydgård 3deabaeb04 JitBlockCache: Add a debug assert 2024-01-15 23:28:59 +01:00
Herman Semenov b871e76d05 [Core/Debugger/FileLoaders/FileSystems/MIPS] Using reserve if possible 2023-12-15 13:59:19 +03:00
Henrik Rydgård 4c0077fd84 Protect against weirdness in UnlinkBlocks (hopefully not needed after prev fix) 2023-09-27 12:31:17 +02:00
Henrik Rydgård dd2b1ace88 BlockCache on ARM/ARM64: Allow two more exits 2023-09-26 19:44:05 +02:00
Henrik Rydgård c0ee711cb9 In the FinalizeBlock assert, extract some more info 2023-09-26 13:37:40 +02:00
Henrik Rydgård e7c0b41867 Improve an assert 2023-09-22 10:58:43 +02:00
Henrik Rydgård 3acbeb3073 Add an assert in JitBlockCache 2023-09-11 13:59:04 +02:00
Unknown W. Brackets 1b756ff8c1 arm64jit: Add initial base for IR jit.
This works, but very slowly at this point.
2023-09-03 12:14:28 -07:00
Unknown W. Brackets 74e5e43fdc jit: Skip known prefix writes.
If we already know what's in memory and it's default, we can skip
overwriting with default values.  This is common, actually.
2023-08-22 23:26:31 -07:00