u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena *arena) { u32 total_mem = 0; int base_attempts = 0; for (int i = 0; i < num_views; i++) { SKIP(flags, views[i].flags); if ((views[i].flags & MV_MIRROR_PREVIOUS) == 0) total_mem += views[i].size; } // Grab some pagefile backed memory out of the void ... arena->GrabLowMemSpace(total_mem); // Now, create views in high memory where there's plenty of space. #ifdef _M_X64 u8 *base = MemArena::Find4GBBase(); // This really shouldn't fail - in 64-bit, there will always be enough // address space. if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); exit(0); return 0; } #else #ifdef _WIN32 // Try a whole range of possible bases. Return once we got a valid one. u32 max_base_addr = 0x7FFF0000 - 0x31000000; u8 *base = NULL; for (u32 base_addr = 0x40000; base_addr < max_base_addr; base_addr += 0x40000) { base_attempts++; base = (u8 *)base_addr; if (Memory_TryBase(base, views, num_views, flags, arena)) { INFO_LOG(MEMMAP, "Found valid memory base at %p after %i tries.", base, base_attempts); base_attempts = 0; break; } } #else // Linux32 is fine with the x64 method, although limited to 32-bit with no automirrors. u8 *base = MemArena::Find4GBBase(); if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); exit(0); return 0; } #endif #endif if (base_attempts) PanicAlert("No possible memory base pointer found!"); return base; }
bool MemoryMap_Setup(u32 flags) { #if PPSSPP_PLATFORM(UWP) // We reserve the memory, then simply commit in TryBase. base = (u8*)VirtualAllocFromApp(0, 0x10000000, MEM_RESERVE, PAGE_READWRITE); #else // Figure out how much memory we need to allocate in total. size_t total_mem = 0; for (int i = 0; i < num_views; i++) { if (views[i].size == 0) continue; SKIP(flags, views[i].flags); if (!CanIgnoreView(views[i])) total_mem += g_arena.roundup(views[i].size); } // Grab some pagefile backed memory out of the void ... g_arena.GrabLowMemSpace(total_mem); #endif #if !PPSSPP_PLATFORM(ANDROID) if (g_arena.NeedsProbing()) { int base_attempts = 0; #if defined(_WIN32) && PPSSPP_ARCH(32BIT) // Try a whole range of possible bases. Return once we got a valid one. uintptr_t max_base_addr = 0x7FFF0000 - 0x10000000; uintptr_t min_base_addr = 0x01000000; uintptr_t stride = 0x400000; #else // iOS uintptr_t max_base_addr = 0x1FFFF0000ULL - 0x80000000ULL; uintptr_t min_base_addr = 0x100000000ULL; uintptr_t stride = 0x800000; #endif for (uintptr_t base_addr = min_base_addr; base_addr < max_base_addr; base_addr += stride) { base_attempts++; base = (u8 *)base_addr; if (Memory_TryBase(flags)) { INFO_LOG(MEMMAP, "Found valid memory base at %p after %i tries.", base, base_attempts); return true; } } ERROR_LOG(MEMMAP, "MemoryMap_Setup: Failed finding a memory base."); PanicAlert("MemoryMap_Setup: Failed finding a memory base."); return false; } else #endif { #if !PPSSPP_PLATFORM(UWP) base = g_arena.Find4GBBase(); #endif } // Should return true... return Memory_TryBase(flags); }
u8 *MemoryMap_Setup(const MemoryView *views, int num_views, u32 flags, MemArena *arena) { u32 total_mem = 0; int base_attempts = 0; for (int i = 0; i < num_views; i++) { SKIP(flags, views[i].flags); if ((views[i].flags & MV_MIRROR_PREVIOUS) == 0) total_mem += views[i].size; } // Grab some pagefile backed memory out of the void ... arena->GrabLowMemSpace(total_mem); // Now, create views in high memory where there's plenty of space. #if _ARCH_64 u8 *base = MemArena::Find4GBBase(); // This really shouldn't fail - in 64-bit, there will always be enough // address space. if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); exit(0); return nullptr; } #else // Linux32 is fine with the x64 method, although limited to 32-bit with no automirrors. u8 *base = MemArena::Find4GBBase(); if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); exit(0); return 0; } #endif if (base_attempts) PanicAlert("No possible memory base pointer found!"); return base; }
u8 *MemoryMap_Setup(MemoryView *views, int num_views, u32 flags, MemArena *arena) { u32 total_mem = MemoryMap_InitializeViews(views, num_views, flags); arena->GrabSHMSegment(total_mem); // Now, create views in high memory where there's plenty of space. u8 *base = MemArena::FindMemoryBase(); // This really shouldn't fail - in 64-bit, there will always be enough // address space. if (!Memory_TryBase(base, views, num_views, flags, arena)) { PanicAlert("MemoryMap_Setup: Failed finding a memory base."); exit(0); return nullptr; } return base; }
void MemoryMap_Setup(u32 flags) { // Find a base to reserve 256MB #if defined(_XBOX) base = (u8*)VirtualAlloc(0, 0x10000000, MEM_RESERVE|MEM_LARGE_PAGES, PAGE_READWRITE); #elif defined(__SYMBIAN32__) memmap = new RChunk(); memmap->CreateDisconnectedLocal(0 , 0, 0x10000000); base = memmap->Base(); #else size_t total_mem = 0; for (int i = 0; i < num_views; i++) { if (views[i].size == 0) continue; SKIP(flags, views[i].flags); if (!CanIgnoreView(views[i])) total_mem += g_arena.roundup(views[i].size); } // Grab some pagefile backed memory out of the void ... g_arena.GrabLowMemSpace(total_mem); // 32-bit Windows retrieves base a different way #if defined(_M_X64) || !defined(_WIN32) // This really shouldn't fail - in 64-bit, there will always be enough address space. // Linux32 is fine with the x64 method, although limited to 32-bit with no automirrors. base = MemArena::Find4GBBase(); #endif #endif // Now, create views in high memory where there's plenty of space. #if defined(_WIN32) && !defined(_M_X64) && !defined(_XBOX) // Try a whole range of possible bases. Return once we got a valid one. int base_attempts = 0; u32 max_base_addr = 0x7FFF0000 - 0x10000000; for (u32 base_addr = 0x01000000; base_addr < max_base_addr; base_addr += 0x400000) { base_attempts++; base = (u8 *)base_addr; if (Memory_TryBase(flags)) { INFO_LOG(MEMMAP, "Found valid memory base at %p after %i tries.", base, base_attempts); base_attempts = 0; break; } } if (base_attempts) PanicAlert("No possible memory base pointer found!"); #else // Try base we retrieved earlier if (!Memory_TryBase(flags)) { ERROR_LOG(MEMMAP, "MemoryMap_Setup: Failed finding a memory base."); PanicAlert("MemoryMap_Setup: Failed finding a memory base."); } #endif return; }