From bd79bc47cc0867f6fefcadd741140a19a33f0ecd Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Wed, 6 Aug 2025 14:35:24 -0700 Subject: [PATCH] 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. --- Source/Core/Core/Debugger/BranchWatch.cpp | 56 +++++------------------ Source/Core/Core/Debugger/BranchWatch.h | 3 ++ 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 #include #include +#include #include @@ -200,7 +201,8 @@ void BranchWatch::IsolateNotExecuted(const CPUThreadGuard&) } } -void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard) +void BranchWatch::IsolateOverwrittenShared(const CPUThreadGuard& guard, + const std::function& 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()); +} + 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()); } 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& compare_func); + std::size_t m_blacklist_size = 0; Phase m_recording_phase = Phase::Blacklist; bool m_recording_active = false;