Allocate low executable memory on OS X as on Windows and Linux.
Even with LoadStorePaired accounted for, there are still some niggling 64-bit cleanliness bugs left that are not practical to weed out on a single platform. We should probably have an option to use >2GB memory only on all platforms for debugging. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6792 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
f634d58035
commit
d4158f076a
|
@ -58,19 +58,12 @@ void MemArena::ReleaseSpace()
|
|||
}
|
||||
|
||||
|
||||
void* MemArena::CreateView(s64 offset, size_t size, bool ensure_low_mem)
|
||||
void* MemArena::CreateView(s64 offset, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return MapViewOfFile(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size);
|
||||
#else
|
||||
void* ptr = mmap(0, size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED
|
||||
#ifdef __x86_64__
|
||||
| (ensure_low_mem ? MAP_32BIT : 0)
|
||||
#endif
|
||||
, fd, offset);
|
||||
return ptr;
|
||||
return mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -27,14 +27,13 @@
|
|||
// This class lets you create a block of anonymous RAM, and then arbitrarily map views into it.
|
||||
// Multiple views can mirror the same section of the block, which makes it very convient for emulating
|
||||
// memory mirrors.
|
||||
// Pass ensure_low_mem = true to CreateView if you want arbitrarily positioned views to end up in the low 2GB.
|
||||
|
||||
class MemArena
|
||||
{
|
||||
public:
|
||||
void GrabLowMemSpace(size_t size);
|
||||
void ReleaseSpace();
|
||||
void* CreateView(s64 offset, size_t size, bool ensure_low_mem = false);
|
||||
void* CreateView(s64 offset, size_t size);
|
||||
void* CreateViewAt(s64 offset, size_t size, void* base);
|
||||
void ReleaseView(void* view, size_t size);
|
||||
|
||||
|
|
|
@ -34,59 +34,42 @@ void* AllocateExecutableMemory(size_t size, bool low)
|
|||
{
|
||||
#ifdef _WIN32
|
||||
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
#else
|
||||
void* ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE
|
||||
#if defined __linux__ && defined __x86_64__
|
||||
| (low ? MAP_32BIT : 0)
|
||||
#endif
|
||||
, -1, 0);
|
||||
#endif
|
||||
|
||||
// printf("Mapped executable memory at %p (size %ld)\n", ptr,
|
||||
// (unsigned long)size);
|
||||
|
||||
if (ptr == NULL)
|
||||
PanicAlert("Failed to allocate executable memory");
|
||||
if ((u64)ptr >= 0x80000000)
|
||||
{
|
||||
PanicAlert("Executable memory ended up above 2GB!");
|
||||
// If this happens, we have to implement a free ram search scheme. ector knows how.
|
||||
}
|
||||
|
||||
return ptr;
|
||||
|
||||
#else
|
||||
void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE
|
||||
#ifdef __x86_64__
|
||||
| (low ? MAP_32BIT : 0)
|
||||
#endif
|
||||
, -1, 0); // | MAP_FIXED
|
||||
// printf("Mapped executable memory at %p (size %i)\n", retval, size);
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
PanicAlert("Failed to allocate executable memory, errno=%i", errno);
|
||||
}
|
||||
|
||||
return retval;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void* AllocateMemoryPages(size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
PanicAlert("Failed to allocate raw memory");
|
||||
}
|
||||
|
||||
return ptr;
|
||||
|
||||
#else
|
||||
void* retval = mmap(0, size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0); // | MAP_FIXED
|
||||
// printf("Mapped memory at %p (size %i)\n", retval, size);
|
||||
|
||||
if (!retval)
|
||||
{
|
||||
PanicAlert("Failed to allocate raw memory, errno=%i", errno);
|
||||
}
|
||||
|
||||
return retval;
|
||||
void* ptr = mmap(0, size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
#endif
|
||||
|
||||
// printf("Mapped memory at %p (size %ld)\n", ptr,
|
||||
// (unsigned long)size);
|
||||
|
||||
if (ptr == NULL)
|
||||
PanicAlert("Failed to allocate raw memory");
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void FreeMemoryPages(void* ptr, size_t size)
|
||||
|
@ -125,27 +108,25 @@ void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
std::string MemUsage()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
DWORD processID = GetCurrentProcessId();
|
||||
HANDLE hProcess;
|
||||
PROCESS_MEMORY_COUNTERS pmc;
|
||||
HANDLE hProcess;
|
||||
PROCESS_MEMORY_COUNTERS pmc;
|
||||
std::string Ret;
|
||||
|
||||
// Print information about the memory usage of the process.
|
||||
// Print information about the memory usage of the process.
|
||||
|
||||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
|
||||
if (NULL == hProcess) return "MemUsage Error";
|
||||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
|
||||
if (NULL == hProcess) return "MemUsage Error";
|
||||
|
||||
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
|
||||
if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
|
||||
Ret = StringFromFormat("%s K", ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str());
|
||||
|
||||
CloseHandle(hProcess);
|
||||
CloseHandle(hProcess);
|
||||
return Ret;
|
||||
|
||||
#else
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -23,11 +23,6 @@
|
|||
#endif
|
||||
#include <string>
|
||||
|
||||
// Linux-specific mmap(2) flag
|
||||
#ifndef MAP_32BIT
|
||||
#define MAP_32BIT 0
|
||||
#endif
|
||||
|
||||
void* AllocateExecutableMemory(size_t size, bool low = true);
|
||||
void* AllocateMemoryPages(size_t size);
|
||||
void FreeMemoryPages(void* ptr, size_t size);
|
||||
|
|
|
@ -91,27 +91,11 @@ void SCoreStartupParameter::LoadDefaults()
|
|||
bJITOff = false; // debugger only settings
|
||||
bJITLoadStoreOff = false;
|
||||
bJITLoadStoreFloatingOff = false;
|
||||
bJITLoadStorePairedOff = false;
|
||||
bJITLoadStorePairedOff = false; // XXX not 64-bit clean
|
||||
bJITFloatingPointOff = false;
|
||||
bJITIntegerOff = false;
|
||||
bJITPairedOff = false;
|
||||
bJITSystemRegistersOff = false;
|
||||
#ifdef __APPLE__
|
||||
// These are required for the JIT cores to work in OSX
|
||||
// Older revs (~4854) Only required LoadStorePaired to be turned off
|
||||
// Newer revs (~4890) require both turned off
|
||||
#ifdef _M_X64
|
||||
// These work fine in 32bit OSX
|
||||
// Since the reason why 64bit OSX fails out is due to casting (u32)(u64)
|
||||
// Since all 64bit applications are above the 32bit memory boundary
|
||||
bJITLoadStorePairedOff = true;
|
||||
#endif
|
||||
//#elif defined(__linux__)
|
||||
// Similar to OSX, something with LoadStorePaired seems to cause
|
||||
// crashes on linux. Only Win32 seems to be forgiving enough to
|
||||
// not do anything funny...(FIXME)
|
||||
// bJITLoadStorePairedOff = true;
|
||||
#endif
|
||||
|
||||
m_strName = "NONE";
|
||||
m_strUniqueID = "00000000";
|
||||
|
|
|
@ -35,63 +35,7 @@
|
|||
|
||||
using namespace Gen;
|
||||
|
||||
static int temp32;
|
||||
|
||||
|
||||
#if defined(__APPLE__) && _M_X64
|
||||
void CommonAsmRoutines::GenFifoWrite(int size)
|
||||
{
|
||||
// Assume value in ABI_PARAM1
|
||||
PUSH(RSI);
|
||||
if (size != 32)
|
||||
PUSH(EDX);
|
||||
BSWAP(size, ABI_PARAM1);
|
||||
MOV(32, R(EAX), Imm32((u64)GPFifo::m_gatherPipe));
|
||||
MOV(64, R(RSI), M(&GPFifo::m_gatherPipeCount));
|
||||
if (size != 32) {
|
||||
MOV(32, R(EDX), R(ABI_PARAM1));
|
||||
MOV(size, MComplex(RAX, RSI, 1, 0), R(EDX));
|
||||
} else {
|
||||
MOV(size, MComplex(RAX, RSI, 1, 0), R(ABI_PARAM1));
|
||||
}
|
||||
ADD(64, R(RSI), Imm8(size >> 3));
|
||||
MOV(64, M(&GPFifo::m_gatherPipeCount), R(RSI));
|
||||
if (size != 32)
|
||||
POP(EDX);
|
||||
POP(RSI);
|
||||
RET();
|
||||
}
|
||||
void CommonAsmRoutines::GenFifoFloatWrite()
|
||||
{
|
||||
// Assume value in XMM0
|
||||
PUSH(RSI);
|
||||
PUSH(EDX);
|
||||
MOVSS(M(&temp32), XMM0);
|
||||
MOV(32, R(EDX), M(&temp32));
|
||||
BSWAP(32, EDX);
|
||||
MOV(64, R(RAX), Imm64((u64)GPFifo::m_gatherPipe));
|
||||
MOV(64, R(RSI), M(&GPFifo::m_gatherPipeCount));
|
||||
MOV(32, MComplex(RAX, RSI, 1, 0), R(EDX));
|
||||
ADD(64, R(RSI), Imm8(4));
|
||||
MOV(64, M(&GPFifo::m_gatherPipeCount), R(RSI));
|
||||
POP(EDX);
|
||||
POP(RSI);
|
||||
RET();
|
||||
}
|
||||
|
||||
void CommonAsmRoutines::GenFifoXmm64Write()
|
||||
{
|
||||
// Assume value in XMM0. Assume pre-byteswapped (unlike the others here!)
|
||||
PUSH(RSI);
|
||||
MOV(64, R(RAX), Imm32((u64)GPFifo::m_gatherPipe));
|
||||
MOV(64, R(RSI), M(&GPFifo::m_gatherPipeCount));
|
||||
MOVQ_xmm(MComplex(RAX, RSI, 1, 0), XMM0);
|
||||
ADD(64, R(RSI), Imm8(8));
|
||||
MOV(64, M(&GPFifo::m_gatherPipeCount), R(RSI));
|
||||
POP(RSI);
|
||||
RET();
|
||||
}
|
||||
#else
|
||||
void CommonAsmRoutines::GenFifoWrite(int size)
|
||||
{
|
||||
// Assume value in ABI_PARAM1
|
||||
|
@ -116,6 +60,8 @@ void CommonAsmRoutines::GenFifoWrite(int size)
|
|||
}
|
||||
void CommonAsmRoutines::GenFifoFloatWrite()
|
||||
{
|
||||
int temp32;
|
||||
|
||||
// Assume value in XMM0
|
||||
PUSH(ESI);
|
||||
PUSH(EDX);
|
||||
|
@ -143,8 +89,6 @@ void CommonAsmRoutines::GenFifoXmm64Write()
|
|||
POP(ESI);
|
||||
RET();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Safe + Fast Quantizers, originally from JITIL by magumagu
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@ libs = [
|
|||
'inputcommon', 'common', 'lua', 'z', 'sfml-network',
|
||||
]
|
||||
|
||||
wxlibs = [ ]
|
||||
|
||||
ldflags = [ ]
|
||||
|
||||
if env['HAVE_WX']:
|
||||
files += [
|
||||
'AboutDolphin.cpp',
|
||||
|
@ -46,7 +50,7 @@ if env['HAVE_WX']:
|
|||
'WxUtils.cpp',
|
||||
]
|
||||
|
||||
wxlibs = [ 'debwx', 'debugger_ui_util', 'inputuicommon' ]
|
||||
wxlibs += [ 'debwx', 'debugger_ui_util', 'inputuicommon' ]
|
||||
else:
|
||||
files += [
|
||||
'MainNoGUI.cpp',
|
||||
|
@ -57,14 +61,15 @@ if sys.platform == 'win32':
|
|||
files += [ "stdafx.cpp" ]
|
||||
elif sys.platform == 'darwin' and not env['HAVE_WX']:
|
||||
files += [ 'cocoaApp.m' ]
|
||||
ldflags += [ '-Wl,-pagezero_size,0x1000' ]
|
||||
exeNoGUI = '#' + env['prefix'] + '/DolphinNoGUI'
|
||||
elif sys.platform == 'darwin' and env['HAVE_WX']:
|
||||
wxlibs += env['wxconfiglibs']
|
||||
ldflags += [ '-Wl,-pagezero_size,0x1000' ]
|
||||
exeGUI = '#' + env['prefix'] + '/Dolphin.app/Contents/MacOS/Dolphin'
|
||||
|
||||
env.Install('#' + env['prefix'] + '/Dolphin.app/Contents/' +
|
||||
'Library/Frameworks/Cg.framework',
|
||||
'#Externals/Cg/Cg.framework/Cg')
|
||||
'Library/Frameworks', '#Externals/Cg/Cg.framework')
|
||||
|
||||
env.Install(env['data_dir'], '#Data/Sys')
|
||||
env.Install(env['data_dir'], '#Data/User')
|
||||
|
@ -104,7 +109,10 @@ else:
|
|||
env.InstallAs(env['data_dir'] + '/sys', '#Data/Sys')
|
||||
env.InstallAs(env['data_dir'] + '/user', '#Data/User')
|
||||
|
||||
libs = wxlibs + libs + env['LIBS']
|
||||
linkflags = ldflags + env['LINKFLAGS']
|
||||
|
||||
if env['HAVE_WX']:
|
||||
env.Program(exeGUI, files, LIBS = wxlibs + libs + env['LIBS'])
|
||||
env.Program(exeGUI, files, LIBS = libs, LINKFLAGS = linkflags)
|
||||
else:
|
||||
env.Program(exeNoGUI, files, LIBS = libs + env['LIBS'])
|
||||
env.Program(exeNoGUI, files, LIBS = libs, LINKFLAGS = linkflags)
|
||||
|
|
|
@ -31,15 +31,17 @@ files = [
|
|||
'VertexFormatConverter.cpp',
|
||||
'VertexLoader.cpp',
|
||||
'VideoConfig.cpp',
|
||||
'VideoConfigDialog.cpp',
|
||||
'XFMemLoader.cpp',
|
||||
]
|
||||
|
||||
libs = [ 'videocommon', 'GLEW', 'SOIL', 'common' ]
|
||||
if env['HAVE_WX']:
|
||||
files += [ 'VideoConfigDialog.cpp' ]
|
||||
|
||||
if sys.platform == 'darwin' and not env['HAVE_WX']:
|
||||
files += [ 'cocoaGL.m' ]
|
||||
elif sys.platform == 'win32':
|
||||
files += [ 'Win32.cpp' ]
|
||||
|
||||
libs = [ 'videocommon', 'GLEW', 'SOIL', 'common' ]
|
||||
|
||||
env.SharedLibrary(env['plugin_dir'] + name, files, LIBS = env['LIBS'] + libs)
|
||||
|
|
Loading…
Reference in New Issue