mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-10 14:39:01 +01:00
Sped up the Dolphin debugger in JIT mode by splitting a block only while stepping or when it contains a breakpoint. The block is invalidated when a breakpoint is set or cleared.
Fixed a bug in the JitCache where the JIT icache was not being invalidated when a block containing the instruction was destroyed.
This commit is contained in:
parent
dc79d68e72
commit
8ed6ea3b07
@ -19,6 +19,7 @@
|
||||
#include "DebugInterface.h"
|
||||
#include "BreakPoints.h"
|
||||
#include <sstream>
|
||||
#include "..\..\Core\Src\PowerPC\JitCommon\JitBase.h"
|
||||
|
||||
bool BreakPoints::IsAddressBreakPoint(u32 _iAddress)
|
||||
{
|
||||
@ -70,7 +71,11 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bps)
|
||||
void BreakPoints::Add(const TBreakPoint& bp)
|
||||
{
|
||||
if (!IsAddressBreakPoint(bp.iAddress))
|
||||
{
|
||||
m_BreakPoints.push_back(bp);
|
||||
if (jit)
|
||||
jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void BreakPoints::Add(u32 em_address, bool temp)
|
||||
@ -83,21 +88,35 @@ void BreakPoints::Add(u32 em_address, bool temp)
|
||||
pt.iAddress = em_address;
|
||||
|
||||
m_BreakPoints.push_back(pt);
|
||||
|
||||
if (jit)
|
||||
jit->GetBlockCache()->InvalidateICache(em_address, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void BreakPoints::Remove(u32 _iAddress)
|
||||
void BreakPoints::Remove(u32 em_address)
|
||||
{
|
||||
for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
|
||||
{
|
||||
if (i->iAddress == _iAddress)
|
||||
if (i->iAddress == em_address)
|
||||
{
|
||||
m_BreakPoints.erase(i);
|
||||
if (jit)
|
||||
jit->GetBlockCache()->InvalidateICache(em_address, 4);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BreakPoints::Clear()
|
||||
{
|
||||
for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i)
|
||||
{
|
||||
if (jit)
|
||||
jit->GetBlockCache()->InvalidateICache(i->iAddress, 4);
|
||||
m_BreakPoints.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
MemChecks::TMemChecksStr MemChecks::GetStrings() const
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
|
||||
// Remove Breakpoint
|
||||
void Remove(u32 _iAddress);
|
||||
void Clear() { m_BreakPoints.clear(); };
|
||||
void Clear();
|
||||
|
||||
void DeleteByAddress(u32 _Address);
|
||||
|
||||
|
@ -415,9 +415,8 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
{
|
||||
// Comment out the following to disable breakpoints (speed-up)
|
||||
blockSize = 1;
|
||||
broken_block = true;
|
||||
if (GetState() == CPU_STEPPING)
|
||||
blockSize = 1;
|
||||
Trace();
|
||||
}
|
||||
|
||||
@ -597,6 +596,20 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
SetJumpTarget(clearInt);
|
||||
}
|
||||
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging && breakpoints.IsAddressBreakPoint(ops[i].address) && GetState() != CPU_STEPPING)
|
||||
{
|
||||
MOV(32, M(&PC), Imm32(ops[i].address));
|
||||
ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints));
|
||||
TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||
|
||||
FixupBranch noBreakpoint = J_CC(CC_Z);
|
||||
gpr.Flush(FLUSH_ALL);
|
||||
fpr.Flush(FLUSH_ALL);
|
||||
|
||||
WriteExit(ops[i].address, 0);
|
||||
SetJumpTarget(noBreakpoint);
|
||||
}
|
||||
|
||||
Jit64Tables::CompileInstruction(ops[i]);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
|
@ -1269,7 +1269,8 @@ static const unsigned alwaysUsedList[] = {
|
||||
Store16, Store32, StoreSingle, StoreDouble, StorePaired, StoreFReg, FDCmpCR,
|
||||
BlockStart, BlockEnd, IdleBranch, BranchCond, BranchUncond, ShortIdleLoop,
|
||||
SystemCall, InterpreterBranch, RFIExit, FPExceptionCheckStart,
|
||||
FPExceptionCheckEnd, ISIException, ExtExceptionCheck, Int3, Tramp, Nop
|
||||
FPExceptionCheckEnd, ISIException, ExtExceptionCheck, BreakPointCheck,
|
||||
Int3, Tramp, Nop
|
||||
};
|
||||
static const unsigned extra8RegList[] = {
|
||||
LoadGReg, LoadCR, LoadGQR, LoadFReg, LoadFRegDENToZero,
|
||||
|
@ -168,7 +168,7 @@ enum Opcode {
|
||||
// used for exception checking, at least until someone
|
||||
// has a better idea of integrating it
|
||||
FPExceptionCheckStart, FPExceptionCheckEnd,
|
||||
ISIException,ExtExceptionCheck,
|
||||
ISIException, ExtExceptionCheck, BreakPointCheck,
|
||||
// "Opcode" representing a register too far away to
|
||||
// reference directly; this is a size optimization
|
||||
Tramp,
|
||||
@ -414,6 +414,9 @@ public:
|
||||
InstLoc EmitExtExceptionCheck(InstLoc pc) {
|
||||
return EmitUOp(ExtExceptionCheck, pc);
|
||||
}
|
||||
InstLoc EmitBreakPointCheck(InstLoc pc) {
|
||||
return EmitUOp(BreakPointCheck, pc);
|
||||
}
|
||||
InstLoc EmitRFIExit() {
|
||||
return FoldZeroOp(RFIExit, 0);
|
||||
}
|
||||
|
@ -763,6 +763,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
||||
case FPExceptionCheckEnd:
|
||||
case ISIException:
|
||||
case ExtExceptionCheck:
|
||||
case BreakPointCheck:
|
||||
case Int3:
|
||||
case Tramp:
|
||||
// No liveness effects
|
||||
@ -1943,6 +1944,17 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
||||
Jit->SetJumpTarget(clearInt);
|
||||
break;
|
||||
}
|
||||
case BreakPointCheck: {
|
||||
unsigned InstLoc = ibuild->GetImmValue(getOp1(I));
|
||||
|
||||
Jit->MOV(32, M(&PC), Imm32(InstLoc));
|
||||
Jit->ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckBreakPoints));
|
||||
Jit->TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||
FixupBranch noBreakpoint = Jit->J_CC(CC_Z);
|
||||
Jit->WriteExit(InstLoc, 0);
|
||||
Jit->SetJumpTarget(noBreakpoint);
|
||||
break;
|
||||
}
|
||||
case Int3: {
|
||||
Jit->INT3();
|
||||
break;
|
||||
|
@ -523,8 +523,8 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
{
|
||||
// Comment out the following to disable breakpoints (speed-up)
|
||||
blockSize = 1;
|
||||
if (GetState() == CPU_STEPPING)
|
||||
blockSize = 1;
|
||||
Trace();
|
||||
}
|
||||
|
||||
@ -654,6 +654,11 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
ibuild.EmitExtExceptionCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
|
||||
if (Core::g_CoreStartupParameter.bEnableDebugging && breakpoints.IsAddressBreakPoint(ops[i].address) && GetState() != CPU_STEPPING)
|
||||
{
|
||||
ibuild.EmitBreakPointCheck(ibuild.EmitIntConst(ops[i].address));
|
||||
}
|
||||
|
||||
JitILTables::CompileInstruction(ops[i]);
|
||||
|
||||
if (js.memcheck && (opinfo->flags & FL_LOADSTORE))
|
||||
|
@ -417,6 +417,24 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||
std::map<pair<u32,u32>, u32>::iterator it1 = block_map.lower_bound(std::make_pair(address, 0)), it2 = it1, it;
|
||||
while (it2 != block_map.end() && it2->first.second < address + length)
|
||||
{
|
||||
#ifdef JIT_UNLIMITED_ICACHE
|
||||
JitBlock &b = blocks[it2->second];
|
||||
if (b.originalAddress & JIT_ICACHE_VMEM_BIT)
|
||||
{
|
||||
u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK;
|
||||
memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, length);
|
||||
}
|
||||
else if (b.originalAddress & JIT_ICACHE_EXRAM_BIT)
|
||||
{
|
||||
u32 cacheaddr = b.originalAddress & JIT_ICACHEEX_MASK;
|
||||
memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK;
|
||||
memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, length);
|
||||
}
|
||||
#endif
|
||||
DestroyBlock(it2->second, true);
|
||||
it2++;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user