From 899d61bc7dd093393aafcd88c4f072ff879228a7 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 30 Sep 2023 17:32:51 +0200 Subject: [PATCH] Jit64: Recompile asm routines on cache clear This is needed so that the checks added in the previous commit will be reevaluated if the value of m_enable_dcache changes. JitArm64 was already recompiling its asm routines on cache clear by necessity. It doesn't have the same setup as Jit64 where the asm routines are in a separate region, so clearing the JitArm64 cache results in the asm routines being cleared too. --- Source/Core/Common/CodeBlock.h | 11 ++++++++--- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 1 + Source/Core/Core/PowerPC/Jit64/JitAsm.cpp | 10 +++++++++- Source/Core/Core/PowerPC/Jit64/JitAsm.h | 1 + Source/Core/VideoCommon/VertexLoaderARM64.cpp | 2 +- Source/Core/VideoCommon/VertexLoaderX64.cpp | 2 +- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Source/Core/Common/CodeBlock.h b/Source/Core/Common/CodeBlock.h index aa35d3b782..fbd4cdb00a 100644 --- a/Source/Core/Common/CodeBlock.h +++ b/Source/Core/Common/CodeBlock.h @@ -82,9 +82,14 @@ public: } bool IsInSpace(const u8* ptr) const { return ptr >= region && ptr < (region + region_size); } - // Cannot currently be undone. Will write protect the entire code region. - // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). - void WriteProtect() { Common::WriteProtectMemory(region, region_size, true); } + void WriteProtect(bool allow_execute) + { + Common::WriteProtectMemory(region, region_size, allow_execute); + } + void UnWriteProtect(bool allow_execute) + { + Common::UnWriteProtectMemory(region, region_size, allow_execute); + } void ResetCodePtr() { T::SetCodePtr(region, region + region_size); } size_t GetSpaceLeft() const { diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 9a5f603573..6dbb998d3a 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -305,6 +305,7 @@ void Jit64::ClearCache() ClearCodeSpace(); Clear(); RefreshConfig(InitFastmemArena::No); + asm_routines.Regenerate(); ResetFreeMemoryRanges(); } diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index ef667cce86..36189dbb40 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -32,7 +32,15 @@ void Jit64AsmRoutineManager::Init() { m_const_pool.Init(AllocChildCodeSpace(4096), 4096); Generate(); - WriteProtect(); + WriteProtect(true); +} + +void Jit64AsmRoutineManager::Regenerate() +{ + UnWriteProtect(false); + ResetCodePtr(); + Generate(); + WriteProtect(true); } // PLAN: no more block numbers - crazy opcodes just contain offset within diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.h b/Source/Core/Core/PowerPC/Jit64/JitAsm.h index 3f2c2297fe..4db3c8f477 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.h +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.h @@ -35,6 +35,7 @@ public: explicit Jit64AsmRoutineManager(Jit64& jit); void Init(); + void Regenerate(); void ResetStack(Gen::X64CodeBlock& emitter); diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.cpp b/Source/Core/VideoCommon/VertexLoaderARM64.cpp index 03bb82d5c2..12b6b1d79a 100644 --- a/Source/Core/VideoCommon/VertexLoaderARM64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderARM64.cpp @@ -56,7 +56,7 @@ VertexLoaderARM64::VertexLoaderARM64(const TVtxDesc& vtx_desc, const VAT& vtx_at const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes; ClearCodeSpace(); GenerateVertexLoader(); - WriteProtect(); + WriteProtect(true); } // Returns the register to use as the base and an offset from that register. diff --git a/Source/Core/VideoCommon/VertexLoaderX64.cpp b/Source/Core/VideoCommon/VertexLoaderX64.cpp index 0280ec4e83..9aba5a58c8 100644 --- a/Source/Core/VideoCommon/VertexLoaderX64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderX64.cpp @@ -49,7 +49,7 @@ VertexLoaderX64::VertexLoaderX64(const TVtxDesc& vtx_desc, const VAT& vtx_att) AllocCodeSpace(4096); ClearCodeSpace(); GenerateVertexLoader(); - WriteProtect(); + WriteProtect(true); Common::JitRegister::Register(region, GetCodePtr(), "VertexLoaderX64\nVtx desc: \n{}\nVAT:\n{}", vtx_desc, vtx_att);