IR: Disable unworkable overwriting of instructions on invalidation. Add debug-mode sanity check.

This commit is contained in:
Henrik Rydgård 2024-07-22 12:02:50 +02:00
parent a27935d5ac
commit eda60a5df9
2 changed files with 26 additions and 2 deletions

View file

@ -110,6 +110,8 @@ void IRJit::InvalidateCacheAt(u32 em_address, int length) {
} }
void IRJit::Compile(u32 em_address) { void IRJit::Compile(u32 em_address) {
_dbg_assert_(compilerEnabled_);
PROFILE_THIS_SCOPE("jitc"); PROFILE_THIS_SCOPE("jitc");
if (g_Config.bPreloadFunctions) { if (g_Config.bPreloadFunctions) {
@ -146,6 +148,8 @@ void IRJit::Compile(u32 em_address) {
// WARNING! This can be called from IRInterpret / the JIT, through the function preload stuff! // WARNING! This can be called from IRInterpret / the JIT, through the function preload stuff!
bool IRJit::CompileBlock(u32 em_address, std::vector<IRInst> &instructions, u32 &mipsBytes, bool preload) { bool IRJit::CompileBlock(u32 em_address, std::vector<IRInst> &instructions, u32 &mipsBytes, bool preload) {
_dbg_assert_(compilerEnabled_);
frontend_.DoJit(em_address, instructions, mipsBytes, preload); frontend_.DoJit(em_address, instructions, mipsBytes, preload);
if (instructions.empty()) { if (instructions.empty()) {
_dbg_assert_(preload); _dbg_assert_(preload);
@ -176,6 +180,8 @@ bool IRJit::CompileBlock(u32 em_address, std::vector<IRInst> &instructions, u32
} }
void IRJit::CompileFunction(u32 start_address, u32 length) { void IRJit::CompileFunction(u32 start_address, u32 length) {
_dbg_assert_(compilerEnabled_);
PROFILE_THIS_SCOPE("jitc"); PROFILE_THIS_SCOPE("jitc");
// Note: we don't actually write emuhacks yet, so we can validate hashes. // Note: we don't actually write emuhacks yet, so we can validate hashes.
@ -264,7 +270,9 @@ void IRJit::RunLoopUntil(u64 globalticks) {
} }
MIPSState *mips = mips_; MIPSState *mips = mips_;
#ifdef _DEBUG
compilerEnabled_ = false;
#endif
while (mips->downcount >= 0) { while (mips->downcount >= 0) {
u32 inst = Memory::ReadUnchecked_U32(mips->pc); u32 inst = Memory::ReadUnchecked_U32(mips->pc);
u32 opcode = inst & 0xFF000000; u32 opcode = inst & 0xFF000000;
@ -294,10 +302,19 @@ void IRJit::RunLoopUntil(u64 globalticks) {
} }
} else { } else {
// RestoreRoundingMode(true); // RestoreRoundingMode(true);
#ifdef _DEBUG
compilerEnabled_ = true;
#endif
Compile(mips->pc); Compile(mips->pc);
#ifdef _DEBUG
compilerEnabled_ = false;
#endif
// ApplyRoundingMode(true); // ApplyRoundingMode(true);
} }
} }
#ifdef _DEBUG
compilerEnabled_ = true;
#endif
} }
// RestoreRoundingMode(true); // RestoreRoundingMode(true);
@ -437,14 +454,19 @@ void IRBlockCache::RemoveBlock(int blockIndex) {
auto iter = std::find(byPage_[page].begin(), byPage_[page].end(), blockIndex); auto iter = std::find(byPage_[page].begin(), byPage_[page].end(), blockIndex);
if (iter != byPage_[page].end()) { if (iter != byPage_[page].end()) {
byPage_[page].erase(iter); byPage_[page].erase(iter);
} else {
WARN_LOG(Log::JIT, "RemoveBlock: Block at %08x was not found where expected in byPage table.", startAddr);
} }
} }
// Additionally, we zap the block in the IR arena. // Additionally, we'd like to zap the block in the IR arena.
// However, this breaks if calling sceKernelIcacheClearAll(), since as soon as we return, we'll be executing garbage.
/*
IRInst bad{ IROp::Bad }; IRInst bad{ IROp::Bad };
for (int off = block.GetIRArenaOffset(); off < (int)(block.GetIRArenaOffset() + block.GetNumIRInstructions()); off++) { for (int off = block.GetIRArenaOffset(); off < (int)(block.GetIRArenaOffset() + block.GetNumIRInstructions()); off++) {
arena_[off] = bad; arena_[off] = bad;
} }
*/
} }
u32 IRBlockCache::AddressToPage(u32 addr) const { u32 IRBlockCache::AddressToPage(u32 addr) const {

View file

@ -248,6 +248,8 @@ protected:
MIPSState *mips_; MIPSState *mips_;
bool compilerEnabled_ = true;
// where to write branch-likely trampolines. not used atm // where to write branch-likely trampolines. not used atm
// u32 blTrampolines_; // u32 blTrampolines_;
// int blTrampolineCount_; // int blTrampolineCount_;