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 <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()

View file

@ -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;