diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index d698b0a9..4edb2f44 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -30,7 +30,7 @@ #include "ARMJIT_Internal.h" #include "ARMJIT_Memory.h" #include "ARMJIT_Compiler.h" -#include "ARMJIT_CodeMem.h" +#include "ARMJIT_Global.h" #include "ARMInterpreter_ALU.h" #include "ARMInterpreter_LoadStore.h" @@ -234,6 +234,8 @@ ARMJIT::~ARMJIT() noexcept { JitEnableWrite(); ResetBlockCache(); + + ARMJIT_Global::DeInit(); } void ARMJIT::Reset() noexcept @@ -477,7 +479,7 @@ ARMJIT::ARMJIT(melonDS::NDS& nds, std::optional jit) noexcept : BranchOptimizations(jit.has_value() ? jit->BranchOptimizations : false), FastMemory(jit.has_value() ? jit->FastMemory : false) { - ARMJIT_CodeMem::Init(); + ARMJIT_Global::Init(); } void ARMJIT::RetireJitBlock(JitBlock* block) noexcept diff --git a/src/ARMJIT_CodeMem.cpp b/src/ARMJIT_Global.cpp similarity index 76% rename from src/ARMJIT_CodeMem.cpp rename to src/ARMJIT_Global.cpp index 4d5b344b..3bf1b4b2 100644 --- a/src/ARMJIT_CodeMem.cpp +++ b/src/ARMJIT_Global.cpp @@ -1,4 +1,5 @@ -#include "ARMJIT_CodeMem.h" +#include "ARMJIT_Global.h" +#include "ARMJIT_Memory.h" #ifdef _WIN32 #include @@ -14,10 +15,10 @@ namespace melonDS { -namespace ARMJIT_CodeMem +namespace ARMJIT_Global { -std::mutex codeMemoryMutex; +std::mutex globalMutex; static constexpr size_t NumCodeMemSlices = 4; @@ -28,9 +29,9 @@ u32 AvailableCodeMemSlices = (1 << NumCodeMemSlices) - 1; int RefCounter = 0; -void* Allocate() +void* AllocateCodeMem() { - std::lock_guard guard(codeMemoryMutex); + std::lock_guard guard(globalMutex); if (AvailableCodeMemSlices) { @@ -49,9 +50,9 @@ void* Allocate() #endif } -void Free(void* codeMem) +void FreeCodeMem(void* codeMem) { - std::lock_guard guard(codeMemoryMutex); + std::lock_guard guard(globalMutex); for (int i = 0; i < NumCodeMemSlices; i++) { @@ -72,7 +73,7 @@ void Free(void* codeMem) void Init() { - std::lock_guard guard(codeMemoryMutex); + std::lock_guard guard(globalMutex); RefCounter++; if (RefCounter == 1) @@ -85,6 +86,19 @@ void Init() #else mprotect(CodeMemory, sizeof(CodeMemory), PROT_EXEC | PROT_READ | PROT_WRITE); #endif + + ARMJIT_Memory::RegisterFaultHandler(); + } +} + +void DeInit() +{ + std::lock_guard guard(globalMutex); + + RefCounter--; + if (RefCounter == 0) + { + ARMJIT_Memory::UnregisterFaultHandler(); } } diff --git a/src/ARMJIT_CodeMem.h b/src/ARMJIT_Global.h similarity index 85% rename from src/ARMJIT_CodeMem.h rename to src/ARMJIT_Global.h index 9f0f2f81..299d71a6 100644 --- a/src/ARMJIT_CodeMem.h +++ b/src/ARMJIT_Global.h @@ -16,8 +16,8 @@ with melonDS. If not, see http://www.gnu.org/licenses/. */ -#ifndef ARMJIT_CODEMEM_H -#define ARMJIT_CODEMEM_H +#ifndef ARMJIT_GLOBAL_H +#define ARMJIT_GLOBAL_H #include "types.h" @@ -26,15 +26,16 @@ namespace melonDS { -namespace ARMJIT_CodeMem +namespace ARMJIT_Global { static constexpr size_t CodeMemorySliceSize = 1024*1024*32; void Init(); +void DeInit(); -void* Allocate(); -void Free(void* codeMem); +void* AllocateCodeMem(); +void FreeCodeMem(void* codeMem); } diff --git a/src/ARMJIT_Memory.cpp b/src/ARMJIT_Memory.cpp index bce1221e..418bbe87 100644 --- a/src/ARMJIT_Memory.cpp +++ b/src/ARMJIT_Memory.cpp @@ -627,6 +627,31 @@ bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept return true; } +void ARMJIT_Memory::RegisterFaultHandler() +{ +#ifdef _WIN32 + +#else + struct sigaction sa; + sa.sa_handler = nullptr; + sa.sa_sigaction = &SigsegvHandler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, &OldSaSegv); +#ifdef __APPLE__ + sigaction(SIGBUS, &sa, &OldSaBus); +#endif +#endif +} + +void ARMJIT_Memory::UnregisterFaultHandler() +{ + sigaction(SIGSEGV, &OldSaSegv, nullptr); +#ifdef __APPLE__ + sigaction(SIGBUS, &OldSaBus, nullptr); +#endif +} + bool ARMJIT_Memory::FaultHandler(FaultDescription& faultDesc, melonDS::NDS& nds) { if (nds.JIT.JITCompiler.IsJITFault(faultDesc.FaultPC)) @@ -725,19 +750,7 @@ ARMJIT_Memory::ARMJIT_Memory(melonDS::NDS& nds) : NDS(nds) Log(LogLevel::Error, "Failed to allocate memory using ftruncate! (%s)", strerror(errno)); } - struct sigaction sa; - sa.sa_handler = nullptr; - sa.sa_sigaction = &SigsegvHandler; - sa.sa_flags = SA_SIGINFO; - sigemptyset(&sa.sa_mask); - sigaction(SIGSEGV, &sa, &OldSaSegv); -#ifdef __APPLE__ - sigaction(SIGBUS, &sa, &OldSaBus); -#endif - mmap(MemoryBase, MemoryTotalSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, MemoryFile, 0); - - u8* basePtr = MemoryBase; #endif } @@ -780,10 +793,6 @@ ARMJIT_Memory::~ARMJIT_Memory() noexcept ExceptionHandlerHandle = nullptr; } #else - sigaction(SIGSEGV, &OldSaSegv, nullptr); -#ifdef __APPLE__ - sigaction(SIGBUS, &OldSaBus, nullptr); -#endif if (MemoryBase) { munmap(MemoryBase, VirtmemAreaSize); diff --git a/src/ARMJIT_Memory.h b/src/ARMJIT_Memory.h index 88e647d5..2b039cbd 100644 --- a/src/ARMJIT_Memory.h +++ b/src/ARMJIT_Memory.h @@ -23,6 +23,7 @@ #include "MemConstants.h" #ifdef JIT_ENABLED +# include # include "TinyVector.h" # include "ARM.h" # if defined(__SWITCH__) @@ -137,6 +138,9 @@ public: bool IsFastmemCompatible(int region) const noexcept; void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) const noexcept; bool MapAtAddress(u32 addr) noexcept; + + static void RegisterFaultHandler(); + static void UnregisterFaultHandler(); private: friend class Compiler; struct Mapping diff --git a/src/ARMJIT_x64/ARMJIT_Compiler.cpp b/src/ARMJIT_x64/ARMJIT_Compiler.cpp index 619e74d0..9ebcc667 100644 --- a/src/ARMJIT_x64/ARMJIT_Compiler.cpp +++ b/src/ARMJIT_x64/ARMJIT_Compiler.cpp @@ -21,7 +21,7 @@ #include "../ARMJIT.h" #include "../ARMInterpreter.h" #include "../NDS.h" -#include "../ARMJIT_CodeMem.h" +#include "../ARMJIT_Global.h" #include #include @@ -225,8 +225,8 @@ void Compiler::A_Comp_MSR() Compiler::Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds) { - CodeMemBase = static_cast(ARMJIT_CodeMem::Allocate()); - CodeMemSize = ARMJIT_CodeMem::CodeMemorySliceSize; + CodeMemBase = static_cast(ARMJIT_Global::AllocateCodeMem()); + CodeMemSize = ARMJIT_Global::CodeMemorySliceSize; ResetStart = CodeMemBase; @@ -444,7 +444,7 @@ Compiler::Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds) Compiler::~Compiler() { - ARMJIT_CodeMem::Free(CodeMemBase); + ARMJIT_Global::FreeCodeMem(CodeMemBase); } void Compiler::LoadCPSR() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2296c1c4..e1f6ee26 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,7 +97,7 @@ if (ENABLE_JIT) ARMJIT.cpp ARMJIT_Memory.cpp - ARMJIT_CodeMem.cpp + ARMJIT_Global.cpp dolphin/CommonFuncs.cpp)