mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-17 23:47:40 +00:00
x86jit: Disable replacements w/ breakpoints inside.
This does alter graphics (memcpys won't fire anymore), but it also means breakpoints work which is nice.
This commit is contained in:
parent
ab8e2d56ec
commit
9cb1151b67
@ -150,6 +150,18 @@ bool CBreakPoints::IsTempBreakPoint(u32 addr)
|
||||
return bp != INVALID_BREAKPOINT;
|
||||
}
|
||||
|
||||
bool CBreakPoints::RangeContainsBreakPoint(u32 addr, u32 size)
|
||||
{
|
||||
const u32 end = addr + size;
|
||||
for (const auto &bp : breakPoints_)
|
||||
{
|
||||
if (bp.addr >= addr && bp.addr < end)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBreakPoints::AddBreakPoint(u32 addr, bool temp)
|
||||
{
|
||||
size_t bp = FindBreakpoint(addr, true, temp);
|
||||
|
@ -115,6 +115,7 @@ public:
|
||||
static bool IsAddressBreakPoint(u32 addr);
|
||||
static bool IsAddressBreakPoint(u32 addr, bool* enabled);
|
||||
static bool IsTempBreakPoint(u32 addr);
|
||||
static bool RangeContainsBreakPoint(u32 addr, u32 size);
|
||||
static void AddBreakPoint(u32 addr, bool temp = false);
|
||||
static void RemoveBreakPoint(u32 addr);
|
||||
static void ChangeBreakPoint(u32 addr, bool enable);
|
||||
|
@ -535,6 +535,19 @@ bool Jit::ReplaceJalTo(u32 dest) {
|
||||
if (!MIPS_IS_REPLACEMENT(op.encoding))
|
||||
return false;
|
||||
|
||||
// Make sure we don't replace if there are any breakpoints inside.
|
||||
u32 funcSize = symbolMap.GetFunctionSize(dest);
|
||||
if (funcSize == SymbolMap::INVALID_ADDRESS) {
|
||||
if (CBreakPoints::IsAddressBreakPoint(dest)) {
|
||||
return false;
|
||||
}
|
||||
funcSize = (u32)sizeof(u32);
|
||||
} else {
|
||||
if (CBreakPoints::RangeContainsBreakPoint(dest, funcSize)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int index = op.encoding & MIPS_EMUHACK_VALUE_MASK;
|
||||
const ReplacementTableEntry *entry = GetReplacementFunc(index);
|
||||
if (!entry) {
|
||||
@ -572,7 +585,7 @@ bool Jit::ReplaceJalTo(u32 dest) {
|
||||
// No writing exits, keep going!
|
||||
|
||||
// Add a trigger so that if the inlined code changes, we invalidate this block.
|
||||
blocks.ProxyBlock(js.blockStart, dest, symbolMap.GetFunctionSize(dest) / sizeof(u32), GetCodePtr());
|
||||
blocks.ProxyBlock(js.blockStart, dest, funcSize / sizeof(u32), GetCodePtr());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -591,7 +604,18 @@ void Jit::Comp_ReplacementFunc(MIPSOpcode op)
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry->flags & REPFLAG_DISABLED) {
|
||||
u32 funcSize = symbolMap.GetFunctionSize(js.compilerPC);
|
||||
bool disabled = (entry->flags & REPFLAG_DISABLED) != 0;
|
||||
if (!disabled && funcSize != SymbolMap::INVALID_ADDRESS && funcSize > sizeof(u32)) {
|
||||
// We don't need to disable hooks, the code will still run.
|
||||
if ((entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) == 0) {
|
||||
// Any breakpoint at the func entry was already tripped, so we can still run the replacement.
|
||||
// That's a common case - just to see how often the replacement hits.
|
||||
disabled = CBreakPoints::RangeContainsBreakPoint(js.compilerPC + sizeof(u32), funcSize - sizeof(u32));
|
||||
}
|
||||
}
|
||||
|
||||
if (disabled) {
|
||||
MIPSCompileOp(Memory::Read_Instruction(js.compilerPC, true));
|
||||
} else if (entry->jitReplaceFunc) {
|
||||
MIPSReplaceFunc repl = entry->jitReplaceFunc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user