From d99c9fb2ff2bf22eee63d884ca031a5434d35f28 Mon Sep 17 00:00:00 2001 From: Sacha Date: Sun, 17 Feb 2013 15:23:56 +1000 Subject: [PATCH] Fix Symbian JIT + FastMem by using a mapped virtual address RChunk. --- Common/MemArena.cpp | 54 +++++++++++++++++++++------------------- Common/MemArena.h | 8 ++++++ Common/MemoryUtil.h | 5 ---- Core/MIPS/ARM/ArmAsm.cpp | 4 --- Core/MemMap.h | 4 +-- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/Common/MemArena.cpp b/Common/MemArena.cpp index dcb0c82e51..4fabb11237 100644 --- a/Common/MemArena.cpp +++ b/Common/MemArena.cpp @@ -131,8 +131,6 @@ void MemArena::GrabLowMemSpace(size_t size) ERROR_LOG(MEMMAP, "Failed to grab ashmem space of size: %08x errno: %d", (int)size, (int)(errno)); return; } -#elif defined(UNUSABLE_MMAP) - // Do nothing as we are using malloc() #else mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; fd = open(ram_temp_file.c_str(), O_RDWR | O_CREAT, mode); @@ -157,8 +155,9 @@ void MemArena::ReleaseSpace() #ifdef _WIN32 CloseHandle(hMemoryMapping); hMemoryMapping = 0; -#elif defined(UNUSABLE_MMAP) - // Do nothing as we are using malloc() +#elif defined(__SYMBIAN32__) + memmap->Close(); + delete memmap; #else close(fd); #endif @@ -170,20 +169,7 @@ void *MemArena::CreateView(s64 offset, size_t size, void *base) #ifdef _WIN32 size = roundup(size); void *ptr = MapViewOfFileEx(hMemoryMapping, FILE_MAP_ALL_ACCESS, 0, (DWORD)((u64)offset), size, base); - if (!ptr) { - //ERROR_LOG(MEMMAP, "Failed to map memory: %08x %08x %08x : %s", (u32)offset, (u32)size, (u32)base, GetLastErrorMsg()); - } else { - //ERROR_LOG(MEMMAP, "Mapped memory: %08x %08x %08x : %s", (u32)offset, (u32)size, (u32)base, GetLastErrorMsg()); - } return ptr; -#elif defined(UNUSABLE_MMAP) - void *retval = malloc(size); - if (!retval) - { - NOTICE_LOG(MEMMAP, "malloc failed: %s", strerror(errno)); - return 0; - } - return retval; #else void *retval = mmap(base, size, PROT_READ | PROT_WRITE, MAP_SHARED | ((base == 0) ? 0 : MAP_FIXED), fd, offset); @@ -202,14 +188,14 @@ void MemArena::ReleaseView(void* view, size_t size) { #ifdef _WIN32 UnmapViewOfFile(view); -#elif defined(UNUSABLE_MMAP) - free(view); +#elif defined(__SYMBIAN32__) + memmap->Decommit((int)view - (int)memmap->Base(), size); #else munmap(view, size); #endif } - +#ifndef __SYMBIAN32__ u8* MemArena::Find4GBBase() { #ifdef _M_X64 @@ -224,8 +210,8 @@ u8* MemArena::Find4GBBase() return reinterpret_cast(0x2300000000ULL); #endif -#else - // 32 bit +#else // 32 bit + #ifdef _WIN32 // The highest thing in any 1GB section of memory space is the locked cache. We only need to fit it. u8* base = (u8*)VirtualAlloc(0, 0x10000000, MEM_RESERVE, PAGE_READWRITE); @@ -233,9 +219,6 @@ u8* MemArena::Find4GBBase() VirtualFree(base, 0, MEM_RELEASE); } return base; -#elif defined(UNUSABLE_MMAP) - // We are unable to use relative addresses due to lack of mmap() - return NULL; #else void* base = mmap(0, 0x10000000, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0); @@ -248,6 +231,7 @@ u8* MemArena::Find4GBBase() #endif #endif } +#endif // yeah, this could also be done in like two bitwise ops... @@ -282,6 +266,12 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 if (view.flags & MV_MIRROR_PREVIOUS) { position = last_position; } else { +#ifdef __SYMBIAN32__ + *(view.out_ptr_low) = (u8*)((int)arena->memmap->Base() + view.virtual_address); + arena->memmap->Commit(view.virtual_address & 0x3FFFFFFF, view.size); + } + *(view.out_ptr) = (u8*)((int)arena->memmap->Base() + view.virtual_address & 0x3FFFFFFF); +#else *(view.out_ptr_low) = (u8*)arena->CreateView(position, view.size); if (!*view.out_ptr_low) goto bail; @@ -299,6 +289,8 @@ static bool Memory_TryBase(u8 *base, const MemoryView *views, int num_views, u32 if (!*view.out_ptr) goto bail; } +#endif + #endif last_position = position; position += roundup(view.size); @@ -344,7 +336,9 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena total_mem += roundup(views[i].size); } // Grab some pagefile backed memory out of the void ... +#ifndef __SYMBIAN32__ arena->GrabLowMemSpace(total_mem); +#endif // Now, create views in high memory where there's plenty of space. #ifdef _M_X64 @@ -374,6 +368,16 @@ u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena break; } } +#elif defined(__SYMBIAN32__) + arena->memmap = new RChunk(); + arena->memmap->CreateDisconnectedLocal(0 , 0, 0x10000000); + if (!Memory_TryBase(arena->memmap->Base(), views, num_views, flags, arena)) + { + PanicAlert("MemoryMap_Setup: Failed finding a memory base."); + exit(0); + return 0; + } + u8* base = arena->memmap->Base(); #else // Linux32 is fine with the x64 method, although limited to 32-bit with no automirrors. u8 *base = MemArena::Find4GBBase(); diff --git a/Common/MemArena.h b/Common/MemArena.h index 75dd738b0e..a12f8f493b 100644 --- a/Common/MemArena.h +++ b/Common/MemArena.h @@ -22,6 +22,10 @@ #include #endif +#ifdef __SYMBIAN32__ +#include +#endif + #include "Common.h" // This class lets you create a block of anonymous RAM, and then arbitrarily map views into it. @@ -36,8 +40,12 @@ public: void *CreateView(s64 offset, size_t size, void *base = 0); void ReleaseView(void *view, size_t size); +#ifdef __SYMBIAN32__ + RChunk* memmap; +#else // This only finds 1 GB in 32-bit static u8 *Find4GBBase(); +#endif private: #ifdef _WIN32 diff --git a/Common/MemoryUtil.h b/Common/MemoryUtil.h index f8c6ee6b1a..bafa7e4e88 100644 --- a/Common/MemoryUtil.h +++ b/Common/MemoryUtil.h @@ -23,11 +23,6 @@ #endif #include -#if defined(__SYMBIAN32__) - // Also Xbox 360 - #define UNUSABLE_MMAP 1 -#endif - void* AllocateExecutableMemory(size_t size, bool low = true); void* AllocateMemoryPages(size_t size); void FreeMemoryPages(void* ptr, size_t size); diff --git a/Core/MIPS/ARM/ArmAsm.cpp b/Core/MIPS/ARM/ArmAsm.cpp index 9a1ad4bc82..d7d1e4b907 100644 --- a/Core/MIPS/ARM/ArmAsm.cpp +++ b/Core/MIPS/ARM/ArmAsm.cpp @@ -113,11 +113,7 @@ void Jit::GenerateFixedCode() // * downcount // * R2-R4 // Really starting to run low on registers already though... -#ifdef UNUSABLE_MMAP - MOVI2R(R11, (u32)Memory::m_pRAM - 0x08000000); -#else MOVI2R(R11, (u32)Memory::base); -#endif MOVI2R(R10, (u32)mips_); MOVI2R(R9, (u32)GetBlockCache()->GetCodePointers()); diff --git a/Core/MemMap.h b/Core/MemMap.h index bf77692018..a7731d839f 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -36,9 +36,9 @@ #if defined(_DEBUG) //#define SAFE_MEMORY #endif -// Required for UNUSABLE_MMAP. Can define this in cmake instead later + #ifdef __SYMBIAN32__ -#define SAFE_MEMORY +//#define SAFE_MEMORY #endif