From 0480ca48fbddc79f41c16e8ef8e251e095b1a6f3 Mon Sep 17 00:00:00 2001 From: aldelaro5 Date: Sat, 20 Aug 2016 23:57:39 -0400 Subject: [PATCH 1/2] Add a thread safe variant of clearing the jit cache --- Source/Core/Core/PowerPC/JitCommon/JitCache.cpp | 14 ++++++++++++++ Source/Core/Core/PowerPC/JitCommon/JitCache.h | 1 + 2 files changed, 15 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp index 6f345b9636..0817bdc7de 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp @@ -17,6 +17,7 @@ #include "Common/JitRegister.h" #include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/CoreTiming.h" #include "Core/PowerPC/JitCommon/JitBase.h" #include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/PowerPC.h" @@ -27,6 +28,13 @@ using namespace Gen; +static int s_clear_jit_cache_thread_safe; + +static void ClearCacheThreadSafe(u64 userdata, s64 cyclesdata) +{ + JitInterface::ClearCache(); +} + bool JitBaseBlockCache::IsFull() const { return GetNumBlocks() >= MAX_NUM_BLOCKS - 1; @@ -34,6 +42,7 @@ bool JitBaseBlockCache::IsFull() const void JitBaseBlockCache::Init() { + s_clear_jit_cache_thread_safe = CoreTiming::RegisterEvent("clearJitCache", ClearCacheThreadSafe); JitRegister::Init(SConfig::GetInstance().m_perfDir); iCache.fill(0); @@ -73,6 +82,11 @@ void JitBaseBlockCache::Clear() blocks[0].invalid = true; } +void JitBaseBlockCache::SchedulateClearCacheThreadSafe() +{ + CoreTiming::ScheduleEvent(0, s_clear_jit_cache_thread_safe); +} + void JitBaseBlockCache::Reset() { Shutdown(); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h index 842e723ee9..f3a3c8b4a3 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h @@ -159,6 +159,7 @@ public: void FinalizeBlock(int block_num, bool block_link, const u8* code_ptr); void Clear(); + void SchedulateClearCacheThreadSafe(); void Init(); void Shutdown(); void Reset(); From a39e331aad4a110602205a0df2ac084a1b43bf94 Mon Sep 17 00:00:00 2001 From: aldelaro5 Date: Sat, 20 Aug 2016 23:59:18 -0400 Subject: [PATCH 2/2] Schedule an event to clear the jit cache when adding the first and last memory check Also fix an oddity in the case when the last memory check is deleted, the jit cache was supposed to be cleared in that case, but it was out of the for loop that finds the one to delete so it was never run. Naturally, the same fix for the adding the first memory check was applied. --- Source/Core/Common/BreakPoints.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Common/BreakPoints.cpp b/Source/Core/Common/BreakPoints.cpp index 769afcfcf0..e9c8c481cc 100644 --- a/Source/Core/Common/BreakPoints.cpp +++ b/Source/Core/Common/BreakPoints.cpp @@ -171,7 +171,7 @@ void MemChecks::Add(const TMemCheck& _rMemoryCheck) // If this is the first one, clear the JIT cache so it can switch to // watchpoint-compatible code. if (!had_any && jit) - jit->ClearCache(); + jit->GetBlockCache()->SchedulateClearCacheThreadSafe(); } void MemChecks::Remove(u32 _Address) @@ -181,11 +181,11 @@ void MemChecks::Remove(u32 _Address) if (i->StartAddress == _Address) { m_MemChecks.erase(i); + if (!HasAny() && jit) + jit->GetBlockCache()->SchedulateClearCacheThreadSafe(); return; } } - if (!HasAny() && jit) - jit->ClearCache(); } TMemCheck* MemChecks::GetMemCheck(u32 address)