mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 09:35:40 +00:00
CPU/CodeCache: Backpatch code writes after they exceed 10 faults
Small performance improvement in Driver 2.
This commit is contained in:
parent
62892b02d1
commit
576914cd2c
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue