CPU/CodeCache: Backpatch code writes after they exceed 10 faults

Small performance improvement in Driver 2.
This commit is contained in:
Connor McLaughlin 2020-11-07 18:49:59 +10:00
parent 62892b02d1
commit 576914cd2c
2 changed files with 22 additions and 12 deletions

View file

@ -27,6 +27,7 @@ constexpr bool USE_BLOCK_LINKING = true;
static constexpr u32 RECOMPILER_CODE_CACHE_SIZE = 32 * 1024 * 1024; static constexpr u32 RECOMPILER_CODE_CACHE_SIZE = 32 * 1024 * 1024;
static constexpr u32 RECOMPILER_FAR_CODE_CACHE_SIZE = 32 * 1024 * 1024; static constexpr u32 RECOMPILER_FAR_CODE_CACHE_SIZE = 32 * 1024 * 1024;
static constexpr u32 CODE_WRITE_FAULT_THRESHOLD_FOR_SLOWMEM = 10;
#ifdef USE_STATIC_CODE_BUFFER #ifdef USE_STATIC_CODE_BUFFER
static constexpr u32 RECOMPILER_GUARD_SIZE = 4096; static constexpr u32 RECOMPILER_GUARD_SIZE = 4096;
@ -727,17 +728,6 @@ Common::PageFaultHandler::HandlerResult PageFaultHandler(void* exception_pc, voi
Log_DevPrintf("Page fault handler invoked at PC=%p Address=%p %s, fastmem offset 0x%08X", exception_pc, fault_address, Log_DevPrintf("Page fault handler invoked at PC=%p Address=%p %s, fastmem offset 0x%08X", exception_pc, fault_address,
is_write ? "(write)" : "(read)", fastmem_address); is_write ? "(write)" : "(read)", fastmem_address);
if (is_write && !g_state.cop0_regs.sr.Isc && Bus::IsRAMAddress(fastmem_address))
{
// this is probably a code page, since we aren't going to fault due to requiring fastmem on RAM.
const u32 code_page_index = Bus::GetRAMCodePageIndex(fastmem_address);
if (Bus::IsRAMCodePage(code_page_index))
{
InvalidateBlocksWithPageIndex(code_page_index);
return Common::PageFaultHandler::HandlerResult::ContinueExecution;
}
}
// use upper_bound to find the next block after the pc // use upper_bound to find the next block after the pc
HostCodeMap::iterator upper_iter = HostCodeMap::iterator upper_iter =
s_host_code_map.upper_bound(reinterpret_cast<CodeBlock::HostCodePointer>(exception_pc)); s_host_code_map.upper_bound(reinterpret_cast<CodeBlock::HostCodePointer>(exception_pc));
@ -752,9 +742,28 @@ Common::PageFaultHandler::HandlerResult PageFaultHandler(void* exception_pc, voi
for (auto bpi_iter = block->loadstore_backpatch_info.begin(); bpi_iter != block->loadstore_backpatch_info.end(); for (auto bpi_iter = block->loadstore_backpatch_info.begin(); bpi_iter != block->loadstore_backpatch_info.end();
++bpi_iter) ++bpi_iter)
{ {
const Recompiler::LoadStoreBackpatchInfo& lbi = *bpi_iter; Recompiler::LoadStoreBackpatchInfo& lbi = *bpi_iter;
if (lbi.host_pc == exception_pc) if (lbi.host_pc == exception_pc)
{ {
if (is_write && !g_state.cop0_regs.sr.Isc && Bus::IsRAMAddress(fastmem_address))
{
// this is probably a code page, since we aren't going to fault due to requiring fastmem on RAM.
const u32 code_page_index = Bus::GetRAMCodePageIndex(fastmem_address);
if (Bus::IsRAMCodePage(code_page_index))
{
if (++lbi.fault_count < CODE_WRITE_FAULT_THRESHOLD_FOR_SLOWMEM)
{
InvalidateBlocksWithPageIndex(code_page_index);
return Common::PageFaultHandler::HandlerResult::ContinueExecution;
}
else
{
Log_DevPrintf("Backpatching code write at %p (%08X) address %p (%08X) to slowmem after threshold",
exception_pc, lbi.guest_pc, fault_address, fastmem_address);
}
}
}
// found it, do fixup // found it, do fixup
if (Recompiler::CodeGenerator::BackpatchLoadStore(lbi)) if (Recompiler::CodeGenerator::BackpatchLoadStore(lbi))
{ {

View file

@ -135,6 +135,7 @@ struct LoadStoreBackpatchInfo
HostReg address_host_reg; // register containing the guest address to load/store HostReg address_host_reg; // register containing the guest address to load/store
HostReg value_host_reg; // register containing the source/destination HostReg value_host_reg; // register containing the source/destination
PhysicalMemoryAddress guest_pc; PhysicalMemoryAddress guest_pc;
u32 fault_count;
}; };
} // namespace Recompiler } // namespace Recompiler