summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMai <mai.iam2048@gmail.com>2023-03-27 10:31:53 -0400
committerGitHub <noreply@github.com>2023-03-27 10:31:53 -0400
commitc096ee64f2abdef2b095ce8092dcde4146d44fc0 (patch)
treed9c15844712ea6aad1715cf74bdbfde1001caa90 /Source/Core
parent0de2890351ef2e309abd7643a38b8505ba42de19 (diff)
parent7f50c070b232b68df04609f60f02db559e97cc4f (diff)
Merge pull request #11696 from AdmiralCurtiss/jit-interface-class
JitInterface: Refactor to class, move to System.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Core.cpp2
-rw-r--r--Source/Core/Core/HW/GPFifo.cpp2
-rw-r--r--Source/Core/Core/MemTools.cpp16
-rw-r--r--Source/Core/Core/PowerPC/BreakPoints.cpp17
-rw-r--r--Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp7
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp8
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp7
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp12
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp7
-rw-r--r--Source/Core/Core/PowerPC/JitInterface.cpp140
-rw-r--r--Source/Core/Core/PowerPC/JitInterface.h138
-rw-r--r--Source/Core/Core/PowerPC/MMU.cpp4
-rw-r--r--Source/Core/Core/PowerPC/PPCCache.cpp4
-rw-r--r--Source/Core/Core/PowerPC/PowerPC.cpp19
-rw-r--r--Source/Core/Core/System.cpp9
-rw-r--r--Source/Core/Core/System.h2
-rw-r--r--Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp11
-rw-r--r--Source/Core/DolphinQt/MenuBar.cpp2
-rw-r--r--Source/Core/UICommon/Disassembler.cpp3
19 files changed, 236 insertions, 174 deletions
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index b4f0583420..fbc87d18fd 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -986,7 +986,7 @@ void UpdateWantDeterminism(bool initial)
// We need to clear the cache because some parts of the JIT depend on want_determinism,
// e.g. use of FMA.
- JitInterface::ClearCache();
+ system.GetJitInterface().ClearCache();
});
}
}
diff --git a/Source/Core/Core/HW/GPFifo.cpp b/Source/Core/Core/HW/GPFifo.cpp
index 8dc865c379..94d8b905ff 100644
--- a/Source/Core/Core/HW/GPFifo.cpp
+++ b/Source/Core/Core/HW/GPFifo.cpp
@@ -132,7 +132,7 @@ void GPFifoManager::CheckGatherPipe()
UpdateGatherPipe();
// Profile where slow FIFO writes are occurring.
- JitInterface::CompileExceptionCheck(JitInterface::ExceptionType::FIFOWrite);
+ m_system.GetJitInterface().CompileExceptionCheck(JitInterface::ExceptionType::FIFOWrite);
}
}
diff --git a/Source/Core/Core/MemTools.cpp b/Source/Core/Core/MemTools.cpp
index 0011fd3bce..75d20dd6a9 100644
--- a/Source/Core/Core/MemTools.cpp
+++ b/Source/Core/Core/MemTools.cpp
@@ -16,6 +16,7 @@
#include "Core/MachineContext.h"
#include "Core/PowerPC/JitInterface.h"
+#include "Core/System.h"
#if defined(__FreeBSD__) || defined(__NetBSD__)
#include <signal.h>
@@ -60,7 +61,7 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
uintptr_t fault_address = (uintptr_t)pPtrs->ExceptionRecord->ExceptionInformation[1];
SContext* ctx = pPtrs->ContextRecord;
- if (JitInterface::HandleFault(fault_address, ctx))
+ if (Core::System::GetInstance().GetJitInterface().HandleFault(fault_address, ctx))
{
return EXCEPTION_CONTINUE_EXECUTION;
}
@@ -72,7 +73,7 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
}
case EXCEPTION_STACK_OVERFLOW:
- if (JitInterface::HandleStackFault())
+ if (Core::System::GetInstance().GetJitInterface().HandleStackFault())
return EXCEPTION_CONTINUE_EXECUTION;
else
return EXCEPTION_CONTINUE_SEARCH;
@@ -190,7 +191,8 @@ static void ExceptionThread(mach_port_t port)
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
- bool ok = JitInterface::HandleFault((uintptr_t)msg_in.code[1], state);
+ bool ok =
+ Core::System::GetInstance().GetJitInterface().HandleFault((uintptr_t)msg_in.code[1], state);
// Set up the reply.
msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0);
@@ -281,13 +283,13 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context)
mcontext_t* ctx = &context->uc_mcontext;
#endif
// assume it's not a write
- if (!JitInterface::HandleFault(bad_address,
+ if (!Core::System::GetInstance().GetJitInterface().HandleFault(bad_address,
#ifdef __APPLE__
- *ctx
+ *ctx
#else
- ctx
+ ctx
#endif
- ))
+ ))
{
// retry and crash
// According to the sigaction man page, if sa_flags "SA_SIGINFO" is set to the sigaction
diff --git a/Source/Core/Core/PowerPC/BreakPoints.cpp b/Source/Core/Core/PowerPC/BreakPoints.cpp
index 9e3a21c3bc..a3615afb2e 100644
--- a/Source/Core/Core/PowerPC/BreakPoints.cpp
+++ b/Source/Core/Core/PowerPC/BreakPoints.cpp
@@ -16,6 +16,7 @@
#include "Core/PowerPC/Expression.h"
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/MMU.h"
+#include "Core/System.h"
bool BreakPoints::IsAddressBreakPoint(u32 address) const
{
@@ -105,7 +106,7 @@ void BreakPoints::Add(TBreakPoint bp)
if (IsAddressBreakPoint(bp.address))
return;
- JitInterface::InvalidateICache(bp.address, 4, true);
+ Core::System::GetInstance().GetJitInterface().InvalidateICache(bp.address, 4, true);
m_breakpoints.emplace_back(std::move(bp));
}
@@ -141,7 +142,7 @@ void BreakPoints::Add(u32 address, bool temp, bool break_on_hit, bool log_on_hit
m_breakpoints.emplace_back(std::move(bp));
}
- JitInterface::InvalidateICache(address, 4, true);
+ Core::System::GetInstance().GetJitInterface().InvalidateICache(address, 4, true);
}
bool BreakPoints::ToggleBreakPoint(u32 address)
@@ -165,14 +166,14 @@ void BreakPoints::Remove(u32 address)
return;
m_breakpoints.erase(iter);
- JitInterface::InvalidateICache(address, 4, true);
+ Core::System::GetInstance().GetJitInterface().InvalidateICache(address, 4, true);
}
void BreakPoints::Clear()
{
for (const TBreakPoint& bp : m_breakpoints)
{
- JitInterface::InvalidateICache(bp.address, 4, true);
+ Core::System::GetInstance().GetJitInterface().InvalidateICache(bp.address, 4, true);
}
m_breakpoints.clear();
@@ -185,7 +186,7 @@ void BreakPoints::ClearAllTemporary()
{
if (bp->is_temporary)
{
- JitInterface::InvalidateICache(bp->address, 4, true);
+ Core::System::GetInstance().GetJitInterface().InvalidateICache(bp->address, 4, true);
bp = m_breakpoints.erase(bp);
}
else
@@ -278,7 +279,7 @@ void MemChecks::Add(TMemCheck memory_check)
// If this is the first one, clear the JIT cache so it can switch to
// watchpoint-compatible code.
if (!had_any)
- JitInterface::ClearCache();
+ Core::System::GetInstance().GetJitInterface().ClearCache();
PowerPC::DBATUpdated();
});
}
@@ -307,7 +308,7 @@ void MemChecks::Remove(u32 address)
Core::RunAsCPUThread([&] {
m_mem_checks.erase(iter);
if (!HasAny())
- JitInterface::ClearCache();
+ Core::System::GetInstance().GetJitInterface().ClearCache();
PowerPC::DBATUpdated();
});
}
@@ -316,7 +317,7 @@ void MemChecks::Clear()
{
Core::RunAsCPUThread([&] {
m_mem_checks.clear();
- JitInterface::ClearCache();
+ Core::System::GetInstance().GetJitInterface().ClearCache();
PowerPC::DBATUpdated();
});
}
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp
index c87a1e0155..73b0c848b1 100644
--- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp
@@ -16,6 +16,7 @@
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h"
+#include "Core/System.h"
static u32 Helper_Get_EA(const PowerPC::PowerPCState& ppcs, const UGeckoInstruction inst)
{
@@ -473,7 +474,7 @@ void Interpreter::dcbf(Interpreter& interpreter, UGeckoInstruction inst)
// Invalidate the JIT cache here as a heuristic to compensate for
// the lack of precise L1 icache emulation in the JIT. (Portable software
// should use icbi consistently, but games aren't portable.)
- JitInterface::InvalidateICacheLine(address);
+ interpreter.m_system.GetJitInterface().InvalidateICacheLine(address);
return;
}
@@ -495,7 +496,7 @@ void Interpreter::dcbi(Interpreter& interpreter, UGeckoInstruction inst)
// Invalidate the JIT cache here as a heuristic to compensate for
// the lack of precise L1 icache emulation in the JIT. (Portable software
// should use icbi consistently, but games aren't portable.)
- JitInterface::InvalidateICacheLine(address);
+ interpreter.m_system.GetJitInterface().InvalidateICacheLine(address);
return;
}
@@ -511,7 +512,7 @@ void Interpreter::dcbst(Interpreter& interpreter, UGeckoInstruction inst)
// Invalidate the JIT cache here as a heuristic to compensate for
// the lack of precise L1 icache emulation in the JIT. (Portable software
// should use icbi consistently, but games aren't portable.)
- JitInterface::InvalidateICacheLine(address);
+ interpreter.m_system.GetJitInterface().InvalidateICacheLine(address);
return;
}
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
index 2624159d23..7783f58c78 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
@@ -877,8 +877,8 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
const u8* target = GetCodePtr();
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
ABI_PushRegistersAndAdjustStack({}, 0);
- ABI_CallFunctionC(JitInterface::CompileExceptionCheck,
- static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
+ ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
+ static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
ABI_PopRegistersAndAdjustStack({}, 0);
JMP(asm_routines.dispatcher_no_check, true);
SwitchToNearCode();
@@ -1193,8 +1193,8 @@ void Jit64::IntializeSpeculativeConstants()
target = GetCodePtr();
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
ABI_PushRegistersAndAdjustStack({}, 0);
- ABI_CallFunctionC(JitInterface::CompileExceptionCheck,
- static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
+ ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
+ static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
ABI_PopRegistersAndAdjustStack({}, 0);
JMP(asm_routines.dispatcher_no_check, true);
SwitchToNearCode();
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
index 179d88f6ac..ca287c80cc 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -22,6 +22,7 @@
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h"
+#include "Core/System.h"
using namespace Gen;
@@ -362,12 +363,14 @@ void Jit64::dcbx(UGeckoInstruction inst)
{
MOV(32, R(ABI_PARAM1), R(effective_address));
MOV(32, R(ABI_PARAM2), R(loop_counter));
- ABI_CallFunction(JitInterface::InvalidateICacheLines);
+ MOV(64, R(ABI_PARAM3), Imm64(reinterpret_cast<u64>(&m_system.GetJitInterface())));
+ ABI_CallFunction(JitInterface::InvalidateICacheLinesFromJIT);
}
else
{
MOV(32, R(ABI_PARAM1), R(effective_address));
- ABI_CallFunction(JitInterface::InvalidateICacheLine);
+ MOV(64, R(ABI_PARAM3), Imm64(reinterpret_cast<u64>(&m_system.GetJitInterface())));
+ ABI_CallFunction(JitInterface::InvalidateICacheLineFromJIT);
}
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
asm_routines.ResetStack(*this);
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index bd65c377d8..7e0735f85d 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -327,8 +327,9 @@ void JitArm64::IntializeSpeculativeConstants()
fail = GetCodePtr();
MOVI2R(DISPATCHER_PC, js.blockStart);
STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
- MOVP2R(ARM64Reg::X8, &JitInterface::CompileExceptionCheck);
- MOVI2R(ARM64Reg::W0, static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
+ MOVP2R(ARM64Reg::X8, &JitInterface::CompileExceptionCheckFromJIT);
+ MOVP2R(ARM64Reg::X0, &m_system.GetJitInterface());
+ MOVI2R(ARM64Reg::W1, static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
BLR(ARM64Reg::X8);
B(dispatcher_no_check);
SwitchToNearCode();
@@ -866,9 +867,10 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
SetJumpTarget(fail);
MOVI2R(DISPATCHER_PC, js.blockStart);
STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
- MOVI2R(ARM64Reg::W0, static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
- MOVP2R(ARM64Reg::X1, &JitInterface::CompileExceptionCheck);
- BLR(ARM64Reg::X1);
+ MOVP2R(ARM64Reg::X0, &m_system.GetJitInterface());
+ MOVI2R(ARM64Reg::W1, static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
+ MOVP2R(ARM64Reg::X2, &JitInterface::CompileExceptionCheckFromJIT);
+ BLR(ARM64Reg::X2);
B(dispatcher_no_check);
SwitchToNearCode();
SetJumpTarget(no_fail);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp
index ac5f3ac492..d3f920b588 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp
@@ -770,11 +770,12 @@ void JitArm64::dcbx(UGeckoInstruction inst)
ABI_PushRegisters(gprs_to_push);
m_float_emit.ABI_PushRegisters(fprs_to_push, WA);
- // The function call arguments are already in the correct registers
+ // The first two function call arguments are already in the correct registers
+ MOVP2R(ARM64Reg::X2, &m_system.GetJitInterface());
if (make_loop)
- MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLines);
+ MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLinesFromJIT);
else
- MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLine);
+ MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLineFromJIT);
BLR(ARM64Reg::X8);
m_float_emit.ABI_PopRegisters(fprs_to_push, WA);
diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp
index ee7493cac5..beec9559e6 100644
--- a/Source/Core/Core/PowerPC/JitInterface.cpp
+++ b/Source/Core/Core/PowerPC/JitInterface.cpp
@@ -40,19 +40,24 @@
#include "Core/PowerPC/JitArm64/Jit.h"
#endif
-namespace JitInterface
+JitInterface::JitInterface(Core::System& system) : m_system(system)
{
-static JitBase* g_jit = nullptr;
-void SetJit(JitBase* jit)
+}
+
+JitInterface::~JitInterface() = default;
+
+void JitInterface::SetJit(std::unique_ptr<JitBase> jit)
{
- g_jit = jit;
+ m_jit = std::move(jit);
}
-void DoState(PointerWrap& p)
+
+void JitInterface::DoState(PointerWrap& p)
{
- if (g_jit && p.IsReadMode())
- g_jit->ClearCache();
+ if (m_jit && p.IsReadMode())
+ m_jit->ClearCache();
}
-CPUCoreBase* InitJitCore(PowerPC::CPUCore core)
+
+CPUCoreBase* JitInterface::InitJitCore(PowerPC::CPUCore core)
{
auto& system = Core::System::GetInstance();
@@ -60,42 +65,42 @@ CPUCoreBase* InitJitCore(PowerPC::CPUCore core)
{
#if _M_X86
case PowerPC::CPUCore::JIT64:
- g_jit = new Jit64(system);
+ m_jit = std::make_unique<Jit64>(system);
break;
#endif
#if _M_ARM_64
case PowerPC::CPUCore::JITARM64:
- g_jit = new JitArm64(system);
+ m_jit = std::make_unique<JitArm64>(system);
break;
#endif
case PowerPC::CPUCore::CachedInterpreter:
- g_jit = new CachedInterpreter(system);
+ m_jit = std::make_unique<CachedInterpreter>(system);
break;
default:
// Under this case the caller overrides the CPU core to the default and logs that
// it performed the override.
- g_jit = nullptr;
+ m_jit.reset();
return nullptr;
}
- g_jit->Init();
- return g_jit;
+ m_jit->Init();
+ return m_jit.get();
}
-CPUCoreBase* GetCore()
+CPUCoreBase* JitInterface::GetCore() const
{
- return g_jit;
+ return m_jit.get();
}
-void SetProfilingState(ProfilingState state)
+void JitInterface::SetProfilingState(ProfilingState state)
{
- if (!g_jit)
+ if (!m_jit)
return;
- g_jit->jo.profile_blocks = state == ProfilingState::Enabled;
+ m_jit->jo.profile_blocks = state == ProfilingState::Enabled;
}
-void WriteProfileResults(const std::string& filename)
+void JitInterface::WriteProfileResults(const std::string& filename) const
{
Profiler::ProfileStats prof_stats;
GetProfileResults(&prof_stats);
@@ -122,19 +127,19 @@ void WriteProfileResults(const std::string& filename)
}
}
-void GetProfileResults(Profiler::ProfileStats* prof_stats)
+void JitInterface::GetProfileResults(Profiler::ProfileStats* prof_stats) const
{
- // Can't really do this with no g_jit core available
- if (!g_jit)
+ // Can't really do this with no m_jit core available
+ if (!m_jit)
return;
prof_stats->cost_sum = 0;
prof_stats->timecost_sum = 0;
prof_stats->block_stats.clear();
- Core::RunAsCPUThread([&prof_stats] {
+ Core::RunAsCPUThread([this, &prof_stats] {
QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec);
- g_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) {
+ m_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) {
const auto& data = block.profile_data;
u64 cost = data.downcountCounter;
u64 timecost = data.ticCounter;
@@ -150,20 +155,21 @@ void GetProfileResults(Profiler::ProfileStats* prof_stats)
});
}
-std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address)
+std::variant<JitInterface::GetHostCodeError, JitInterface::GetHostCodeResult>
+JitInterface::GetHostCode(u32 address) const
{
- if (!g_jit)
+ if (!m_jit)
{
return GetHostCodeError::NoJitActive;
}
JitBlock* block =
- g_jit->GetBlockCache()->GetBlockFromStartAddress(address, PowerPC::ppcState.msr.Hex);
+ m_jit->GetBlockCache()->GetBlockFromStartAddress(address, PowerPC::ppcState.msr.Hex);
if (!block)
{
for (int i = 0; i < 500; i++)
{
- block = g_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i,
+ block = m_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i,
PowerPC::ppcState.msr.Hex);
if (block)
break;
@@ -190,51 +196,52 @@ std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address)
return result;
}
-bool HandleFault(uintptr_t access_address, SContext* ctx)
+bool JitInterface::HandleFault(uintptr_t access_address, SContext* ctx)
{
// Prevent nullptr dereference on a crash with no JIT present
- if (!g_jit)
+ if (!m_jit)
{
return false;
}
- return g_jit->HandleFault(access_address, ctx);
+ return m_jit->HandleFault(access_address, ctx);
}
-bool HandleStackFault()
+bool JitInterface::HandleStackFault()
{
- if (!g_jit)
+ if (!m_jit)
{
return false;
}
- return g_jit->HandleStackFault();
+ return m_jit->HandleStackFault();
}
-void ClearCache()
+void JitInterface::ClearCache()
{
- if (g_jit)
- g_jit->ClearCache();
+ if (m_jit)
+ m_jit->ClearCache();
}
-void ClearSafe()
+
+void JitInterface::ClearSafe()
{
- if (g_jit)
- g_jit->GetBlockCache()->Clear();
+ if (m_jit)
+ m_jit->GetBlockCache()->Clear();
}
-void InvalidateICache(u32 address, u32 size, bool forced)
+void JitInterface::InvalidateICache(u32 address, u32 size, bool forced)
{
- if (g_jit)
- g_jit->GetBlockCache()->InvalidateICache(address, size, forced);
+ if (m_jit)
+ m_jit->GetBlockCache()->InvalidateICache(address, size, forced);
}
-void InvalidateICacheLine(u32 address)
+void JitInterface::InvalidateICacheLine(u32 address)
{
- if (g_jit)
- g_jit->GetBlockCache()->InvalidateICacheLine(address);
+ if (m_jit)
+ m_jit->GetBlockCache()->InvalidateICacheLine(address);
}
-void InvalidateICacheLines(u32 address, u32 count)
+void JitInterface::InvalidateICacheLines(u32 address, u32 count)
{
// This corresponds to a PPC code loop that:
// - calls some form of dcb* instruction on 'address'
@@ -250,9 +257,19 @@ void InvalidateICacheLines(u32 address, u32 count)
InvalidateICache(address & ~0x1f, 32 * count, false);
}
-void CompileExceptionCheck(ExceptionType type)
+void JitInterface::InvalidateICacheLineFromJIT(u32 address, u32 dummy, JitInterface& jit_interface)
{
- if (!g_jit)
+ jit_interface.InvalidateICacheLine(address);
+}
+
+void JitInterface::InvalidateICacheLinesFromJIT(u32 address, u32 count, JitInterface& jit_interface)
+{
+ jit_interface.InvalidateICacheLines(address, count);
+}
+
+void JitInterface::CompileExceptionCheck(ExceptionType type)
+{
+ if (!m_jit)
return;
std::unordered_set<u32>* exception_addresses = nullptr;
@@ -260,13 +277,13 @@ void CompileExceptionCheck(ExceptionType type)
switch (type)
{
case ExceptionType::FIFOWrite:
- exception_addresses = &g_jit->js.fifoWriteAddresses;
+ exception_addresses = &m_jit->js.fifoWriteAddresses;
break;
case ExceptionType::PairedQuantize:
- exception_addresses = &g_jit->js.pairedQuantizeAddresses;
+ exception_addresses = &m_jit->js.pairedQuantizeAddresses;
break;
case ExceptionType::SpeculativeConstants:
- exception_addresses = &g_jit->js.noSpeculativeConstantsAddresses;
+ exception_addresses = &m_jit->js.noSpeculativeConstantsAddresses;
break;
}
@@ -288,17 +305,20 @@ void CompileExceptionCheck(ExceptionType type)
// Invalidate the JIT block so that it gets recompiled with the external exception check
// included.
- g_jit->GetBlockCache()->InvalidateICache(PowerPC::ppcState.pc, 4, true);
+ m_jit->GetBlockCache()->InvalidateICache(PowerPC::ppcState.pc, 4, true);
}
}
-void Shutdown()
+void JitInterface::CompileExceptionCheckFromJIT(JitInterface& jit_interface, ExceptionType type)
+{
+ jit_interface.CompileExceptionCheck(type);
+}
+
+void JitInterface::Shutdown()
{
- if (g_jit)
+ if (m_jit)
{
- g_jit->Shutdown();
- delete g_jit;
- g_jit = nullptr;
+ m_jit->Shutdown();
+ m_jit.reset();
}
}
-} // namespace JitInterface
diff --git a/Source/Core/Core/PowerPC/JitInterface.h b/Source/Core/Core/PowerPC/JitInterface.h
index 18b60d5296..1ba54cc2c9 100644
--- a/Source/Core/Core/PowerPC/JitInterface.h
+++ b/Source/Core/Core/PowerPC/JitInterface.h
@@ -3,6 +3,7 @@
#pragma once
+#include <memory>
#include <string>
#include <variant>
@@ -13,6 +14,10 @@ class CPUCoreBase;
class PointerWrap;
class JitBase;
+namespace Core
+{
+class System;
+}
namespace PowerPC
{
enum class CPUCore;
@@ -23,65 +28,78 @@ namespace Profiler
struct ProfileStats;
}
-namespace JitInterface
-{
-enum class ExceptionType
-{
- FIFOWrite,
- PairedQuantize,
- SpeculativeConstants
-};
-
-void DoState(PointerWrap& p);
-
-CPUCoreBase* InitJitCore(PowerPC::CPUCore core);
-CPUCoreBase* GetCore();
-
-// Debugging
-enum class ProfilingState
-{
- Enabled,
- Disabled
-};
-
-enum class GetHostCodeError
+class JitInterface
{
- NoJitActive,
- NoTranslation,
+public:
+ explicit JitInterface(Core::System& system);
+ JitInterface(const JitInterface&) = delete;
+ JitInterface(JitInterface&&) = delete;
+ JitInterface& operator=(const JitInterface&) = delete;
+ JitInterface& operator=(JitInterface&&) = delete;
+ ~JitInterface();
+
+ void DoState(PointerWrap& p);
+
+ CPUCoreBase* InitJitCore(PowerPC::CPUCore core);
+ CPUCoreBase* GetCore() const;
+
+ // Debugging
+ enum class ProfilingState
+ {
+ Enabled,
+ Disabled
+ };
+ enum class GetHostCodeError
+ {
+ NoJitActive,
+ NoTranslation,
+ };
+ struct GetHostCodeResult
+ {
+ const u8* code;
+ u32 code_size;
+ u32 entry_address;
+ };
+
+ void SetProfilingState(ProfilingState state);
+ void WriteProfileResults(const std::string& filename) const;
+ void GetProfileResults(Profiler::ProfileStats* prof_stats) const;
+ std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address) const;
+
+ // Memory Utilities
+ bool HandleFault(uintptr_t access_address, SContext* ctx);
+ bool HandleStackFault();
+
+ // Clearing CodeCache
+ void ClearCache();
+
+ // This clear is "safe" in the sense that it's okay to run from
+ // inside a JIT'ed block: it clears the instruction cache, but not
+ // the JIT'ed code.
+ void ClearSafe();
+
+ // If "forced" is true, a recompile is being requested on code that hasn't been modified.
+ void InvalidateICache(u32 address, u32 size, bool forced);
+ void InvalidateICacheLine(u32 address);
+ void InvalidateICacheLines(u32 address, u32 count);
+ static void InvalidateICacheLineFromJIT(u32 address, u32 dummy, JitInterface& jit_interface);
+ static void InvalidateICacheLinesFromJIT(u32 address, u32 count, JitInterface& jit_interface);
+
+ enum class ExceptionType
+ {
+ FIFOWrite,
+ PairedQuantize,
+ SpeculativeConstants
+ };
+ void CompileExceptionCheck(ExceptionType type);
+ static void CompileExceptionCheckFromJIT(JitInterface& jit_interface, ExceptionType type);
+
+ /// used for the page fault unit test, don't use outside of tests!
+ void SetJit(std::unique_ptr<JitBase> jit);
+
+ void Shutdown();
+
+private:
+ std::unique_ptr<JitBase> m_jit;
+ Core::System& m_system;
};
-struct GetHostCodeResult
-{
- const u8* code;
- u32 code_size;
- u32 entry_address;
-};
-
-void SetProfilingState(ProfilingState state);
-void WriteProfileResults(const std::string& filename);
-void GetProfileResults(Profiler::ProfileStats* prof_stats);
-std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address);
-
-// Memory Utilities
-bool HandleFault(uintptr_t access_address, SContext* ctx);
-bool HandleStackFault();
-
-// Clearing CodeCache
-void ClearCache();
-
-// This clear is "safe" in the sense that it's okay to run from
-// inside a JIT'ed block: it clears the instruction cache, but not
-// the JIT'ed code.
-void ClearSafe();
-
-// If "forced" is true, a recompile is being requested on code that hasn't been modified.
-void InvalidateICache(u32 address, u32 size, bool forced);
-void InvalidateICacheLine(u32 address);
-void InvalidateICacheLines(u32 address, u32 count);
-
-void CompileExceptionCheck(ExceptionType type);
-
-/// used for the page fault unit test, don't use outside of tests!
-void SetJit(JitBase* jit);
-
-void Shutdown();
-} // namespace JitInterface
diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp
index 2b3706ae27..6a069b2a76 100644
--- a/Source/Core/Core/PowerPC/MMU.cpp
+++ b/Source/Core/Core/PowerPC/MMU.cpp
@@ -1770,7 +1770,7 @@ void DBATUpdated()
#endif
// IsOptimizable*Address and dcbz depends on the BAT mapping, so we need a flush here.
- JitInterface::ClearSafe();
+ system.GetJitInterface().ClearSafe();
}
void IBATUpdated()
@@ -1789,7 +1789,7 @@ void IBATUpdated()
UpdateFakeMMUBat(ibat_table, 0x40000000);
UpdateFakeMMUBat(ibat_table, 0x70000000);
}
- JitInterface::ClearSafe();
+ system.GetJitInterface().ClearSafe();
}
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp
index 9d4cf00083..7818dcb616 100644
--- a/Source/Core/Core/PowerPC/PPCCache.cpp
+++ b/Source/Core/Core/PowerPC/PPCCache.cpp
@@ -107,7 +107,7 @@ void Cache::Reset()
void InstructionCache::Reset()
{
Cache::Reset();
- JitInterface::ClearSafe();
+ Core::System::GetInstance().GetJitInterface().ClearSafe();
}
void Cache::Init()
@@ -424,7 +424,7 @@ void InstructionCache::Invalidate(u32 addr)
valid[set] = 0;
modified[set] = 0;
- JitInterface::InvalidateICacheLine(addr);
+ Core::System::GetInstance().GetJitInterface().InvalidateICacheLine(addr);
}
void InstructionCache::RefreshConfig()
diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp
index 404813d6d4..b18960f473 100644
--- a/Source/Core/Core/PowerPC/PowerPC.cpp
+++ b/Source/Core/Core/PowerPC/PowerPC.cpp
@@ -153,7 +153,7 @@ void DoState(PointerWrap& p)
// SystemTimers::DecrementerSet();
// SystemTimers::TimeBaseSet();
- JitInterface::DoState(p);
+ Core::System::GetInstance().GetJitInterface().DoState(p);
}
static void ResetRegisters()
@@ -219,7 +219,8 @@ static void InitializeCPUCore(CPUCore cpu_core)
{
// We initialize the interpreter because
// it is used on boot and code window independently.
- auto& interpreter = Core::System::GetInstance().GetInterpreter();
+ auto& system = Core::System::GetInstance();
+ auto& interpreter = system.GetInterpreter();
interpreter.Init();
switch (cpu_core)
@@ -229,12 +230,12 @@ static void InitializeCPUCore(CPUCore cpu_core)
break;
default:
- s_cpu_core_base = JitInterface::InitJitCore(cpu_core);
+ s_cpu_core_base = system.GetJitInterface().InitJitCore(cpu_core);
if (!s_cpu_core_base) // Handle Situations where JIT core isn't available
{
WARN_LOG_FMT(POWERPC, "CPU core {} not available. Falling back to default.",
static_cast<int>(cpu_core));
- s_cpu_core_base = JitInterface::InitJitCore(DefaultCPUCore());
+ s_cpu_core_base = system.GetJitInterface().InitJitCore(DefaultCPUCore());
}
break;
}
@@ -315,8 +316,9 @@ void ScheduleInvalidateCacheThreadSafe(u32 address)
void Shutdown()
{
InjectExternalCPUCore(nullptr);
- JitInterface::Shutdown();
- auto& interpreter = Core::System::GetInstance().GetInterpreter();
+ auto& system = Core::System::GetInstance();
+ system.GetJitInterface().Shutdown();
+ auto& interpreter = system.GetInterpreter();
interpreter.Shutdown();
s_cpu_core_base = nullptr;
}
@@ -328,7 +330,8 @@ CoreMode GetMode()
static void ApplyMode()
{
- auto& interpreter = Core::System::GetInstance().GetInterpreter();
+ auto& system = Core::System::GetInstance();
+ auto& interpreter = system.GetInterpreter();
switch (s_mode)
{
@@ -338,7 +341,7 @@ static void ApplyMode()
case CoreMode::JIT: // Switching from interpreter to JIT.
// Don't really need to do much. It'll work, the cache will refill itself.
- s_cpu_core_base = JitInterface::GetCore();
+ s_cpu_core_base = system.GetJitInterface().GetCore();
if (!s_cpu_core_base) // Has a chance to not get a working JIT core if one isn't active on host
s_cpu_core_base = &interpreter;
break;
diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp
index 0a1a0eb77f..1897131041 100644
--- a/Source/Core/Core/System.cpp
+++ b/Source/Core/Core/System.cpp
@@ -23,6 +23,7 @@
#include "Core/HW/Sram.h"
#include "Core/HW/VideoInterface.h"
#include "Core/PowerPC/Interpreter/Interpreter.h"
+#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/PowerPC.h"
#include "IOS/USB/Emulated/Skylander.h"
#include "VideoCommon/CommandProcessor.h"
@@ -40,7 +41,7 @@ struct System::Impl
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system), m_memory(system),
m_ppc_state(PowerPC::ppcState), m_processor_interface(system), m_serial_interface(system),
- m_video_interface(system), m_interpreter(system, m_ppc_state)
+ m_video_interface(system), m_interpreter(system, m_ppc_state), m_jit_interface(system)
{
}
@@ -72,6 +73,7 @@ struct System::Impl
VertexShaderManager m_vertex_shader_manager;
VideoInterface::VideoInterfaceManager m_video_interface;
Interpreter m_interpreter;
+ JitInterface m_jit_interface;
};
System::System() : m_impl{std::make_unique<Impl>(*this)}
@@ -182,6 +184,11 @@ Interpreter& System::GetInterpreter() const
return m_impl->m_interpreter;
}
+JitInterface& System::GetJitInterface() const
+{
+ return m_impl->m_jit_interface;
+}
+
IOS::HLE::USB::SkylanderPortal& System::GetSkylanderPortal() const
{
return m_impl->m_skylander_portal;
diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h
index e1c7b9a5b8..d25b5ad609 100644
--- a/Source/Core/Core/System.h
+++ b/Source/Core/Core/System.h
@@ -7,6 +7,7 @@
class GeometryShaderManager;
class Interpreter;
+class JitInterface;
class PixelShaderManager;
class SoundStream;
struct Sram;
@@ -133,6 +134,7 @@ public:
GPFifo::GPFifoManager& GetGPFifo() const;
HSP::HSPManager& GetHSP() const;
Interpreter& GetInterpreter() const;
+ JitInterface& GetJitInterface() const;
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
Memory::MemoryManager& GetMemory() const;
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
diff --git a/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp b/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp
index 1be7d8c785..11f2a9a287 100644
--- a/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp
+++ b/Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp
@@ -140,7 +140,8 @@ void CodeDiffDialog::ClearData()
// Swap is used instead of clear for efficiency in the case of huge m_include/m_exclude
std::vector<Diff>().swap(m_include);
std::vector<Diff>().swap(m_exclude);
- JitInterface::SetProfilingState(JitInterface::ProfilingState::Disabled);
+ Core::System::GetInstance().GetJitInterface().SetProfilingState(
+ JitInterface::ProfilingState::Disabled);
}
void CodeDiffDialog::ClearBlockCache()
@@ -150,7 +151,7 @@ void CodeDiffDialog::ClearBlockCache()
if (old_state == Core::State::Running)
Core::SetState(Core::State::Paused);
- JitInterface::ClearCache();
+ Core::System::GetInstance().GetJitInterface().ClearCache();
if (old_state == Core::State::Running)
Core::SetState(Core::State::Running);
@@ -205,7 +206,7 @@ void CodeDiffDialog::OnRecord(bool enabled)
}
m_record_btn->update();
- JitInterface::SetProfilingState(state);
+ Core::System::GetInstance().GetJitInterface().SetProfilingState(state);
}
void CodeDiffDialog::OnInclude()
@@ -271,7 +272,7 @@ std::vector<Diff> CodeDiffDialog::CalculateSymbolsFromProfile()
{
Profiler::ProfileStats prof_stats;
auto& blockstats = prof_stats.block_stats;
- JitInterface::GetProfileResults(&prof_stats);
+ Core::System::GetInstance().GetJitInterface().GetProfileResults(&prof_stats);
std::vector<Diff> current;
current.reserve(20000);
@@ -391,7 +392,7 @@ void CodeDiffDialog::Update(bool include)
m_exclude_size_label->setText(tr("Excluded: %1").arg(m_exclude.size()));
m_include_size_label->setText(tr("Included: %1").arg(m_include.size()));
- JitInterface::ClearCache();
+ Core::System::GetInstance().GetJitInterface().ClearCache();
if (old_state == Core::State::Running)
Core::SetState(Core::State::Running);
}
diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp
index 1a15d9c100..ea991d1e6f 100644
--- a/Source/Core/DolphinQt/MenuBar.cpp
+++ b/Source/Core/DolphinQt/MenuBar.cpp
@@ -1671,7 +1671,7 @@ void MenuBar::PatchHLEFunctions()
void MenuBar::ClearCache()
{
- Core::RunAsCPUThread(JitInterface::ClearCache);
+ Core::RunAsCPUThread([] { Core::System::GetInstance().GetJitInterface().ClearCache(); });
}
void MenuBar::LogInstructions()
diff --git a/Source/Core/UICommon/Disassembler.cpp b/Source/Core/UICommon/Disassembler.cpp
index 62e4d32c6d..840af8ec1f 100644
--- a/Source/Core/UICommon/Disassembler.cpp
+++ b/Source/Core/UICommon/Disassembler.cpp
@@ -16,6 +16,7 @@
#include "Common/Assert.h"
#include "Common/VariantUtil.h"
#include "Core/PowerPC/JitInterface.h"
+#include "Core/System.h"
#if defined(HAVE_LLVM)
class HostDisassemblerLLVM : public HostDisassembler
@@ -170,7 +171,7 @@ std::unique_ptr<HostDisassembler> GetNewDisassembler(const std::string& arch)
DisassembleResult DisassembleBlock(HostDisassembler* disasm, u32 address)
{
- auto res = JitInterface::GetHostCode(address);
+ auto res = Core::System::GetInstance().GetJitInterface().GetHostCode(address);
return std::visit(overloaded{[&](JitInterface::GetHostCodeError error) {
DisassembleResult result;