mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
Apple M1 Support for MacOS
This commit adds support for compiling Dolphin for ARM on MacOS so that it can run natively on the M1 processors without running through Rosseta2 emulation providing a 30-50% performance speedup and less hitches from Rosseta2. It consists of several key changes: - Adding support for W^X allocation(MAP_JIT) for the ARM JIT - Adding the machine context and config info to identify the M1 processor - Additions to the build system and docs to support building universal binaries - Adding code signing entitlements to access the MAP_JIT functionality - Updating the MoltenVK libvulkan.dylib to a newer version with M1 support
This commit is contained in:
@ -16,6 +16,7 @@
|
||||
#include <windows.h>
|
||||
#include "Common/StringUtil.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
@ -38,9 +39,12 @@ void* AllocateExecutableMemory(size_t size)
|
||||
#if defined(_WIN32)
|
||||
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
#else
|
||||
int map_flags =MAP_ANON | MAP_PRIVATE;
|
||||
#if defined(_M_ARM_64) && defined(__APPLE__)
|
||||
map_flags |= MAP_JIT;
|
||||
#endif
|
||||
void* ptr =
|
||||
mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
|
||||
mmap(nullptr, size, PROT_READ | PROT_WRITE |PROT_EXEC , map_flags, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
ptr = nullptr;
|
||||
#endif
|
||||
@ -50,6 +54,35 @@ void* AllocateExecutableMemory(size_t size)
|
||||
|
||||
return ptr;
|
||||
}
|
||||
// Certain platforms (Mac OS X on ARM) enforce that a single thread can only have write or
|
||||
// execute permissions to pages at any given point of time. The two below functions
|
||||
// are used to toggle between having write permissions or execute permissions.
|
||||
//
|
||||
// The default state of these allocations in Dolphin is for them to be executable,
|
||||
// but not writeable. So, functions that are updating these pages should wrap their
|
||||
// writes like below:
|
||||
|
||||
// JITPageWriteEnableExecuteDisable();
|
||||
// PrepareInstructionStreamForJIT();
|
||||
// JITPageWriteDisableExecuteEnable();
|
||||
|
||||
//Allows a thread to write to executable memory, but not execute the data.
|
||||
void JITPageWriteEnableExecuteDisable(){
|
||||
#if defined(_M_ARM_64) && defined(__APPLE__)
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
pthread_jit_write_protect_np(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
//Allows a thread to execute memory allocated for execution, but not write to it.
|
||||
void JITPageWriteDisableExecuteEnable(){
|
||||
#if defined(_M_ARM_64) && defined(__APPLE__)
|
||||
if (__builtin_available(macOS 11.0, *)) {
|
||||
pthread_jit_write_protect_np(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void* AllocateMemoryPages(size_t size)
|
||||
{
|
||||
|
Reference in New Issue
Block a user