diff options
author | RSDuck <rsduck@users.noreply.github.com> | 2019-06-22 01:28:32 +0200 |
---|---|---|
committer | RSDuck <rsduck@users.noreply.github.com> | 2020-04-26 13:02:53 +0200 |
commit | c5c342c0091d9bf36500950a21585c5c98dd7d9d (patch) | |
tree | 79abf542c763cce60ffe650e300bfee31194ba8a /src/dolphin/MemoryUtil.cpp | |
parent | d2f05cd30fcd530655649549452c34dea1969281 (diff) |
JIT: base
all instructions are interpreted
Diffstat (limited to 'src/dolphin/MemoryUtil.cpp')
-rw-r--r-- | src/dolphin/MemoryUtil.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/dolphin/MemoryUtil.cpp b/src/dolphin/MemoryUtil.cpp new file mode 100644 index 0000000..01cb897 --- /dev/null +++ b/src/dolphin/MemoryUtil.cpp @@ -0,0 +1,193 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license_dolphin.txt file included. + +#include <cstddef> +#include <cstdlib> +#include <string> + +#define PanicAlert(fmt, ...) \ + do \ + { \ + printf(fmt "\n", ## __VA_ARGS__); \ + abort(); \ + } while (false) + +#include "../types.h" +#include "CommonFuncs.h" + +#ifdef _WIN32 +#include <windows.h> +//#include "Common/StringUtil.h" +#else +#include <stdio.h> +#include <sys/mman.h> +#include <sys/types.h> +#if defined __APPLE__ || defined __FreeBSD__ || defined __OpenBSD__ +#include <sys/sysctl.h> +#elif defined __HAIKU__ +#include <OS.h> +#else +#include <sys/sysinfo.h> +#endif +#endif + +namespace Common +{ +// 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) +{ + printf("c\n"); + +#if defined(_WIN32) + void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + void* ptr = + mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); + + if (ptr == MAP_FAILED) + ptr = nullptr; +#endif + printf("a\n"); + + if (ptr == nullptr) + PanicAlert("Failed to allocate executable memory"); + + printf("b\n"); + + return ptr; +} + +void* AllocateMemoryPages(size_t size) +{ +#ifdef _WIN32 + void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); +#else + void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + + if (ptr == MAP_FAILED) + ptr = nullptr; +#endif + + if (ptr == nullptr) + PanicAlert("Failed to allocate raw memory"); + + return ptr; +} + +void* AllocateAlignedMemory(size_t size, size_t alignment) +{ +#ifdef _WIN32 + void* ptr = _aligned_malloc(size, alignment); +#else + void* ptr = nullptr; + if (posix_memalign(&ptr, alignment, size) != 0) + ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); +#endif + + if (ptr == nullptr) + PanicAlert("Failed to allocate aligned memory"); + + return ptr; +} + +void FreeMemoryPages(void* ptr, size_t size) +{ + if (ptr) + { +#ifdef _WIN32 + if (!VirtualFree(ptr, 0, MEM_RELEASE)) + PanicAlert("FreeMemoryPages failed!\nVirtualFree: %s", GetLastErrorString().c_str()); +#else + if (munmap(ptr, size) != 0) + PanicAlert("FreeMemoryPages failed!\nmunmap: %s", LastStrerrorString().c_str()); +#endif + } +} + +void FreeAlignedMemory(void* ptr) +{ + if (ptr) + { +#ifdef _WIN32 + _aligned_free(ptr); +#else + free(ptr); +#endif + } +} + +void ReadProtectMemory(void* ptr, size_t size) +{ +#ifdef _WIN32 + DWORD oldValue; + if (!VirtualProtect(ptr, size, PAGE_NOACCESS, &oldValue)) + PanicAlert("ReadProtectMemory failed!\nVirtualProtect: %s", GetLastErrorString().c_str()); +#else + if (mprotect(ptr, size, PROT_NONE) != 0) + PanicAlert("ReadProtectMemory failed!\nmprotect: %s", LastStrerrorString().c_str()); +#endif +} + +void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) +{ +#ifdef _WIN32 + DWORD oldValue; + if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) + PanicAlert("WriteProtectMemory failed!\nVirtualProtect: %s", GetLastErrorString().c_str()); +#else + if (mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ) != 0) + PanicAlert("WriteProtectMemory failed!\nmprotect: %s", LastStrerrorString().c_str()); +#endif +} + +void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) +{ +#ifdef _WIN32 + DWORD oldValue; + if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) + PanicAlert("UnWriteProtectMemory failed!\nVirtualProtect: %s", GetLastErrorString().c_str()); +#else + if (mprotect(ptr, size, + allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ) != 0) + { + PanicAlert("UnWriteProtectMemory failed!\nmprotect: %s", LastStrerrorString().c_str()); + } +#endif +} + +size_t MemPhysical() +{ +#ifdef _WIN32 + MEMORYSTATUSEX memInfo; + memInfo.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&memInfo); + return memInfo.ullTotalPhys; +#elif defined __APPLE__ || defined __FreeBSD__ || defined __OpenBSD__ + int mib[2]; + size_t physical_memory; + mib[0] = CTL_HW; +#ifdef __APPLE__ + mib[1] = HW_MEMSIZE; +#elif defined __FreeBSD__ + mib[1] = HW_REALMEM; +#elif defined __OpenBSD__ + mib[1] = HW_PHYSMEM; +#endif + size_t length = sizeof(size_t); + sysctl(mib, 2, &physical_memory, &length, NULL, 0); + return physical_memory; +#elif defined __HAIKU__ + system_info sysinfo; + get_system_info(&sysinfo); + return static_cast<size_t>(sysinfo.max_pages * B_PAGE_SIZE); +#else + struct sysinfo memInfo; + sysinfo(&memInfo); + return (size_t)memInfo.totalram * memInfo.mem_unit; +#endif +} + +} // namespace Common |