From a0987829e5c3440a43b6db768e6f94c930d367e5 Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Fri, 26 Jul 2024 23:59:19 -0700 Subject: [PATCH] JITs: Add GetMemoryStats Function Using the updated rangeset library --- .../Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp | 5 +++++ .../Core/PowerPC/CachedInterpreter/CachedInterpreter.h | 1 + Source/Core/Core/PowerPC/Jit64/Jit.cpp | 5 +++++ Source/Core/Core/PowerPC/Jit64/Jit.h | 1 + Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 8 ++++++++ Source/Core/Core/PowerPC/JitArm64/Jit.h | 1 + Source/Core/Core/PowerPC/JitCommon/JitBase.h | 6 ++++++ Source/Core/Core/PowerPC/JitInterface.cpp | 7 +++++++ Source/Core/Core/PowerPC/JitInterface.h | 7 +++++++ Source/UnitTests/Core/PageFaultTest.cpp | 1 + 10 files changed, 42 insertions(+) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index 0584e29adb..99b9e30163 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -408,6 +408,11 @@ void CachedInterpreter::EraseSingleBlock(const JitBlock& block) FreeRanges(); } +std::vector CachedInterpreter::GetMemoryStats() const +{ + return {{"free", m_free_ranges.get_stats()}}; +} + void CachedInterpreter::ClearCache() { m_block_cache.Clear(); diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h index 5463badd32..9f84f5d4ec 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h @@ -47,6 +47,7 @@ public: bool DoJit(u32 address, JitBlock* b, u32 nextPC); void EraseSingleBlock(const JitBlock& block) override; + std::vector GetMemoryStats() const override; static std::size_t Disassemble(const JitBlock& block, std::ostream& stream); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index b88f486b30..0f408f8bb7 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -1208,6 +1208,11 @@ void Jit64::EraseSingleBlock(const JitBlock& block) FreeRanges(); } +std::vector Jit64::GetMemoryStats() const +{ + return {{"near", m_free_ranges_near.get_stats()}, {"far", m_free_ranges_far.get_stats()}}; +} + BitSet8 Jit64::ComputeStaticGQRs(const PPCAnalyst::CodeBlock& cb) const { return cb.m_gqr_used & ~cb.m_gqr_modified; diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index bdb25ebd33..75fd8a118b 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -66,6 +66,7 @@ public: bool DoJit(u32 em_address, JitBlock* b, u32 nextPC); void EraseSingleBlock(const JitBlock& block) override; + std::vector GetMemoryStats() const override; // Finds a free memory region and sets the near and far code emitters to point at that region. // Returns false if no free memory region can be found for either of the two. diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 48595cbeae..ad129ad98f 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -1040,6 +1040,14 @@ void JitArm64::EraseSingleBlock(const JitBlock& block) FreeRanges(); } +std::vector JitArm64::GetMemoryStats() const +{ + return {{"near_0", m_free_ranges_near_0.get_stats()}, + {"near_1", m_free_ranges_near_1.get_stats()}, + {"far_0", m_free_ranges_far_0.get_stats()}, + {"far_1", m_free_ranges_far_1.get_stats()}}; +} + std::optional JitArm64::SetEmitterStateToFreeCodeRegion() { // Find some large free memory blocks and set code emitters to point at them. If we can't find diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 019b734655..f73c5f3252 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -49,6 +49,7 @@ public: void Jit(u32 em_address, bool clear_cache_and_retry_on_failure); void EraseSingleBlock(const JitBlock& block) override; + std::vector GetMemoryStats() const override; const char* GetName() const override { return "JITARM64"; } diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/PowerPC/JitCommon/JitBase.h index 42e47d679b..cad4e6d44e 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.h @@ -6,8 +6,10 @@ #include #include #include +#include #include #include +#include #include "Common/BitSet.h" #include "Common/CommonTypes.h" @@ -196,6 +198,10 @@ public: virtual void EraseSingleBlock(const JitBlock& block) = 0; + // Memory region name, free size, and fragmentation ratio + using MemoryStats = std::pair>; + virtual std::vector GetMemoryStats() const = 0; + virtual const CommonAsmRoutinesBase* GetAsmRoutines() = 0; virtual bool HandleFault(uintptr_t access_address, SContext* ctx) = 0; diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp index b0c05b68ad..f142fcee60 100644 --- a/Source/Core/Core/PowerPC/JitInterface.cpp +++ b/Source/Core/Core/PowerPC/JitInterface.cpp @@ -269,6 +269,13 @@ void JitInterface::EraseSingleBlock(const JitBlock& block) m_jit->EraseSingleBlock(block); } +std::vector JitInterface::GetMemoryStats() const +{ + if (m_jit) + return m_jit->GetMemoryStats(); + return {}; +} + void JitInterface::InvalidateICache(u32 address, u32 size, bool forced) { if (m_jit) diff --git a/Source/Core/Core/PowerPC/JitInterface.h b/Source/Core/Core/PowerPC/JitInterface.h index 6dd624502d..09e3d49f8b 100644 --- a/Source/Core/Core/PowerPC/JitInterface.h +++ b/Source/Core/Core/PowerPC/JitInterface.h @@ -8,7 +8,10 @@ #include #include #include +#include +#include #include +#include #include "Common/CommonTypes.h" #include "Core/MachineContext.h" @@ -78,6 +81,10 @@ public: // outside of the Core *must* use this, consider reworking the logic in JITWidget. void EraseSingleBlock(const JitBlock& block); + // Memory region name, free size, and fragmentation ratio + using MemoryStats = std::pair>; + std::vector GetMemoryStats() const; + // If "forced" is true, a recompile is being requested on code that hasn't been modified. void InvalidateICache(u32 address, u32 size, bool forced); void InvalidateICacheLine(u32 address); diff --git a/Source/UnitTests/Core/PageFaultTest.cpp b/Source/UnitTests/Core/PageFaultTest.cpp index abaea313ed..21ef289159 100644 --- a/Source/UnitTests/Core/PageFaultTest.cpp +++ b/Source/UnitTests/Core/PageFaultTest.cpp @@ -41,6 +41,7 @@ public: JitBaseBlockCache* GetBlockCache() override { return nullptr; } void Jit(u32 em_address) override {} void EraseSingleBlock(const JitBlock&) override {} + std::vector GetMemoryStats() const override { return {}; } const CommonAsmRoutinesBase* GetAsmRoutines() override { return nullptr; } virtual bool HandleFault(uintptr_t access_address, SContext* ctx) override {