From ff9be97ea1135a238a093a4bbc61342b454921fe Mon Sep 17 00:00:00 2001
From: mitaclaw <140017135+mitaclaw@users.noreply.github.com>
Date: Wed, 17 Apr 2024 14:12:41 -0700
Subject: [PATCH] JitCache: Add WipeBlockProfilingData Function
Accessible from DolphinQt and Android.
---
.../org/dolphinemu/dolphinemu/NativeLibrary.java | 5 +++++
.../settings/ui/SettingsFragmentPresenter.kt | 10 ++++++++++
.../Android/app/src/main/res/values/strings.xml | 2 ++
Source/Android/jni/MainAndroid.cpp | 16 ++++++++++++++++
Source/Core/Core/PowerPC/JitCommon/JitCache.cpp | 9 +++++++++
Source/Core/Core/PowerPC/JitCommon/JitCache.h | 1 +
Source/Core/Core/PowerPC/JitInterface.cpp | 6 ++++++
Source/Core/Core/PowerPC/JitInterface.h | 1 +
Source/Core/DolphinQt/MenuBar.cpp | 11 ++++++++++-
Source/Core/DolphinQt/MenuBar.h | 2 ++
10 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
index 1cdd9fa473..63d40d5a91 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
@@ -391,6 +391,11 @@ public final class NativeLibrary
*/
public static native boolean IsUninitialized();
+ /**
+ * Re-initialize software JitBlock profiling data
+ */
+ public static native void WipeJitBlockProfilingData();
+
/**
* Writes out the JitBlock Cache log dump
*/
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt
index 7404b396fa..2af2202599 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -2013,6 +2013,16 @@ class SettingsFragmentPresenter(
0
)
)
+ sl.add(
+ RunRunnable(
+ context,
+ R.string.debug_jit_wipe_block_profiling_data,
+ 0,
+ R.string.debug_jit_wipe_block_profiling_data_alert,
+ 0,
+ true
+ ) { NativeLibrary.WipeJitBlockProfilingData() }
+ )
sl.add(
RunRunnable(
context,
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 8d1f9db297..aacc57a3be 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -412,6 +412,8 @@
Disable Large Entry Points Map
Jit Profiling
Enable Jit Block Profiling
+ Wipe Jit Block Profiling Data
+ Re-initialize JIT block profiling data?
Write Jit Block Log Dump
Jit
Jit Disabled
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index 270dad9ed3..f0a74986f6 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -410,6 +410,22 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetMaxLogLev
return static_cast(Common::Log::MAX_LOGLEVEL);
}
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WipeJitBlockProfilingData(
+ JNIEnv* env, jclass native_library_class)
+{
+ HostThreadLock guard;
+ auto& system = Core::System::GetInstance();
+ auto& jit_interface = system.GetJitInterface();
+ const Core::CPUThreadGuard cpu_guard(system);
+ if (jit_interface.GetCore() == nullptr)
+ {
+ env->CallStaticVoidMethod(native_library_class, IDCache::GetDisplayToastMsg(),
+ ToJString(env, Common::GetStringT("JIT is not active")), JNI_FALSE);
+ return;
+ }
+ jit_interface.WipeBlockProfilingData(cpu_guard);
+}
+
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteJitBlockLogDump(
JNIEnv* env, jclass native_library_class)
{
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
index 890e9975a4..62be327460 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
@@ -117,6 +117,15 @@ void JitBaseBlockCache::RunOnBlocks(const Core::CPUThreadGuard&,
f(e.second);
}
+void JitBaseBlockCache::WipeBlockProfilingData(const Core::CPUThreadGuard&)
+{
+ for (const auto& kv : block_map)
+ {
+ if (JitBlock::ProfileData* const profile_data = kv.second.profile_data.get())
+ *profile_data = {};
+ }
+}
+
JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address)
{
const u32 physical_address = m_jit.m_mmu.JitCache_TranslateAddress(em_address).address;
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
index 15e8c99e43..9539c15815 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
@@ -161,6 +161,7 @@ public:
u8** GetEntryPoints();
JitBlock** GetFastBlockMapFallback();
void RunOnBlocks(const Core::CPUThreadGuard& guard, std::function f) const;
+ void WipeBlockProfilingData(const Core::CPUThreadGuard& guard);
JitBlock* AllocateBlock(u32 em_address);
void FinalizeBlock(JitBlock& block, bool block_link, const std::set& physical_addresses);
diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp
index 7e0e281998..df128bb496 100644
--- a/Source/Core/Core/PowerPC/JitInterface.cpp
+++ b/Source/Core/Core/PowerPC/JitInterface.cpp
@@ -182,6 +182,12 @@ void JitInterface::JitBlockLogDump(const Core::CPUThreadGuard& guard, std::FILE*
}
}
+void JitInterface::WipeBlockProfilingData(const Core::CPUThreadGuard& guard)
+{
+ if (m_jit)
+ m_jit->GetBlockCache()->WipeBlockProfilingData(guard);
+}
+
std::variant
JitInterface::GetHostCode(u32 address) const
{
diff --git a/Source/Core/Core/PowerPC/JitInterface.h b/Source/Core/Core/PowerPC/JitInterface.h
index 17d0796bfd..0abf47eccb 100644
--- a/Source/Core/Core/PowerPC/JitInterface.h
+++ b/Source/Core/Core/PowerPC/JitInterface.h
@@ -57,6 +57,7 @@ public:
void UpdateMembase();
void JitBlockLogDump(const Core::CPUThreadGuard& guard, std::FILE* file) const;
+ void WipeBlockProfilingData(const Core::CPUThreadGuard& guard);
std::variant GetHostCode(u32 address) const;
// Memory Utilities
diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp
index 74f3f45e45..6170fa9ada 100644
--- a/Source/Core/DolphinQt/MenuBar.cpp
+++ b/Source/Core/DolphinQt/MenuBar.cpp
@@ -155,7 +155,8 @@ void MenuBar::OnEmulationStateChanged(Core::State state)
m_jit_clear_cache->setEnabled(running);
m_jit_log_coverage->setEnabled(!running);
m_jit_search_instruction->setEnabled(running);
- m_jit_write_cache_log_dump->setEnabled(running && jit_exists);
+ m_jit_wipe_profiling_data->setEnabled(jit_exists);
+ m_jit_write_cache_log_dump->setEnabled(jit_exists);
// Symbols
m_symbols->setEnabled(running);
@@ -196,6 +197,12 @@ void MenuBar::OnDebugModeToggled(bool enabled)
}
}
+void MenuBar::OnWipeJitBlockProfilingData()
+{
+ auto& system = Core::System::GetInstance();
+ system.GetJitInterface().WipeBlockProfilingData(Core::CPUThreadGuard{system});
+}
+
void MenuBar::OnWriteJitBlockLogDump()
{
const std::string filename = fmt::format("{}{}.txt", File::GetUserPath(D_DUMPDEBUG_JITBLOCKS_IDX),
@@ -922,6 +929,8 @@ void MenuBar::AddJITMenu()
connect(m_jit_profile_blocks, &QAction::toggled, [](bool enabled) {
Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_ENABLE_PROFILING, enabled);
});
+ m_jit_wipe_profiling_data = m_jit->addAction(tr("Wipe JIT Block Profiling Data"), this,
+ &MenuBar::OnWipeJitBlockProfilingData);
m_jit_write_cache_log_dump =
m_jit->addAction(tr("Write JIT Block Log Dump"), this, &MenuBar::OnWriteJitBlockLogDump);
diff --git a/Source/Core/DolphinQt/MenuBar.h b/Source/Core/DolphinQt/MenuBar.h
index 38bc164dc6..4ccc8df819 100644
--- a/Source/Core/DolphinQt/MenuBar.h
+++ b/Source/Core/DolphinQt/MenuBar.h
@@ -185,6 +185,7 @@ private:
void OnRecordingStatusChanged(bool recording);
void OnReadOnlyModeChanged(bool read_only);
void OnDebugModeToggled(bool enabled);
+ void OnWipeJitBlockProfilingData();
void OnWriteJitBlockLogDump();
QString GetSignatureSelector() const;
@@ -270,6 +271,7 @@ private:
QAction* m_jit_log_coverage;
QAction* m_jit_search_instruction;
QAction* m_jit_profile_blocks;
+ QAction* m_jit_wipe_profiling_data;
QAction* m_jit_write_cache_log_dump;
QAction* m_jit_off;
QAction* m_jit_loadstore_off;