summaryrefslogtreecommitdiff
path: root/Source/Core/Common/MemoryUtil.cpp
diff options
context:
space:
mode:
authorTillmann Karras <tilkax@gmail.com>2015-05-02 11:57:17 +0200
committerTillmann Karras <tilkax@gmail.com>2015-06-03 21:44:31 +0200
commitd4538c762ff1d42b69c325abea9bd0ce3854f486 (patch)
tree0a0c0387b501ccaa4bf5bb4ae1dbf48ee12995b2 /Source/Core/Common/MemoryUtil.cpp
parenta0597f0d626a919c6eeb4725b0efd189fddd4341 (diff)
MemoryUtil: get executable pages near static data
and clean up a bit.
Diffstat (limited to 'Source/Core/Common/MemoryUtil.cpp')
-rw-r--r--Source/Core/Common/MemoryUtil.cpp120
1 files changed, 19 insertions, 101 deletions
diff --git a/Source/Core/Common/MemoryUtil.cpp b/Source/Core/Common/MemoryUtil.cpp
index 510b258b09..e4563e3409 100644
--- a/Source/Core/Common/MemoryUtil.cpp
+++ b/Source/Core/Common/MemoryUtil.cpp
@@ -27,71 +27,29 @@
#endif
#endif
-// Valgrind doesn't support MAP_32BIT.
-// Uncomment the following line to be able to run Dolphin in Valgrind.
-//#undef MAP_32BIT
-
-#if !defined(_WIN32) && defined(_M_X86_64) && !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)
+void* AllocateExecutableMemory(size_t size, void* map_hint)
{
#if defined(_WIN32)
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
- static char *map_hint = nullptr;
-#if defined(_M_X86_64) && !defined(MAP_32BIT)
- // This OS has no flag to enforce allocation below the 4 GB boundary,
- // but if we hint that we want a low address it is very likely we will
- // get one.
- // An older version of this code used MAP_FIXED, but that has the side
- // effect of discarding already mapped pages that happen to be in the
- // requested virtual memory range (such as the emulated RAM, sometimes).
- if (low && (!map_hint))
- map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
-#endif
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_ANON | MAP_PRIVATE
-#if defined(_M_X86_64) && defined(MAP_32BIT)
- | (low ? MAP_32BIT : 0)
-#endif
- , -1, 0);
+ MAP_ANON | MAP_PRIVATE, -1, 0);
#endif /* defined(_WIN32) */
- // printf("Mapped executable memory at %p (size %ld)\n", ptr,
- // (unsigned long)size);
-
#ifdef _WIN32
if (ptr == nullptr)
- {
#else
if (ptr == MAP_FAILED)
- {
- ptr = nullptr;
#endif
- PanicAlert("Failed to allocate executable memory. If you are running Dolphin in Valgrind, try '#undef MAP_32BIT'.");
- }
-#if !defined(_WIN32) && defined(_M_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);
- }
+ ptr = nullptr;
+ PanicAlert("Failed to allocate executable memory.");
}
-#endif
-#if _M_X86_64
- if ((u64)ptr >= 0x80000000 && low == true)
- PanicAlert("Executable memory ended up above 2GB!");
+#ifdef _X86_64
+ ptrdiff_t ofs = (u8*)ptr - (u8*)map_hint;
+ if (ofs < -0x80000000ll || ofs + size > 0x80000000ll)
+ PanicAlert("Executable range can't be used for RIP-relative addressing.");
#endif
return ptr;
@@ -117,18 +75,12 @@ void* AllocateMemoryPages(size_t size)
void* AllocateAlignedMemory(size_t size, size_t alignment)
{
+ void* ptr = nullptr;
#ifdef _WIN32
- void* ptr = _aligned_malloc(size, alignment);
+ if (!(ptr = _aligned_malloc(size, alignment)))
#else
- void* ptr = nullptr;
- if (posix_memalign(&ptr, alignment, size) != 0)
- ERROR_LOG(MEMMAP, "Failed to allocate aligned memory");
+ if (posix_memalign(&ptr, alignment, size))
#endif
-
- // printf("Mapped memory at %p (size %ld)\n", ptr,
- // (unsigned long)size);
-
- if (ptr == nullptr)
PanicAlert("Failed to allocate aligned memory");
return ptr;
@@ -136,23 +88,12 @@ void* AllocateAlignedMemory(size_t size, size_t alignment)
void FreeMemoryPages(void* ptr, size_t size)
{
- if (ptr)
- {
- bool error_occurred = false;
-
#ifdef _WIN32
- if (!VirtualFree(ptr, 0, MEM_RELEASE))
- error_occurred = true;
+ if (ptr && !VirtualFree(ptr, 0, MEM_RELEASE))
#else
- int retval = munmap(ptr, size);
-
- if (retval != 0)
- error_occurred = true;
+ if (ptr && munmap(ptr, size))
#endif
-
- if (error_occurred)
- PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg().c_str());
- }
+ PanicAlert("FreeMemoryPages failed!\n%s", GetLastErrorMsg().c_str());
}
void FreeAlignedMemory(void* ptr)
@@ -169,58 +110,34 @@ void FreeAlignedMemory(void* ptr)
void ReadProtectMemory(void* ptr, size_t size)
{
- bool error_occurred = false;
-
#ifdef _WIN32
DWORD oldValue;
if (!VirtualProtect(ptr, size, PAGE_NOACCESS, &oldValue))
- error_occurred = true;
#else
- int retval = mprotect(ptr, size, PROT_NONE);
-
- if (retval != 0)
- error_occurred = true;
+ if (mprotect(ptr, size, PROT_NONE))
#endif
-
- if (error_occurred)
PanicAlert("ReadProtectMemory failed!\n%s", GetLastErrorMsg().c_str());
}
void WriteProtectMemory(void* ptr, size_t size, bool allowExecute)
{
- bool error_occurred = false;
-
#ifdef _WIN32
DWORD oldValue;
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
- error_occurred = true;
#else
- int retval = mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ);
-
- if (retval != 0)
- error_occurred = true;
+ if (mprotect(ptr, size, PROT_READ | (allowExecute ? PROT_EXEC : 0)))
#endif
-
- if (error_occurred)
PanicAlert("WriteProtectMemory failed!\n%s", GetLastErrorMsg().c_str());
}
void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
{
- bool error_occurred = false;
-
#ifdef _WIN32
DWORD oldValue;
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue))
- error_occurred = true;
#else
- int retval = mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
-
- if (retval != 0)
- error_occurred = true;
+ if (mprotect(ptr, size, PROT_READ | PROT_WRITE | (allowExecute ? PROT_EXEC : 0)))
#endif
-
- if (error_occurred)
PanicAlert("UnWriteProtectMemory failed!\n%s", GetLastErrorMsg().c_str());
}
@@ -236,7 +153,8 @@ std::string MemUsage()
// Print information about the memory usage of the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
- if (nullptr == hProcess) return "MemUsage Error";
+ if (nullptr == hProcess)
+ return "MemUsage Error";
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str());