summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorDentomologist <dentomologist@gmail.com>2025-08-06 14:35:24 -0700
committerDentomologist <dentomologist@gmail.com>2025-08-12 12:15:22 -0700
commitbd79bc47cc0867f6fefcadd741140a19a33f0ecd (patch)
tree212c3651510c562b046a059891f78a69e902eaab /Source/Core
parent72ef27c157e13075b656334657e46a3952ae2dff (diff)
BranchWatch: Extract shared function logic
IsolateWasOverwritten and IsolateNotOverwritten share the same basic logic and have almost exactly the same code, with the only difference being the comparison function used to keep or discard branches. To avoid unnecessary code duplication and ensure that the functions stay in sync after any future changes, create a helper function that takes the comparison function as a parameter and have IsolateWasOverwritten and IsolateNotOverwritten call that helper.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Debugger/BranchWatch.cpp56
-rw-r--r--Source/Core/Core/Debugger/BranchWatch.h3
2 files changed, 15 insertions, 44 deletions
diff --git a/Source/Core/Core/Debugger/BranchWatch.cpp b/Source/Core/Core/Debugger/BranchWatch.cpp
index 7facfda5d0..8393d8fcec 100644
--- a/Source/Core/Core/Debugger/BranchWatch.cpp
+++ b/Source/Core/Core/Debugger/BranchWatch.cpp
@@ -6,6 +6,7 @@
#include <algorithm>
#include <cstddef>
#include <cstdio>
+#include <functional>
#include <fmt/format.h>
@@ -200,7 +201,8 @@ void BranchWatch::IsolateNotExecuted(const CPUThreadGuard&)
}
}
-void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard)
+void BranchWatch::IsolateOverwrittenShared(const CPUThreadGuard& guard,
+ const std::function<bool(u32, u32)>& compare_func)
{
if (Core::GetState(guard.GetSystem()) == Core::State::Uninitialized)
{
@@ -223,7 +225,7 @@ void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard)
PowerPC::MMU::HostTryReadInstruction(guard, kv.first.origin_addr, address_space);
if (!read_result.has_value())
continue;
- if (kv.first.original_inst.hex == read_result->value)
+ if (compare_func(kv.first.original_inst.hex, read_result->value))
kv.second.hits_snapshot = ++m_blacklist_size; // Any non-zero number will work.
}
}
@@ -235,61 +237,27 @@ void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard)
return;
}
case Phase::Reduction:
- std::erase_if(m_selection, [&guard](const Selection::value_type& value) -> bool {
+ std::erase_if(m_selection, [&](const Selection::value_type& value) -> bool {
const std::optional read_result = PowerPC::MMU::HostTryReadInstruction(
guard, value.collection_ptr->first.origin_addr,
value.is_virtual ? PowerPC::RequestedAddressSpace::Virtual :
PowerPC::RequestedAddressSpace::Physical);
if (!read_result.has_value())
return false;
- return value.collection_ptr->first.original_inst.hex == read_result->value;
+ return compare_func(value.collection_ptr->first.original_inst.hex, read_result->value);
});
return;
}
}
+void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard)
+{
+ IsolateOverwrittenShared(guard, std::equal_to<u32>());
+}
+
void BranchWatch::IsolateNotOverwritten(const CPUThreadGuard& guard)
{
- if (Core::GetState(guard.GetSystem()) == Core::State::Uninitialized)
- {
- ASSERT_MSG(CORE, false, "Core is uninitialized.");
- return;
- }
- switch (m_recording_phase)
- {
- case Phase::Blacklist:
- {
- // Same dirty hack with != rather than ==, see above for details
- const auto routine = [&](Collection& collection, PowerPC::RequestedAddressSpace address_space) {
- for (Collection::value_type& kv : collection)
- if (kv.second.hits_snapshot == 0)
- {
- const std::optional read_result =
- PowerPC::MMU::HostTryReadInstruction(guard, kv.first.origin_addr, address_space);
- if (!read_result.has_value())
- continue;
- if (kv.first.original_inst.hex != read_result->value)
- kv.second.hits_snapshot = ++m_blacklist_size; // Any non-zero number will work.
- }
- };
- routine(m_collection_vt, PowerPC::RequestedAddressSpace::Virtual);
- routine(m_collection_vf, PowerPC::RequestedAddressSpace::Virtual);
- routine(m_collection_pt, PowerPC::RequestedAddressSpace::Physical);
- routine(m_collection_pf, PowerPC::RequestedAddressSpace::Physical);
- return;
- }
- case Phase::Reduction:
- std::erase_if(m_selection, [&guard](const Selection::value_type& value) -> bool {
- const std::optional read_result = PowerPC::MMU::HostTryReadInstruction(
- guard, value.collection_ptr->first.origin_addr,
- value.is_virtual ? PowerPC::RequestedAddressSpace::Virtual :
- PowerPC::RequestedAddressSpace::Physical);
- if (!read_result.has_value())
- return false;
- return value.collection_ptr->first.original_inst.hex != read_result->value;
- });
- return;
- }
+ IsolateOverwrittenShared(guard, std::not_equal_to<u32>());
}
void BranchWatch::UpdateHitsSnapshot()
diff --git a/Source/Core/Core/Debugger/BranchWatch.h b/Source/Core/Core/Debugger/BranchWatch.h
index 5644a979ba..d15af60a03 100644
--- a/Source/Core/Core/Debugger/BranchWatch.h
+++ b/Source/Core/Core/Debugger/BranchWatch.h
@@ -261,6 +261,9 @@ private:
return GetCollectionP(condition);
}
+ void IsolateOverwrittenShared(const CPUThreadGuard& guard,
+ const std::function<bool(u32, u32)>& compare_func);
+
std::size_t m_blacklist_size = 0;
Phase m_recording_phase = Phase::Blacklist;
bool m_recording_active = false;