mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-02-10 05:29:02 -06:00
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.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user