Make memory breakpoint faster
Currently, slowmem is used at any time that memory breakpoints are in use. This commit makes it so that whenever the DBAT gets updated, if the address is overllaping any memchecks, it forces the use of slowmem. This allows to keep fastmem for any other cases and noticably increases performance when using memory breakpoints.
This commit is contained in:
parent
52fe05af6b
commit
9ad6c8f334
|
@ -173,8 +173,8 @@ void MemChecks::Add(const TMemCheck& memory_check)
|
||||||
if (GetMemCheck(memory_check.start_address) == nullptr)
|
if (GetMemCheck(memory_check.start_address) == nullptr)
|
||||||
{
|
{
|
||||||
bool had_any = HasAny();
|
bool had_any = HasAny();
|
||||||
m_mem_checks.push_back(memory_check);
|
|
||||||
bool lock = Core::PauseAndLock(true);
|
bool lock = Core::PauseAndLock(true);
|
||||||
|
m_mem_checks.push_back(memory_check);
|
||||||
// If this is the first one, clear the JIT cache so it can switch to
|
// If this is the first one, clear the JIT cache so it can switch to
|
||||||
// watchpoint-compatible code.
|
// watchpoint-compatible code.
|
||||||
if (!had_any && g_jit)
|
if (!had_any && g_jit)
|
||||||
|
@ -190,8 +190,8 @@ void MemChecks::Remove(u32 address)
|
||||||
{
|
{
|
||||||
if (i->start_address == address)
|
if (i->start_address == address)
|
||||||
{
|
{
|
||||||
m_mem_checks.erase(i);
|
|
||||||
bool lock = Core::PauseAndLock(true);
|
bool lock = Core::PauseAndLock(true);
|
||||||
|
m_mem_checks.erase(i);
|
||||||
if (!HasAny() && g_jit)
|
if (!HasAny() && g_jit)
|
||||||
g_jit->ClearCache();
|
g_jit->ClearCache();
|
||||||
PowerPC::DBATUpdated();
|
PowerPC::DBATUpdated();
|
||||||
|
@ -220,6 +220,25 @@ TMemCheck* MemChecks::GetMemCheck(u32 address)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MemChecks::OverlapsMemcheck(u32 address, u32 length)
|
||||||
|
{
|
||||||
|
if (!HasAny())
|
||||||
|
return false;
|
||||||
|
u32 page_end_suffix = length - 1;
|
||||||
|
u32 page_end_address = address | page_end_suffix;
|
||||||
|
for (TMemCheck memcheck : m_mem_checks)
|
||||||
|
{
|
||||||
|
if (((memcheck.start_address | page_end_suffix) == page_end_address ||
|
||||||
|
(memcheck.end_address | page_end_suffix) == page_end_address) ||
|
||||||
|
((memcheck.start_address | page_end_suffix) < page_end_address &&
|
||||||
|
(memcheck.end_address | page_end_suffix) > page_end_address))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool TMemCheck::Action(DebugInterface* debug_interface, u32 value, u32 addr, bool write, int size,
|
bool TMemCheck::Action(DebugInterface* debug_interface, u32 value, u32 addr, bool write, int size,
|
||||||
u32 pc)
|
u32 pc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
|
|
||||||
// memory breakpoint
|
// memory breakpoint
|
||||||
TMemCheck* GetMemCheck(u32 address);
|
TMemCheck* GetMemCheck(u32 address);
|
||||||
|
bool OverlapsMemcheck(u32 address, u32 length);
|
||||||
void Remove(u32 address);
|
void Remove(u32 address);
|
||||||
|
|
||||||
void Clear() { m_mem_checks.clear(); }
|
void Clear() { m_mem_checks.clear(); }
|
||||||
|
|
|
@ -46,6 +46,6 @@ bool JitBase::MergeAllowedNextInstructions(int count)
|
||||||
void JitBase::UpdateMemoryOptions()
|
void JitBase::UpdateMemoryOptions()
|
||||||
{
|
{
|
||||||
bool any_watchpoints = PowerPC::memchecks.HasAny();
|
bool any_watchpoints = PowerPC::memchecks.HasAny();
|
||||||
jo.fastmem = SConfig::GetInstance().bFastmem;
|
jo.fastmem = SConfig::GetInstance().bFastmem && (UReg_MSR(MSR).DR || !any_watchpoints);
|
||||||
jo.memcheck = SConfig::GetInstance().bMMU || any_watchpoints;
|
jo.memcheck = SConfig::GetInstance().bMMU || any_watchpoints;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1132,24 +1132,6 @@ static TranslateAddressResult TranslatePageAddress(const u32 address, const XChe
|
||||||
return TranslateAddressResult{TranslateAddressResult::PAGE_FAULT, 0};
|
return TranslateAddressResult{TranslateAddressResult::PAGE_FAULT, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool overlaps_memcheck(u32 pageEndAddress)
|
|
||||||
{
|
|
||||||
if (!memchecks.HasAny())
|
|
||||||
return false;
|
|
||||||
u32 page_end_suffix = ((1 << BAT_INDEX_SHIFT)) - 1;
|
|
||||||
for (TMemCheck memcheck : memchecks.GetMemChecks())
|
|
||||||
{
|
|
||||||
if (((memcheck.start_address | page_end_suffix) == pageEndAddress ||
|
|
||||||
(memcheck.end_address | page_end_suffix) == pageEndAddress) ||
|
|
||||||
((memcheck.start_address | page_end_suffix) < pageEndAddress &&
|
|
||||||
(memcheck.end_address | page_end_suffix) > pageEndAddress))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateBATs(BatTable& bat_table, u32 base_spr)
|
static void UpdateBATs(BatTable& bat_table, u32 base_spr)
|
||||||
{
|
{
|
||||||
// TODO: Separate BATs for MSR.PR==0 and MSR.PR==1
|
// TODO: Separate BATs for MSR.PR==0 and MSR.PR==1
|
||||||
|
@ -1209,7 +1191,9 @@ static void UpdateBATs(BatTable& bat_table, u32 base_spr)
|
||||||
valid_bit = 0x3;
|
valid_bit = 0x3;
|
||||||
else if ((address >> 28) == 0xE && (address < (0xE0000000 + Memory::L1_CACHE_SIZE)))
|
else if ((address >> 28) == 0xE && (address < (0xE0000000 + Memory::L1_CACHE_SIZE)))
|
||||||
valid_bit = 0x3;
|
valid_bit = 0x3;
|
||||||
if (overlaps_memcheck(((batu.BEPI | j) << BAT_INDEX_SHIFT) | ((1 << BAT_INDEX_SHIFT) - 1)))
|
// Fastmem doesn't support memchecks, so disable it for all overlapping virtual pages.
|
||||||
|
if (PowerPC::memchecks.OverlapsMemcheck(((batu.BEPI | j) << BAT_INDEX_SHIFT),
|
||||||
|
1 << BAT_INDEX_SHIFT))
|
||||||
valid_bit &= ~0x2;
|
valid_bit &= ~0x2;
|
||||||
|
|
||||||
// (BEPI | j) == (BEPI & ~BL) | (j & BL).
|
// (BEPI | j) == (BEPI & ~BL) | (j & BL).
|
||||||
|
|
Loading…
Reference in New Issue