From c42e1b8c3e81c9304de66ec83dc0f3a59691d4f9 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 21 Apr 2024 20:57:35 -0700 Subject: [PATCH 1/5] Output REF version info into the log --- src/REFramework.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/REFramework.cpp b/src/REFramework.cpp index d551f7962..0de0ad19f 100644 --- a/src/REFramework.cpp +++ b/src/REFramework.cpp @@ -240,6 +240,14 @@ REFramework::REFramework(HMODULE reframework_module) spdlog::info("REFramework entry"); + spdlog::info("Commit hash: {}", REF_COMMIT_HASH); + spdlog::info("Tag: {}", REF_TAG); + spdlog::info("Commits past tag: {}", REF_COMMITS_PAST_TAG); + spdlog::info("Branch: {}", REF_BRANCH); + spdlog::info("Total commits: {}", REF_TOTAL_COMMITS); + spdlog::info("Build date: {}", REF_BUILD_DATE); + spdlog::info("Build time: {}", REF_BUILD_TIME); + const auto module_size = *utility::get_module_size(m_game_module); spdlog::info("Game Module Addr: {:x}", (uintptr_t)m_game_module); From 0820b966b5e8762e6c344fee0705384640ad03e9 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 22 Apr 2024 02:38:50 -0700 Subject: [PATCH 2/5] VM: Fix horrible performance issues caused by lock contention --- shared/sdk/REContext.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/shared/sdk/REContext.cpp b/shared/sdk/REContext.cpp index 898201c64..f823eefca 100644 --- a/shared/sdk/REContext.cpp +++ b/shared/sdk/REContext.cpp @@ -7,6 +7,7 @@ #include "utility/Scan.hpp" #include "utility/Module.hpp" #include "utility/Exceptions.hpp" +#include #include "reframework/API.hpp" #include "ReClass.hpp" @@ -17,6 +18,7 @@ namespace sdk { VM** VM::s_global_context{ nullptr }; sdk::InvokeMethod* VM::s_invoke_tbl{nullptr}; VM::ThreadContextFn VM::s_get_thread_context{ nullptr }; + bool s_fully_updated_pointers{false}; int32_t VM::s_static_tbl_offset{ 0 }; int32_t VM::s_type_db_offset{ 0 }; @@ -65,6 +67,13 @@ namespace sdk { void VM::update_pointers() { { + // Originally this was always locking the lock in read mode + // however that was WAY too much which was reducing performance + // so just checking this bool is enough. + if (s_fully_updated_pointers) { + return; + } + // Lock a shared lock for the s_mutex std::shared_lock lock(s_mutex); @@ -76,6 +85,11 @@ namespace sdk { // Create a unique lock for the s_mutex as we get to the meat of the function std::unique_lock lock{ s_mutex }; + utility::ScopeGuard sg{ [&]() { + s_fully_updated_pointers = true; + } + }; + spdlog::info("[VM::update_pointers] Updating..."); // Version 1 From e4b8cfcf0b873000ce958041c5dcb65155e36413 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 22 Apr 2024 02:53:41 -0700 Subject: [PATCH 3/5] VM: Fix --- shared/sdk/REContext.cpp | 2 +- shared/sdk/REContext.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/shared/sdk/REContext.cpp b/shared/sdk/REContext.cpp index f823eefca..15f7c227f 100644 --- a/shared/sdk/REContext.cpp +++ b/shared/sdk/REContext.cpp @@ -18,7 +18,7 @@ namespace sdk { VM** VM::s_global_context{ nullptr }; sdk::InvokeMethod* VM::s_invoke_tbl{nullptr}; VM::ThreadContextFn VM::s_get_thread_context{ nullptr }; - bool s_fully_updated_pointers{false}; + bool VM::s_fully_updated_pointers{false}; int32_t VM::s_static_tbl_offset{ 0 }; int32_t VM::s_type_db_offset{ 0 }; diff --git a/shared/sdk/REContext.hpp b/shared/sdk/REContext.hpp index 4e89e91a8..c5d706089 100644 --- a/shared/sdk/REContext.hpp +++ b/shared/sdk/REContext.hpp @@ -75,6 +75,7 @@ class VM { static sdk::InvokeMethod* s_invoke_tbl; static ThreadContextFn s_get_thread_context; + static bool s_fully_updated_pointers; static int32_t s_static_tbl_offset; static int32_t s_type_db_offset; }; From a1e3006194871a3e446383a55b0c53b5b72d83df Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 22 Apr 2024 03:07:16 -0700 Subject: [PATCH 4/5] VM: Reduce VMContext lock contention --- shared/sdk/REContext.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/shared/sdk/REContext.cpp b/shared/sdk/REContext.cpp index 15f7c227f..d48c308b7 100644 --- a/shared/sdk/REContext.cpp +++ b/shared/sdk/REContext.cpp @@ -298,12 +298,17 @@ namespace sdk { } static std::shared_mutex s_pointers_mtx{}; + static bool s_fully_updated_vm_context_pointers{false}; static void* (*s_context_unhandled_exception_fn)(::REThreadContext*) = nullptr; static void* (*s_context_local_frame_gc_fn)(::REThreadContext*) = nullptr; static void* (*s_context_end_global_frame_fn)(::REThreadContext*) = nullptr; void sdk::VMContext::update_pointers() { { + if (s_fully_updated_vm_context_pointers) { + return; + } + std::shared_lock _{s_pointers_mtx}; if (s_context_unhandled_exception_fn != nullptr && s_context_local_frame_gc_fn != nullptr && s_context_end_global_frame_fn != nullptr) { @@ -313,6 +318,10 @@ namespace sdk { std::unique_lock _{s_pointers_mtx}; + utility::ScopeGuard sg{[] { + s_fully_updated_vm_context_pointers = true; + }}; + spdlog::info("Locating funcs"); // Version 1 From 4e55776818dba4a284a90ebbdc86c39ab05f7f31 Mon Sep 17 00:00:00 2001 From: praydog Date: Mon, 22 Apr 2024 03:14:18 -0700 Subject: [PATCH 5/5] FunctionHook: Reduce lock contention --- shared/utility/FunctionHook.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/shared/utility/FunctionHook.hpp b/shared/utility/FunctionHook.hpp index 57a501bb9..e52b29cfc 100644 --- a/shared/utility/FunctionHook.hpp +++ b/shared/utility/FunctionHook.hpp @@ -19,18 +19,33 @@ class FunctionHook { bool create(); auto get_original() const { + if (m_init_finished) { + return m_inline_hook->trampoline().address(); + } + std::shared_lock _{ m_initialization_mutex }; + m_init_finished = true; return m_inline_hook->trampoline().address(); } template T* get_original() const { + if (m_init_finished) { + return m_inline_hook->original(); + } + std::shared_lock _{ m_initialization_mutex }; + m_init_finished = true; return m_inline_hook->original(); } auto is_valid() const { + if (m_init_finished) { + return is_valid_unsafe(); + } + std::shared_lock _{ m_initialization_mutex }; + m_init_finished = true; return is_valid_unsafe(); } @@ -44,6 +59,7 @@ class FunctionHook { std::expected m_inline_hook; mutable std::shared_mutex m_initialization_mutex{}; + mutable bool m_init_finished{ false }; uintptr_t m_target{ 0 }; uintptr_t m_destination{ 0 };