This commit is contained in:
Dentomologist 2025-08-12 12:18:50 -07:00 committed by GitHub
commit 79b7460863
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 15 additions and 44 deletions

View file

@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
#include <functional>
#include <fmt/format.h> #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) 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); PowerPC::MMU::HostTryReadInstruction(guard, kv.first.origin_addr, address_space);
if (!read_result.has_value()) if (!read_result.has_value())
continue; 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. kv.second.hits_snapshot = ++m_blacklist_size; // Any non-zero number will work.
} }
} }
@ -235,61 +237,27 @@ void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard)
return; return;
} }
case Phase::Reduction: 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( const std::optional read_result = PowerPC::MMU::HostTryReadInstruction(
guard, value.collection_ptr->first.origin_addr, guard, value.collection_ptr->first.origin_addr,
value.is_virtual ? PowerPC::RequestedAddressSpace::Virtual : value.is_virtual ? PowerPC::RequestedAddressSpace::Virtual :
PowerPC::RequestedAddressSpace::Physical); PowerPC::RequestedAddressSpace::Physical);
if (!read_result.has_value()) if (!read_result.has_value())
return false; 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; return;
} }
} }
void BranchWatch::IsolateWasOverwritten(const CPUThreadGuard& guard)
{
IsolateOverwrittenShared(guard, std::equal_to<u32>());
}
void BranchWatch::IsolateNotOverwritten(const CPUThreadGuard& guard) void BranchWatch::IsolateNotOverwritten(const CPUThreadGuard& guard)
{ {
if (Core::GetState(guard.GetSystem()) == Core::State::Uninitialized) IsolateOverwrittenShared(guard, std::not_equal_to<u32>());
{
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;
}
} }
void BranchWatch::UpdateHitsSnapshot() void BranchWatch::UpdateHitsSnapshot()

View file

@ -261,6 +261,9 @@ private:
return GetCollectionP(condition); return GetCollectionP(condition);
} }
void IsolateOverwrittenShared(const CPUThreadGuard& guard,
const std::function<bool(u32, u32)>& compare_func);
std::size_t m_blacklist_size = 0; std::size_t m_blacklist_size = 0;
Phase m_recording_phase = Phase::Blacklist; Phase m_recording_phase = Phase::Blacklist;
bool m_recording_active = false; bool m_recording_active = false;