summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Src/MemoryUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/Src/MemoryUtil.cpp')
-rw-r--r--Source/Core/Common/Src/MemoryUtil.cpp48
1 files changed, 42 insertions, 6 deletions
diff --git a/Source/Core/Common/Src/MemoryUtil.cpp b/Source/Core/Common/Src/MemoryUtil.cpp
index bc65f856f4..65c70e0c5e 100644
--- a/Source/Core/Common/Src/MemoryUtil.cpp
+++ b/Source/Core/Common/Src/MemoryUtil.cpp
@@ -27,28 +27,64 @@
#include <stdio.h>
#endif
+#if !defined(MAP_32BIT)
+#include <unistd.h>
+#define PAGE_MASK (getpagesize() - 1)
+#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
+#endif
+
// This is purposely not a full wrapper for virtualalloc/mmap, but it
// provides exactly the primitive operations that Dolphin needs.
void* AllocateExecutableMemory(size_t size, bool low)
{
-#ifdef _WIN32
+ static char *map_hint = 0;
+#if defined(__x86_64__) && !defined(MAP_32BIT)
+ if (low && (!map_hint))
+ map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
+#endif
+
+#if defined(_WIN32)
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
- void* ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE
-#if defined __linux__ && defined __x86_64__
+#if defined(__x86_64__)
+#if defined(MAP_32BIT)
| (low ? MAP_32BIT : 0)
-#endif
+#else
+ | (low ? MAP_FIXED : 0)
+#endif /* defined(MAP_32BIT) */
+#endif /* defined(__x86_64__) */
, -1, 0);
-#endif
+#endif /* defined(_WIN32) */
// printf("Mapped executable memory at %p (size %ld)\n", ptr,
// (unsigned long)size);
+#if defined(__FreeBSD__)
+ if (ptr == MAP_FAILED)
+ {
+ ptr = NULL;
+#else
if (ptr == NULL)
+ {
+#endif
PanicAlert("Failed to allocate executable memory");
-#ifdef _M_X64
+ }
+#if defined(__x86_64__) && !defined(MAP_32BIT)
+ else
+ {
+ if (low)
+ {
+ map_hint += size;
+ map_hint = (char*)round_page(map_hint); /* round up to the next page */
+ // printf("Next map will (hopefully) be at %p\n", map_hint);
+ }
+ }
+#endif
+
+#if defined(_M_X64)
if ((u64)ptr >= 0x80000000 && low == true)
PanicAlert("Executable memory ended up above 2GB!");
#endif