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;