mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-31 10:01:26 +02:00
Breakpoints: Fix lag when adding or removing multiple memory breakpoints by only calling DBATUpdated() once.
This commit is contained in:
parent
696b363f47
commit
05bf321a0c
@ -255,6 +255,8 @@ MemChecks::TMemChecksStr MemChecks::GetStrings() const
|
||||
|
||||
void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
{
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
for (const std::string& mc_string : mc_strings)
|
||||
{
|
||||
TMemCheck mc;
|
||||
@ -281,15 +283,16 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
||||
mc.condition = Expression::TryParse(condition);
|
||||
}
|
||||
|
||||
Add(std::move(mc));
|
||||
Add(std::move(mc), false);
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
void MemChecks::Add(TMemCheck memory_check)
|
||||
void MemChecks::Add(TMemCheck memory_check, bool update)
|
||||
{
|
||||
bool had_any = HasAny();
|
||||
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
// Check for existing breakpoint, and overwrite with new info.
|
||||
// This is assuming we usually want the new breakpoint over an old one.
|
||||
const u32 address = memory_check.start_address;
|
||||
@ -306,11 +309,9 @@ void MemChecks::Add(TMemCheck memory_check)
|
||||
{
|
||||
m_mem_checks.emplace_back(std::move(memory_check));
|
||||
}
|
||||
// If this is the first one, clear the JIT cache so it can switch to
|
||||
// watchpoint-compatible code.
|
||||
if (!had_any)
|
||||
m_system.GetJitInterface().ClearCache(guard);
|
||||
m_system.GetMMU().DBATUpdated();
|
||||
|
||||
if (update)
|
||||
Update();
|
||||
}
|
||||
|
||||
bool MemChecks::ToggleEnable(u32 address)
|
||||
@ -325,7 +326,7 @@ bool MemChecks::ToggleEnable(u32 address)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemChecks::Remove(u32 address)
|
||||
bool MemChecks::Remove(u32 address, bool update)
|
||||
{
|
||||
const auto iter =
|
||||
std::find_if(m_mem_checks.cbegin(), m_mem_checks.cend(),
|
||||
@ -336,9 +337,10 @@ bool MemChecks::Remove(u32 address)
|
||||
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
m_mem_checks.erase(iter);
|
||||
if (!HasAny())
|
||||
m_system.GetJitInterface().ClearCache(guard);
|
||||
m_system.GetMMU().DBATUpdated();
|
||||
|
||||
if (update)
|
||||
Update();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -346,7 +348,20 @@ void MemChecks::Clear()
|
||||
{
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
m_mem_checks.clear();
|
||||
m_system.GetJitInterface().ClearCache(guard);
|
||||
Update();
|
||||
}
|
||||
|
||||
void MemChecks::Update()
|
||||
{
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
|
||||
// Clear the JIT cache so it can switch the watchpoint-compatible mode.
|
||||
if (m_mem_breakpoints_set != HasAny())
|
||||
{
|
||||
m_system.GetJitInterface().ClearCache(guard);
|
||||
m_mem_breakpoints_set = HasAny();
|
||||
}
|
||||
|
||||
m_system.GetMMU().DBATUpdated();
|
||||
}
|
||||
|
||||
|
@ -115,19 +115,20 @@ public:
|
||||
TMemChecksStr GetStrings() const;
|
||||
void AddFromStrings(const TMemChecksStr& mc_strings);
|
||||
|
||||
void Add(TMemCheck memory_check);
|
||||
void Add(TMemCheck memory_check, bool update = true);
|
||||
|
||||
bool ToggleEnable(u32 address);
|
||||
|
||||
TMemCheck* GetMemCheck(u32 address, size_t size = 1);
|
||||
bool OverlapsMemcheck(u32 address, u32 length) const;
|
||||
// Remove Breakpoint. Returns whether it was removed.
|
||||
bool Remove(u32 address);
|
||||
bool Remove(u32 address, bool update = true);
|
||||
|
||||
void Update();
|
||||
void Clear();
|
||||
bool HasAny() const { return !m_mem_checks.empty(); }
|
||||
|
||||
private:
|
||||
TMemChecks m_mem_checks;
|
||||
Core::System& m_system;
|
||||
bool m_mem_breakpoints_set = false;
|
||||
};
|
||||
|
@ -174,9 +174,10 @@ static void RemoveBreakpoint(BreakpointType type, u32 addr, u32 len)
|
||||
auto& memchecks = Core::System::GetInstance().GetPowerPC().GetMemChecks();
|
||||
while (memchecks.GetMemCheck(addr, len) != nullptr)
|
||||
{
|
||||
memchecks.Remove(addr);
|
||||
memchecks.Remove(addr, false);
|
||||
INFO_LOG_FMT(GDB_STUB, "gdb: removed a memcheck: {:08x} bytes at {:08x}", len, addr);
|
||||
}
|
||||
memchecks.Update();
|
||||
}
|
||||
Host_PPCBreakpointsChanged();
|
||||
}
|
||||
|
@ -817,31 +817,36 @@ void MemoryViewWidget::ToggleBreakpoint(u32 addr, bool row)
|
||||
if (row && memchecks.OverlapsMemcheck(addr, m_bytes_per_row))
|
||||
overlap = true;
|
||||
|
||||
for (int i = 0; i < breaks; i++)
|
||||
{
|
||||
u32 address = addr + length * i;
|
||||
TMemCheck* check_ptr = memchecks.GetMemCheck(address, length);
|
||||
|
||||
if (check_ptr == nullptr && !overlap)
|
||||
const Core::CPUThreadGuard guard(m_system);
|
||||
for (int i = 0; i < breaks; i++)
|
||||
{
|
||||
TMemCheck check;
|
||||
check.start_address = address;
|
||||
check.end_address = check.start_address + length - 1;
|
||||
check.is_ranged = length > 0;
|
||||
check.is_break_on_read = (m_bp_type == BPType::ReadOnly || m_bp_type == BPType::ReadWrite);
|
||||
check.is_break_on_write = (m_bp_type == BPType::WriteOnly || m_bp_type == BPType::ReadWrite);
|
||||
check.log_on_hit = m_do_log;
|
||||
check.break_on_hit = true;
|
||||
u32 address = addr + length * i;
|
||||
TMemCheck* check_ptr = memchecks.GetMemCheck(address, length);
|
||||
|
||||
memchecks.Add(std::move(check));
|
||||
}
|
||||
else if (check_ptr != nullptr)
|
||||
{
|
||||
// Using the pointer fixes misaligned breakpoints (0x11 breakpoint in 0x10 aligned view).
|
||||
memchecks.Remove(check_ptr->start_address);
|
||||
if (check_ptr == nullptr && !overlap)
|
||||
{
|
||||
TMemCheck check;
|
||||
check.start_address = address;
|
||||
check.end_address = check.start_address + length - 1;
|
||||
check.is_ranged = length > 0;
|
||||
check.is_break_on_read = (m_bp_type == BPType::ReadOnly || m_bp_type == BPType::ReadWrite);
|
||||
check.is_break_on_write =
|
||||
(m_bp_type == BPType::WriteOnly || m_bp_type == BPType::ReadWrite);
|
||||
check.log_on_hit = m_do_log;
|
||||
check.break_on_hit = true;
|
||||
|
||||
memchecks.Add(std::move(check), false);
|
||||
}
|
||||
else if (check_ptr != nullptr)
|
||||
{
|
||||
// Using the pointer fixes misaligned breakpoints (0x11 breakpoint in 0x10 aligned view).
|
||||
memchecks.Remove(check_ptr->start_address, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memchecks.Update();
|
||||
emit Host::GetInstance()->PPCBreakpointsChanged();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user