multi instance fastmem on Linux

This commit is contained in:
RSDuck 2024-10-30 00:20:12 +01:00
parent 04fe90b437
commit 0a34a21ee7
7 changed files with 66 additions and 36 deletions

View File

@ -30,7 +30,7 @@
#include "ARMJIT_Internal.h" #include "ARMJIT_Internal.h"
#include "ARMJIT_Memory.h" #include "ARMJIT_Memory.h"
#include "ARMJIT_Compiler.h" #include "ARMJIT_Compiler.h"
#include "ARMJIT_CodeMem.h" #include "ARMJIT_Global.h"
#include "ARMInterpreter_ALU.h" #include "ARMInterpreter_ALU.h"
#include "ARMInterpreter_LoadStore.h" #include "ARMInterpreter_LoadStore.h"
@ -234,6 +234,8 @@ ARMJIT::~ARMJIT() noexcept
{ {
JitEnableWrite(); JitEnableWrite();
ResetBlockCache(); ResetBlockCache();
ARMJIT_Global::DeInit();
} }
void ARMJIT::Reset() noexcept void ARMJIT::Reset() noexcept
@ -477,7 +479,7 @@ ARMJIT::ARMJIT(melonDS::NDS& nds, std::optional<JITArgs> jit) noexcept :
BranchOptimizations(jit.has_value() ? jit->BranchOptimizations : false), BranchOptimizations(jit.has_value() ? jit->BranchOptimizations : false),
FastMemory(jit.has_value() ? jit->FastMemory : false) FastMemory(jit.has_value() ? jit->FastMemory : false)
{ {
ARMJIT_CodeMem::Init(); ARMJIT_Global::Init();
} }
void ARMJIT::RetireJitBlock(JitBlock* block) noexcept void ARMJIT::RetireJitBlock(JitBlock* block) noexcept

View File

@ -1,4 +1,5 @@
#include "ARMJIT_CodeMem.h" #include "ARMJIT_Global.h"
#include "ARMJIT_Memory.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
@ -14,10 +15,10 @@
namespace melonDS namespace melonDS
{ {
namespace ARMJIT_CodeMem namespace ARMJIT_Global
{ {
std::mutex codeMemoryMutex; std::mutex globalMutex;
static constexpr size_t NumCodeMemSlices = 4; static constexpr size_t NumCodeMemSlices = 4;
@ -28,9 +29,9 @@ u32 AvailableCodeMemSlices = (1 << NumCodeMemSlices) - 1;
int RefCounter = 0; int RefCounter = 0;
void* Allocate() void* AllocateCodeMem()
{ {
std::lock_guard guard(codeMemoryMutex); std::lock_guard guard(globalMutex);
if (AvailableCodeMemSlices) if (AvailableCodeMemSlices)
{ {
@ -49,9 +50,9 @@ void* Allocate()
#endif #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++) for (int i = 0; i < NumCodeMemSlices; i++)
{ {
@ -72,7 +73,7 @@ void Free(void* codeMem)
void Init() void Init()
{ {
std::lock_guard guard(codeMemoryMutex); std::lock_guard guard(globalMutex);
RefCounter++; RefCounter++;
if (RefCounter == 1) if (RefCounter == 1)
@ -85,6 +86,19 @@ void Init()
#else #else
mprotect(CodeMemory, sizeof(CodeMemory), PROT_EXEC | PROT_READ | PROT_WRITE); mprotect(CodeMemory, sizeof(CodeMemory), PROT_EXEC | PROT_READ | PROT_WRITE);
#endif #endif
ARMJIT_Memory::RegisterFaultHandler();
}
}
void DeInit()
{
std::lock_guard guard(globalMutex);
RefCounter--;
if (RefCounter == 0)
{
ARMJIT_Memory::UnregisterFaultHandler();
} }
} }

View File

@ -16,8 +16,8 @@
with melonDS. If not, see http://www.gnu.org/licenses/. with melonDS. If not, see http://www.gnu.org/licenses/.
*/ */
#ifndef ARMJIT_CODEMEM_H #ifndef ARMJIT_GLOBAL_H
#define ARMJIT_CODEMEM_H #define ARMJIT_GLOBAL_H
#include "types.h" #include "types.h"
@ -26,15 +26,16 @@
namespace melonDS namespace melonDS
{ {
namespace ARMJIT_CodeMem namespace ARMJIT_Global
{ {
static constexpr size_t CodeMemorySliceSize = 1024*1024*32; static constexpr size_t CodeMemorySliceSize = 1024*1024*32;
void Init(); void Init();
void DeInit();
void* Allocate(); void* AllocateCodeMem();
void Free(void* codeMem); void FreeCodeMem(void* codeMem);
} }

View File

@ -627,6 +627,31 @@ bool ARMJIT_Memory::MapAtAddress(u32 addr) noexcept
return true; 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) bool ARMJIT_Memory::FaultHandler(FaultDescription& faultDesc, melonDS::NDS& nds)
{ {
if (nds.JIT.JITCompiler.IsJITFault(faultDesc.FaultPC)) 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)); 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); mmap(MemoryBase, MemoryTotalSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, MemoryFile, 0);
u8* basePtr = MemoryBase;
#endif #endif
} }
@ -780,10 +793,6 @@ ARMJIT_Memory::~ARMJIT_Memory() noexcept
ExceptionHandlerHandle = nullptr; ExceptionHandlerHandle = nullptr;
} }
#else #else
sigaction(SIGSEGV, &OldSaSegv, nullptr);
#ifdef __APPLE__
sigaction(SIGBUS, &OldSaBus, nullptr);
#endif
if (MemoryBase) if (MemoryBase)
{ {
munmap(MemoryBase, VirtmemAreaSize); munmap(MemoryBase, VirtmemAreaSize);

View File

@ -23,6 +23,7 @@
#include "MemConstants.h" #include "MemConstants.h"
#ifdef JIT_ENABLED #ifdef JIT_ENABLED
# include <mutex>
# include "TinyVector.h" # include "TinyVector.h"
# include "ARM.h" # include "ARM.h"
# if defined(__SWITCH__) # if defined(__SWITCH__)
@ -137,6 +138,9 @@ public:
bool IsFastmemCompatible(int region) const noexcept; bool IsFastmemCompatible(int region) const noexcept;
void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) const noexcept; void* GetFuncForAddr(ARM* cpu, u32 addr, bool store, int size) const noexcept;
bool MapAtAddress(u32 addr) noexcept; bool MapAtAddress(u32 addr) noexcept;
static void RegisterFaultHandler();
static void UnregisterFaultHandler();
private: private:
friend class Compiler; friend class Compiler;
struct Mapping struct Mapping

View File

@ -21,7 +21,7 @@
#include "../ARMJIT.h" #include "../ARMJIT.h"
#include "../ARMInterpreter.h" #include "../ARMInterpreter.h"
#include "../NDS.h" #include "../NDS.h"
#include "../ARMJIT_CodeMem.h" #include "../ARMJIT_Global.h"
#include <assert.h> #include <assert.h>
#include <stdarg.h> #include <stdarg.h>
@ -225,8 +225,8 @@ void Compiler::A_Comp_MSR()
Compiler::Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds) Compiler::Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds)
{ {
CodeMemBase = static_cast<u8*>(ARMJIT_CodeMem::Allocate()); CodeMemBase = static_cast<u8*>(ARMJIT_Global::AllocateCodeMem());
CodeMemSize = ARMJIT_CodeMem::CodeMemorySliceSize; CodeMemSize = ARMJIT_Global::CodeMemorySliceSize;
ResetStart = CodeMemBase; ResetStart = CodeMemBase;
@ -444,7 +444,7 @@ Compiler::Compiler(melonDS::NDS& nds) : XEmitter(), NDS(nds)
Compiler::~Compiler() Compiler::~Compiler()
{ {
ARMJIT_CodeMem::Free(CodeMemBase); ARMJIT_Global::FreeCodeMem(CodeMemBase);
} }
void Compiler::LoadCPSR() void Compiler::LoadCPSR()

View File

@ -97,7 +97,7 @@ if (ENABLE_JIT)
ARMJIT.cpp ARMJIT.cpp
ARMJIT_Memory.cpp ARMJIT_Memory.cpp
ARMJIT_CodeMem.cpp ARMJIT_Global.cpp
dolphin/CommonFuncs.cpp) dolphin/CommonFuncs.cpp)