From a3c4ef8e06dd62add6c90a85099fddaceb37e53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 20 Oct 2026 09:52:17 +0200 Subject: [PATCH] CPU: Let each MIPSState own its JIT The global MIPSComp::jit becomes MIPSState::jit, created and deleted by the state it runs. JitAt() compiles with the JIT of the state it's handed, so the dispatchers no longer go through a global. Code that is about the main CPU by nature (the UI, the crash handler, the disassembler's symbol lookup, the JIT harness) uses mipsr4k.jit. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/HLE/sceKernelThread.cpp | 4 +- Core/MIPS/Interpreter.cpp | 6 +-- Core/MIPS/JitCommon/JitCommon.cpp | 14 +++---- Core/MIPS/JitCommon/JitCommon.h | 4 +- Core/MIPS/MIPS.cpp | 62 +++++++++++++++---------------- Core/MIPS/MIPS.h | 7 ++++ Core/MemFault.cpp | 14 +++---- UI/CwCheatScreen.cpp | 8 ++-- UI/DebugOverlay.cpp | 4 +- UI/ImDebugger/ImDebugger.cpp | 4 +- UI/ImDebugger/ImJitViewer.cpp | 2 +- UI/JitCompareScreen.cpp | 28 +++++++------- UI/MiscScreens.cpp | 6 +-- Windows/MainWindow.cpp | 2 +- unittest/JitHarness.cpp | 40 ++++++++++---------- 15 files changed, 103 insertions(+), 102 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index ae972af596..cc0f0b0c84 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1453,9 +1453,9 @@ void __KernelLoadContext(const PSPThreadContext *ctx, bool vfpuEnabled) { memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other)); // Not locking here, we assume the jit isn't switched during execution. - if (MIPSComp::jit) { + if (currentMIPS->jit) { // When thread switching, we must update the rounding mode if cached in the jit. - MIPSComp::jit->UpdateFCR31(); + currentMIPS->jit->UpdateFCR31(); } // Reset the llBit, the other thread may have touched memory. diff --git a/Core/MIPS/Interpreter.cpp b/Core/MIPS/Interpreter.cpp index dc92a72e02..65824b91e1 100644 --- a/Core/MIPS/Interpreter.cpp +++ b/Core/MIPS/Interpreter.cpp @@ -198,7 +198,7 @@ namespace MIPSInt { int size = 0x40 + (addr & 0x3F); // Through MIPSState, which also drops replacement hooks in functions the game changed. mips->InvalidateICacheRangeImmediate(alignedAddr, size); - if (MIPSComp::jit) { + if (mips->jit) { // Using a bool to avoid locking/etc. in case it's slow. if (!loggedAlignment && (addr & 0x3F) != 0) { // These are seen exclusively in Lego games, and are really no big deal. Reporting removed. @@ -745,9 +745,9 @@ namespace MIPSInt { mips->fcr31 = value & 0x0181FFFF; mips->fpcond = (value >> 23) & 1; // Don't bother locking, assuming the CPU can't be reset now anyway. - if (MIPSComp::jit) { + if (mips->jit) { // In case of DISABLE, we need to tell jit we updated FCR31. - MIPSComp::jit->UpdateFCR31(); + mips->jit->UpdateFCR31(); } else { // The interpreter emulates the rounding mode by putting the host FPU in it, // so it has to switch right here rather than at the next block boundary. diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index aaa47a386e..f9ca593f45 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -51,15 +51,13 @@ #endif namespace MIPSComp { - JitInterface *jit; - void JitAt(MIPSState *mips) { // TODO: We could probably check for a bad pc here, and fire an exception. Could spare us from some crashes. // Although, we just tried to load from this address to check for a JIT block, and if we're here, that succeeded.. - jit->Compile(mips->pc); + mips->jit->Compile(mips->pc); } - void DoDummyJitState(PointerWrap &p) { + void DoDummyJitState(PointerWrap &p, const MIPSState *mips) { // This is here so the savestate matches between jit and non-jit. auto s = p.Section("Jit", 1, 2); if (!s) @@ -67,7 +65,7 @@ namespace MIPSComp { // This is startDefaultPrefix. Writing false made a JIT loading the state assume an uneaten // prefix for the rest of the session. - bool dummy = currentMIPS->HasDefaultPrefix(); + bool dummy = mips->HasDefaultPrefix(); Do(p, dummy); if (s >= 2) { dummy = true; @@ -176,9 +174,9 @@ std::string AddAddress(const std::string &buf, uint64_t addr) { #if PPSSPP_ARCH(ARM64) || defined(DISASM_ALL) static bool Arm64SymbolCallback(char *buffer, int bufsize, uint8_t *address) { - if (MIPSComp::jit) { + if (mipsr4k.jit) { std::string name; - if (MIPSComp::jit->DescribeCodePtr(address, name)) { + if (mipsr4k.jit->DescribeCodePtr(address, name)) { truncate_cpy(buffer, bufsize, name); return true; } @@ -269,7 +267,7 @@ const char *ppsspp_resolver(struct ud*, static char buf[128]; std::string str; - if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) { + if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) { *offset = 0; truncate_cpy(buf, sizeof(buf), str); return buf; diff --git a/Core/MIPS/JitCommon/JitCommon.h b/Core/MIPS/JitCommon/JitCommon.h index 6ac328df69..055bf58b7d 100644 --- a/Core/MIPS/JitCommon/JitCommon.h +++ b/Core/MIPS/JitCommon/JitCommon.h @@ -182,9 +182,7 @@ namespace MIPSComp { // This seems to be the same for all branch types. u32 ResolveNotTakenTarget(const BranchInfo &branchInfo); - extern JitInterface *jit; - - void DoDummyJitState(PointerWrap &p); + void DoDummyJitState(PointerWrap &p, const MIPSState *mips); JitInterface *CreateNativeJit(MIPSState *mipsState); } diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 5bfd2c67bd..a6757ab884 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -232,8 +232,6 @@ const float cst_constants[32] = { }; MIPSState::MIPSState() { - MIPSComp::jit = nullptr; - // Initialize vorder // This reordering of the VFPU registers in RAM means that instead of being like this: @@ -304,18 +302,18 @@ MIPSState::~MIPSState() { } // The block shadow's replacement hook entries have to match the JIT's dispatcher. -static void UpdateBlockShadowHook() { - Replacement_SetBlockShadowHook(MIPSComp::jit ? MIPSComp::jit->GetBlockShadowHookValue() : Memory::BLOCK_SHADOW_HOOK_NO_JIT); +static void UpdateBlockShadowHook(const MIPSComp::JitInterface *jit) { + Replacement_SetBlockShadowHook(jit ? jit->GetBlockShadowHookValue() : Memory::BLOCK_SHADOW_HOOK_NO_JIT); } void MIPSState::Shutdown() { - MIPSComp::JitInterface *oldjit = MIPSComp::jit; + MIPSComp::JitInterface *oldjit = jit; if (oldjit) { oldjit->FlushProfile(); - MIPSComp::jit = nullptr; + jit = nullptr; delete oldjit; } - UpdateBlockShadowHook(); + UpdateBlockShadowHook(jit); pendingInvalidates_.clear(); invalidateAll_ = false; } @@ -328,13 +326,13 @@ void MIPSState::Reset() { void MIPSState::Init() { InitRegisters(); if (PSP_CoreParameter().cpuCore == CPUCore::JIT || PSP_CoreParameter().cpuCore == CPUCore::JIT_IR) { - MIPSComp::jit = MIPSComp::CreateNativeJit(this); + jit = MIPSComp::CreateNativeJit(this); } else if (PSP_CoreParameter().cpuCore == CPUCore::IR_INTERPRETER) { - MIPSComp::jit = new MIPSComp::IRJit(this, false); + jit = new MIPSComp::IRJit(this, false); } else { - MIPSComp::jit = nullptr; + jit = nullptr; } - UpdateBlockShadowHook(); + UpdateBlockShadowHook(jit); } void MIPSState::InitRegisters() { @@ -386,9 +384,9 @@ void MIPSState::UpdateCore(CPUCore desired) { IncrementDebugCounter(DebugCounter::CPUCORE_SWITCHES); // Get rid of the old JIT first, before switching. - if (MIPSComp::jit) { - delete MIPSComp::jit; - MIPSComp::jit = nullptr; + if (jit) { + delete jit; + jit = nullptr; } PSP_CoreParameter().cpuCore = desired; @@ -416,12 +414,12 @@ void MIPSState::UpdateCore(CPUCore desired) { break; } - MIPSComp::jit = newjit; + jit = newjit; if (newjit) { // The game may already have set a rounding mode on the previous core. newjit->UpdateFCR31(); } - UpdateBlockShadowHook(); + UpdateBlockShadowHook(jit); } void MIPSState::DoState(PointerWrap &p) { @@ -430,10 +428,10 @@ void MIPSState::DoState(PointerWrap &p) { return; if (p.mode == p.MODE_READ) { - if (MIPSComp::jit && !keepJitBlocks_.empty()) { + if (jit && !keepJitBlocks_.empty()) { // Blocks in code the load didn't change can stay. Queued invalidations stay too. InitRegisters(); - MIPSComp::jit->InvalidateCacheExcept(keepJitBlocks_); + jit->InvalidateCacheExcept(keepJitBlocks_); } else { // Start the JIT over. Reset(); @@ -441,10 +439,10 @@ void MIPSState::DoState(PointerWrap &p) { keepJitBlocks_.clear(); } // Assume we're not saving state during a CPU core reset, so no lock. - if (MIPSComp::jit) - MIPSComp::jit->DoState(p); + if (jit) + jit->DoState(p); else - MIPSComp::DoDummyJitState(p); + MIPSComp::DoDummyJitState(p, this); DoArray(p, r, sizeof(r) / sizeof(r[0])); DoArray(p, f, sizeof(f) / sizeof(f[0])); @@ -480,9 +478,9 @@ void MIPSState::DoState(PointerWrap &p) { Do(p, llBit); Do(p, debugCount); - if (p.mode == p.MODE_READ && MIPSComp::jit) { + if (p.mode == p.MODE_READ && jit) { // Now that we've loaded fcr31, update any jit state associated. - MIPSComp::jit->UpdateFCR31(); + jit->UpdateFCR31(); } } @@ -505,7 +503,7 @@ int MIPSState::RunLoopUntil(u64 globalTicks) { downcount -= cycles; } ProcessPendingInvalidates(); - MIPSComp::jit->RunLoopUntil(globalTicks); + jit->RunLoopUntil(globalTicks); break; case CPUCore::INTERPRETER: @@ -517,12 +515,12 @@ int MIPSState::RunLoopUntil(u64 globalTicks) { void MIPSState::InvalidateICacheRangeImmediate(u32 address, u32 length) { Replacement_CheckRange(address, length); - if (!MIPSComp::jit) { + if (!jit) { // Nothing to do. return; } if (length != 0) { - MIPSComp::jit->InvalidateCacheAt(address, length); + jit->InvalidateCacheAt(address, length); } } @@ -536,12 +534,12 @@ void MIPSState::ProcessPendingInvalidates() { pending.swap(pendingInvalidates_); for (const auto &p : pending) { Replacement_CheckRange(p.addr, p.size); - if (MIPSComp::jit && !all) { - MIPSComp::jit->InvalidateCacheAt(p.addr, p.size); + if (jit && !all) { + jit->InvalidateCacheAt(p.addr, p.size); } } - if (MIPSComp::jit && all) { - MIPSComp::jit->ClearCache(); + if (jit && all) { + jit->ClearCache(); } } } @@ -549,14 +547,14 @@ void MIPSState::ProcessPendingInvalidates() { void MIPSState::InvalidateICacheRangeDeferred(u32 address, u32 length) { // TODO: We can try to merge the invalidate with the previous one. pendingInvalidates_.push_back(PendingCacheOperation{address, length}); - if (MIPSComp::jit) { + if (jit) { Core_ReenterDispatcher(); } } // Queued ranges still get their replacement hook checks. void MIPSState::ClearJitCacheDeferred() { - if (!MIPSComp::jit) { + if (!jit) { return; } diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index 53f131b637..d3877f6e56 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -30,6 +30,10 @@ class PointerWrap; +namespace MIPSComp { +class JitInterface; +} + typedef Memory::Opcode MIPSOpcode; // A fake opcode the CPU cores fetch in place of an instruction with a replacement function (see @@ -304,6 +308,9 @@ public: std::vector pendingInvalidates_; bool invalidateAll_ = false; std::vector> keepJitBlocks_; + + // Owned. Null on the interpreter. + MIPSComp::JitInterface *jit = nullptr; }; // Access control ('private') break standard layout. Let's not allow it, to avoid excessive diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index c07fb0c07f..3fdf3adeb0 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -125,7 +125,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { g_lastCrashAddress = nullptr; // TODO: Check that codePtr is within the current JIT space. - bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr); + bool inJitSpace = mipsr4k.jit && mipsr4k.jit->CodeInRange(codePtr); if (!inJitSpace) { // This is a crash in non-jitted code. Not something we want to handle here, ignore. // Actually, we could handle crashes from the IR interpreter here, although recovering the call stack @@ -210,7 +210,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { success = false; #endif - if (MIPSComp::jit && (shadowFault || MIPSComp::jit->IsAtDispatchFetch(codePtr))) { + if (mipsr4k.jit && (shadowFault || mipsr4k.jit->IsAtDispatchFetch(codePtr))) { // The shadow entry's offset is the target, masked. u32 targetAddr = shadowFault ? guestAddress : currentMIPS->pc; // TODO: Do the other archs and platforms. @@ -220,7 +220,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { #endif Core_ExecException(targetAddr, currentMIPS->pc, ExecExceptionType::JUMP); // Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately. - uintptr_t crashHandler = (uintptr_t)MIPSComp::jit->GetCrashHandler(); + uintptr_t crashHandler = (uintptr_t)mipsr4k.jit->GetCrashHandler(); if (crashHandler != 0) { context->CTX_PC = crashHandler; ERROR_LOG(Log::MemMap, "Bad execution access detected, halting: %08x (last known pc %08x, host: %p)", targetAddr, currentMIPS->pc, (void *)hostAddress); @@ -252,7 +252,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { g_numReportedBadAccesses++; if (g_numReportedBadAccesses < 100) { std::string temp; - if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(codePtr, temp)) { + if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr(codePtr, temp)) { ERROR_LOG(Log::MemMap, "Bad memory access detected and ignored: %08x (%p) at %s", guestAddress, (void *)hostAddress, temp.c_str()); } else { ERROR_LOG(Log::MemMap, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress); @@ -261,7 +261,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { } else { std::string infoString = ""; std::string temp; - if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(codePtr, temp)) { + if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr(codePtr, temp)) { infoString += temp + " "; } temp.clear(); @@ -281,8 +281,8 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { // Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately. uintptr_t crashHandler = 0; - if (MIPSComp::jit) - crashHandler = (uintptr_t)MIPSComp::jit->GetCrashHandler(); + if (mipsr4k.jit) + crashHandler = (uintptr_t)mipsr4k.jit->GetCrashHandler(); if (crashHandler != 0) context->CTX_PC = crashHandler; else diff --git a/UI/CwCheatScreen.cpp b/UI/CwCheatScreen.cpp index e2b68bd9a7..3d0d1c5e21 100644 --- a/UI/CwCheatScreen.cpp +++ b/UI/CwCheatScreen.cpp @@ -376,8 +376,8 @@ void CwCheatScreen::onFinish(DialogResult result) { if (result != DR_BACK) // This only works for BACK here. return; - if (MIPSComp::jit) { - MIPSComp::jit->ClearCache(); + if (mipsr4k.jit) { + mipsr4k.jit->ClearCache(); } } @@ -401,8 +401,8 @@ void CwCheatScreen::OnAddCheat(UI::EventParams ¶ms) { void CwCheatScreen::OnEditCheatFile(UI::EventParams ¶ms) { g_Config.bReloadCheats = true; - if (MIPSComp::jit) { - MIPSComp::jit->ClearCache(); + if (mipsr4k.jit) { + mipsr4k.jit->ClearCache(); } if (engine_) { File::OpenFileInEditor(engine_->CheatFilename()); diff --git a/UI/DebugOverlay.cpp b/UI/DebugOverlay.cpp index 1edb26f277..755a6cc2f5 100644 --- a/UI/DebugOverlay.cpp +++ b/UI/DebugOverlay.cpp @@ -72,9 +72,9 @@ static void DrawJitStats(UIContext *ctx, const Bounds &bounds) { char statbuf[1024]; StringWriter w(statbuf, sizeof(statbuf)); - if (MIPSComp::jit) { + if (mipsr4k.jit) { MIPSComp::JitStats stats; - MIPSComp::jit->GetStats(&stats); + mipsr4k.jit->GetStats(&stats); const double irPercent = stats.irArenaSize ? 100.0 * stats.irArenaUsed / stats.irArenaSize : 0.0; w.F("Blocks: %d (%d valid)\n", stats.numBlocks, stats.numValidBlocks); if (stats.codeSize) { diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 92e0e7818b..0beabbaad6 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -922,8 +922,8 @@ static void DrawInternals(ImConfig &cfg) { if (ImGui::CollapsingHeader("Memory")) { ImGui::Text("Base pointer: %p", Memory::base); ImGui::Text("Main memory size: %08x", Memory::g_MemorySize); - if (MIPSComp::jit) { - ImGui::Text("JIT code cache: %p", MIPSComp::jit->GetCodeBase()); + if (mipsr4k.jit) { + ImGui::Text("JIT code cache: %p", mipsr4k.jit->GetCodeBase()); ImGui::Text("MIPS state: %p", currentMIPS); } if (ImGui::Button("Copy to clipboard")) { diff --git a/UI/ImDebugger/ImJitViewer.cpp b/UI/ImDebugger/ImJitViewer.cpp index fc5218d817..0290739f8a 100644 --- a/UI/ImDebugger/ImJitViewer.cpp +++ b/UI/ImDebugger/ImJitViewer.cpp @@ -63,7 +63,7 @@ void ImJitViewerWindow::Draw(ImConfig &cfg, ImControl &control) { numColumns = 4; } - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface(); if (core_ != (int)core) { // Core changed, need to refresh. diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index 5dc71a83f8..fe3f3964cf 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -13,10 +13,10 @@ #include "UI/PopupScreens.h" JitCompareScreen::JitCompareScreen() : UITabbedBaseDialogScreen(Path()) { - if (!MIPSComp::jit) { + if (!mipsr4k.jit) { return; } - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface(); // The only defaults that make sense. if (blockCacheDebug->SupportsProfiling()) { listSort_ = ListSort::TIME_SPENT; @@ -43,8 +43,8 @@ void JitCompareScreen::CreateTabs() { { "Executions", "I_ARROW_DOWN" }, }; int sortCount = ARRAY_SIZE(sortMenu); - if (MIPSComp::jit) { - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (mipsr4k.jit) { + JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface(); if (!blockCacheDebug->SupportsProfiling()) { sortCount -= 2; } @@ -133,7 +133,7 @@ void JitCompareScreen::CreateTabs() { } void JitCompareScreen::FillBlockList() { - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface(); blockList_.clear(); int64_t sumTotalNanos = 0; int64_t sumExecutions = 0; @@ -226,11 +226,11 @@ void JitCompareScreen::UpdateDisasm() { using namespace UI; - if (!MIPSComp::jit) { + if (!mipsr4k.jit) { return; } - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface(); FillBlockList(); @@ -337,10 +337,10 @@ void JitCompareScreen::OnBlockClick(UI::EventParams &e) { } void JitCompareScreen::OnAddressChange(UI::EventParams &e) { - if (!MIPSComp::jit) { + if (!mipsr4k.jit) { return; } - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCache = mipsr4k.jit->GetBlockCacheDebugInterface(); if (!blockCache) return; u32 addr; @@ -363,11 +363,11 @@ void JitCompareScreen::OnSelectBlock(UI::EventParams &e) { } void JitCompareScreen::OnBlockAddress(UI::EventParams &e) { - if (!MIPSComp::jit) { + if (!mipsr4k.jit) { return; } - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCache = mipsr4k.jit->GetBlockCacheDebugInterface(); if (!blockCache) return; @@ -381,11 +381,11 @@ void JitCompareScreen::OnBlockAddress(UI::EventParams &e) { /* void JitCompareScreen::OnRandomBlock(int flag) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { + std::lock_guard guard(mipsr4k.jitLock); + if (!mipsr4k.jit) { return; } - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *blockCache = mipsr4k.jit->GetBlockCacheDebugInterface(); if (!blockCache) return; diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 6cd439476f..f1db4d1054 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -66,9 +66,9 @@ void HandleCommonMessages(UIMessage message, const char *value, ScreenManager *m if (message == UIMessage::REQUEST_CLEAR_JIT && PSP_IsInited()) { // TODO: This seems to clearly be the wrong place to handle this. - if (MIPSComp::jit) { - if (MIPSComp::jit) - MIPSComp::jit->ClearCache(); + if (mipsr4k.jit) { + if (mipsr4k.jit) + mipsr4k.jit->ClearCache(); } currentMIPS->UpdateCore((CPUCore)g_Config.iCpuCore); } else if (message == UIMessage::SHOW_CONTROL_MAPPING && isActiveScreen && std::string(activeScreen->tag()) != "ControlMapping") { diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index 073ec990f9..966f84dfec 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -1027,7 +1027,7 @@ namespace MainWindow { const u8 *ptr = (const u8 *)info->addr; std::string name; - if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) { + if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr(ptr, name)) { swprintf_s(info->name, L"Jit::%S", name.c_str()); return; } diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 2fd8784bf2..ce4d6c2c63 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -87,7 +87,7 @@ HLEFunction UnitTestFakeSyscalls[] = { double ExecCPUTest(bool clearCache = true) { int blockTicks = 1000000; - if (MIPSComp::jit) { + if (mipsr4k.jit) { currentMIPS->pc = PSP_GetUserMemoryBase(); MIPSComp::JitAt(currentMIPS); } @@ -101,15 +101,15 @@ double ExecCPUTest(bool clearCache = true) { } }, 0.5, 1000); - if (MIPSComp::jit) { - JitBlockCacheDebugInterface *cache = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (mipsr4k.jit) { + JitBlockCacheDebugInterface *cache = mipsr4k.jit->GetBlockCacheDebugInterface(); if (cache) { JitBlockDebugInfo block = cache->GetBlockDebugInfo(0); WARN_LOG(Log::JIT, "Executed %d target instrs, %d IR, for %d orig", (int)block.targetDisasm.size(), (int)block.irDisasm.size(), (int)block.origDisasm.size()); } if (clearCache) - MIPSComp::jit->ClearCache(); + mipsr4k.jit->ClearCache(); } return callsPerSecond; @@ -200,7 +200,7 @@ bool TestJit() { printf("%s modified the code in PSP memory\n", core); memoryClean = false; } - if (MIPSComp::jit && Memory::ReadBlockShadow(PSP_GetUserMemoryBase()) == 0) { + if (mipsr4k.jit && Memory::ReadBlockShadow(PSP_GetUserMemoryBase()) == 0) { printf("%s didn't enter its block in the block shadow\n", core); memoryClean = false; } @@ -224,13 +224,13 @@ bool TestJit() { mipsr4k.UpdateCore(CPUCore::IR_INTERPRETER); ir_speed = ExecCPUTest(false); checkMemoryClean("IR interpreter"); - MIPSComp::jit->ClearCache(); + mipsr4k.jit->ClearCache(); mipsr4k.UpdateCore(CPUCore::JIT); jit_speed = ExecCPUTest(false); // not clearing, so the below can do things. checkMemoryClean("JIT"); // Disassemble - JitBlockCacheDebugInterface *cache = MIPSComp::jit->GetBlockCacheDebugInterface(); + JitBlockCacheDebugInterface *cache = mipsr4k.jit->GetBlockCacheDebugInterface(); if (cache) { JitBlockDebugInfo block = cache->GetBlockDebugInfo(0); // Should only be one block. std::vector &lines = block.targetDisasm; @@ -297,11 +297,11 @@ bool TestJitDotBench() { mipsr4k.UpdateCore(CPUCore::JIT); const double callsPerSecond = ExecCPUTest(false); if (getenv("PPSSPP_JITBENCH_DISASM")) { - JitBlockDebugInfo block = MIPSComp::jit->GetBlockCacheDebugInterface()->GetBlockDebugInfo(0); + JitBlockDebugInfo block = mipsr4k.jit->GetBlockCacheDebugInterface()->GetBlockDebugInfo(0); for (size_t i = 0; i < block.targetDisasm.size() && i < 80; i++) printf(" %s\n", block.targetDisasm[i].c_str()); } - MIPSComp::jit->ClearCache(); + mipsr4k.jit->ClearCache(); printf("%-14s %6.2f ns per dot\n", seq.name, 1e9 / (callsPerSecond * groups * seq.dots)); } @@ -337,7 +337,7 @@ static bool CheckReplacementHooks(u32 func, u32 size, const std::vector &cod }; for (CPUCore core : cores) { mipsr4k.UpdateCore(core); - const u32 hook = MIPSComp::jit->GetBlockShadowHookValue(); + const u32 hook = mipsr4k.jit->GetBlockShadowHookValue(); EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), hook); // Compiling replaces the hook value with the block's entry. @@ -346,11 +346,11 @@ static bool CheckReplacementHooks(u32 func, u32 size, const std::vector &cod EXPECT_TRUE(block != 0 && block != hook); // Destroying the block puts it back, whichever way it goes. - MIPSComp::jit->InvalidateCacheAt(func, 4); + mipsr4k.jit->InvalidateCacheAt(func, 4); EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), hook); compile(); - MIPSComp::jit->ClearCache(); - EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), MIPSComp::jit->GetBlockShadowHookValue()); + mipsr4k.jit->ClearCache(); + EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), mipsr4k.jit->GetBlockShadowHookValue()); // Leave a block for the core switch to destroy. compile(); @@ -398,7 +398,7 @@ static bool CheckReplacementHooks(u32 func, u32 size, const std::vector &cod // The game overwriting the hooked instruction drops the hook. MIPSAnalyst::ReplaceFunctions(); - EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), MIPSComp::jit->GetBlockShadowHookValue()); + EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), mipsr4k.jit->GetBlockShadowHookValue()); Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), func); EXPECT_EQ_HEX(ReadExecutedOp(func).encoding, MIPS_MAKE_NOP()); EXPECT_FALSE(Replacement_IsHooked(func)); @@ -836,8 +836,8 @@ static void RunFuzzCase(const std::vector &code, const FuzzState &init, Fuz for (int i = 0; i < FUZZ_MAX_INSTRS; ++i) { Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), addr + 12 + i * 4); } - if (MIPSComp::jit && !keepCache) { - MIPSComp::jit->ClearCache(); + if (mipsr4k.jit && !keepCache) { + mipsr4k.jit->ClearCache(); } MIPSState *mips = currentMIPS; @@ -850,8 +850,8 @@ static void RunFuzzCase(const std::vector &code, const FuzzState &init, Fuz mips->lo = init.lo; mips->fcr31 = init.fcr31; // As a thread switch does, or a JIT keeps converting in the previous case's rounding mode. - if (MIPSComp::jit) { - MIPSComp::jit->UpdateFCR31(); + if (mipsr4k.jit) { + mipsr4k.jit->UpdateFCR31(); } mips->fpcond = init.fpcond; mips->llBit = 0; @@ -866,8 +866,8 @@ static void RunFuzzCase(const std::vector &code, const FuzzState &init, Fuz } out->cycles = (u32)(g_terminatorTicks - startTicks); - if (g_fuzzPrintBlocks && MIPSComp::jit) { - JitBlockCacheDebugInterface *blocks = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (g_fuzzPrintBlocks && mipsr4k.jit) { + JitBlockCacheDebugInterface *blocks = mipsr4k.jit->GetBlockCacheDebugInterface(); for (int i = 0; i < blocks->GetNumBlocks(); i++) { if (!blocks->IsValidBlock(i)) continue;