Merge pull request #4961 from aldelaro5/fast-memchecks
Make memory breakpoint faster
This commit is contained in:
commit
521a777ade
|
@ -11,8 +11,10 @@
|
|||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/DebugInterface.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
#include "Core/PowerPC/JitCommon/JitCache.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
bool BreakPoints::IsAddressBreakPoint(u32 address) const
|
||||
{
|
||||
|
@ -168,13 +170,18 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
|||
|
||||
void MemChecks::Add(const TMemCheck& memory_check)
|
||||
{
|
||||
bool had_any = HasAny();
|
||||
if (GetMemCheck(memory_check.start_address) == nullptr)
|
||||
{
|
||||
bool had_any = HasAny();
|
||||
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
|
||||
// watchpoint-compatible code.
|
||||
if (!had_any && g_jit)
|
||||
g_jit->GetBlockCache()->SchedulateClearCacheThreadSafe();
|
||||
// If this is the first one, clear the JIT cache so it can switch to
|
||||
// watchpoint-compatible code.
|
||||
if (!had_any && g_jit)
|
||||
g_jit->ClearCache();
|
||||
PowerPC::DBATUpdated();
|
||||
Core::PauseAndLock(false, lock);
|
||||
}
|
||||
}
|
||||
|
||||
void MemChecks::Remove(u32 address)
|
||||
|
@ -183,9 +190,12 @@ void MemChecks::Remove(u32 address)
|
|||
{
|
||||
if (i->start_address == address)
|
||||
{
|
||||
bool lock = Core::PauseAndLock(true);
|
||||
m_mem_checks.erase(i);
|
||||
if (!HasAny() && g_jit)
|
||||
g_jit->GetBlockCache()->SchedulateClearCacheThreadSafe();
|
||||
g_jit->ClearCache();
|
||||
PowerPC::DBATUpdated();
|
||||
Core::PauseAndLock(false, lock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +220,25 @@ TMemCheck* MemChecks::GetMemCheck(u32 address)
|
|||
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,
|
||||
u32 pc)
|
||||
{
|
||||
|
|
|
@ -87,6 +87,7 @@ public:
|
|||
|
||||
// memory breakpoint
|
||||
TMemCheck* GetMemCheck(u32 address);
|
||||
bool OverlapsMemcheck(u32 address, u32 length);
|
||||
void Remove(u32 address);
|
||||
|
||||
void Clear() { m_mem_checks.clear(); }
|
||||
|
|
|
@ -335,7 +335,7 @@ void EmuCodeBlock::MMIOLoadToReg(MMIO::Mapping* mmio, Gen::X64Reg reg_value,
|
|||
void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress, int accessSize,
|
||||
s32 offset, BitSet32 registersInUse, bool signExtend, int flags)
|
||||
{
|
||||
bool slowmem = (flags & SAFE_LOADSTORE_FORCE_SLOWMEM) != 0 || g_jit->jo.alwaysUseMemFuncs;
|
||||
bool slowmem = (flags & SAFE_LOADSTORE_FORCE_SLOWMEM) != 0;
|
||||
|
||||
registersInUse[reg_value] = false;
|
||||
if (g_jit->jo.fastmem && !(flags & SAFE_LOADSTORE_NO_FASTMEM) && !slowmem)
|
||||
|
@ -492,7 +492,7 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
|
|||
BitSet32 registersInUse, int flags)
|
||||
{
|
||||
bool swap = !(flags & SAFE_LOADSTORE_NO_SWAP);
|
||||
bool slowmem = (flags & SAFE_LOADSTORE_FORCE_SLOWMEM) != 0 || g_jit->jo.alwaysUseMemFuncs;
|
||||
bool slowmem = (flags & SAFE_LOADSTORE_FORCE_SLOWMEM) != 0;
|
||||
|
||||
// set the correct immediate format
|
||||
reg_value = FixImmediate(accessSize, reg_value);
|
||||
|
|
|
@ -46,7 +46,6 @@ bool JitBase::MergeAllowedNextInstructions(int count)
|
|||
void JitBase::UpdateMemoryOptions()
|
||||
{
|
||||
bool any_watchpoints = PowerPC::memchecks.HasAny();
|
||||
jo.fastmem = SConfig::GetInstance().bFastmem && !any_watchpoints;
|
||||
jo.fastmem = SConfig::GetInstance().bFastmem && (UReg_MSR(MSR).DR || !any_watchpoints);
|
||||
jo.memcheck = SConfig::GetInstance().bMMU || any_watchpoints;
|
||||
jo.alwaysUseMemFuncs = any_watchpoints;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ protected:
|
|||
bool accurateSinglePrecision;
|
||||
bool fastmem;
|
||||
bool memcheck;
|
||||
bool alwaysUseMemFuncs;
|
||||
};
|
||||
struct JitState
|
||||
{
|
||||
|
|
|
@ -29,13 +29,6 @@
|
|||
|
||||
using namespace Gen;
|
||||
|
||||
static CoreTiming::EventType* s_clear_jit_cache_thread_safe;
|
||||
|
||||
static void ClearCacheThreadSafe(u64 userdata, s64 cyclesdata)
|
||||
{
|
||||
JitInterface::ClearCache();
|
||||
}
|
||||
|
||||
bool JitBlock::OverlapsPhysicalRange(u32 address, u32 length) const
|
||||
{
|
||||
return physical_addresses.lower_bound(address) !=
|
||||
|
@ -50,7 +43,6 @@ JitBaseBlockCache::~JitBaseBlockCache() = default;
|
|||
|
||||
void JitBaseBlockCache::Init()
|
||||
{
|
||||
s_clear_jit_cache_thread_safe = CoreTiming::RegisterEvent("clearJitCache", ClearCacheThreadSafe);
|
||||
JitRegister::Init(SConfig::GetInstance().m_perfDir);
|
||||
|
||||
Clear();
|
||||
|
@ -89,11 +81,6 @@ void JitBaseBlockCache::Reset()
|
|||
Init();
|
||||
}
|
||||
|
||||
void JitBaseBlockCache::SchedulateClearCacheThreadSafe()
|
||||
{
|
||||
CoreTiming::ScheduleEvent(0, s_clear_jit_cache_thread_safe, 0, CoreTiming::FromThread::NON_CPU);
|
||||
}
|
||||
|
||||
JitBlock** JitBaseBlockCache::GetFastBlockMap()
|
||||
{
|
||||
return fast_block_map.data();
|
||||
|
|
|
@ -125,7 +125,6 @@ public:
|
|||
void Shutdown();
|
||||
void Clear();
|
||||
void Reset();
|
||||
void SchedulateClearCacheThreadSafe();
|
||||
|
||||
// Code Cache
|
||||
JitBlock** GetFastBlockMap();
|
||||
|
|
|
@ -1191,6 +1191,10 @@ static void UpdateBATs(BatTable& bat_table, u32 base_spr)
|
|||
valid_bit = 0x3;
|
||||
else if ((address >> 28) == 0xE && (address < (0xE0000000 + Memory::L1_CACHE_SIZE)))
|
||||
valid_bit = 0x3;
|
||||
// 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;
|
||||
|
||||
// (BEPI | j) == (BEPI & ~BL) | (j & BL).
|
||||
bat_table[batu.BEPI | j] = address | valid_bit;
|
||||
|
|
Loading…
Reference in New Issue