From 00f97073992b393c7eac4f1a6ec4311cb8a21cb1 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 19 Dec 2021 10:40:33 -0800 Subject: [PATCH] jit: Use a hash for invalidate/clear all. This should make sceKernelICacheClearAll() more useful. --- Core/MIPS/JitCommon/JitBlockCache.cpp | 25 +++++++++++++++++++++++-- Core/MIPS/JitCommon/JitBlockCache.h | 3 +++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 3f5e797312..7a0e3179f2 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -19,7 +19,9 @@ #include #include +#include "ext/xxhash.h" #include "Common.h" +#include "Common/Profiler/Profiler.h" #ifdef _WIN32 #include "Common/CommonWindows.h" @@ -59,6 +61,15 @@ op_agent_t agent; const u32 INVALID_EXIT = 0xFFFFFFFF; +static uint64_t HashJitBlock(const JitBlock &b) { + PROFILE_THIS_SCOPE("jithash"); + if (JIT_USE_COMPILEDHASH) { + // Includes the emuhack (or emuhacks) in memory. + return XXH3_64bits(Memory::GetPointer(b.originalAddress), b.originalSize * 4); + } + return 0; +} + JitBlockCache::JitBlockCache(MIPSState *mipsState, CodeBlockCommon *codeBlock) : codeBlock_(codeBlock), blocks_(nullptr), num_blocks_(0) { } @@ -234,6 +245,9 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link) { MIPSOpcode opcode = GetEmuHackOpForBlock(block_num); Memory::Write_Opcode_JIT(b.originalAddress, opcode); + // Note that this hashes the emuhack too, which is intentional. + b.compiledHash = HashJitBlock(b); + AddBlockMap(block_num); if (block_link) { @@ -592,8 +606,15 @@ void JitBlockCache::InvalidateChangedBlocks() { if (b.invalid || b.IsPureProxy()) continue; - const u32 emuhack = GetEmuHackOpForBlock(block_num).encoding; - if (Memory::ReadUnchecked_U32(b.originalAddress) != emuhack) { + bool changed = false; + if (JIT_USE_COMPILEDHASH) { + changed = b.compiledHash != HashJitBlock(b); + } else { + const u32 emuhack = GetEmuHackOpForBlock(block_num).encoding; + changed = Memory::ReadUnchecked_U32(b.originalAddress) != emuhack; + } + + if (changed) { DEBUG_LOG(JIT, "Invalidating changed block at %08x", b.originalAddress); DestroyBlock(block_num, DestroyType::INVALIDATE); } diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index fe6217da1f..28a432fafe 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -17,6 +17,7 @@ #pragma once +#include #include #include #include @@ -33,6 +34,7 @@ const int MAX_JIT_BLOCK_EXITS = 2; #else const int MAX_JIT_BLOCK_EXITS = 8; #endif +constexpr bool JIT_USE_COMPILEDHASH = true; struct BlockCacheStats { int numBlocks; @@ -68,6 +70,7 @@ struct JitBlock { u32 originalAddress; MIPSOpcode originalFirstOpcode; //to be able to restore + uint64_t compiledHash; u16 codeSize; u16 originalSize; u16 blockNum;