From ed7118531b8edfd6d7783dc2b76bdfe43308289b Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 8 Jan 2026 22:45:20 +0000 Subject: [PATCH] fix alloc failures --- src/common/virtual_buffer.cpp | 43 +++++++++++++++---- src/core/arm/dynarmic/arm_dynarmic_32.cpp | 8 +++- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 8 +++- .../src/dynarmic/backend/x64/a32_emit_x64.h | 6 +++ .../src/dynarmic/backend/x64/a64_emit_x64.h | 5 +++ 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/common/virtual_buffer.cpp b/src/common/virtual_buffer.cpp index a4ccd84d38..407bf2e157 100644 --- a/src/common/virtual_buffer.cpp +++ b/src/common/virtual_buffer.cpp @@ -13,6 +13,7 @@ #ifdef __OPENORBIS__ #include #include +#include #include #include typedef void (*SceKernelExceptionHandler)(int32_t, void*); @@ -107,15 +108,19 @@ static boost::container::static_vector, 16> swap_region extern "C" int sceKernelRemoveExceptionHandler(s32 sig_num); static void SwapHandler(int sig, void* raw_context) { auto& mctx = ((Orbis::Ucontext*)raw_context)->uc_mcontext; - if (std::ranges::find_if(swap_regions, [addr = mctx.mc_addr](auto const& e) { + if (auto const it = std::ranges::find_if(swap_regions, [addr = mctx.mc_addr](auto const& e) { return uintptr_t(addr) >= uintptr_t(e.first) && uintptr_t(addr) < uintptr_t(e.first) + e.second; - }) != swap_regions.end()) { - size_t const page_size = 4096; - size_t const page_mask = ~0xfff; + }); it != swap_regions.end()) { + size_t const page_size = 4096 * 8; + size_t const page_mask = ~(page_size - 1); // should replace the existing mapping... ugh void* aligned_addr = reinterpret_cast(uintptr_t(mctx.mc_addr) & page_mask); void* res = mmap(aligned_addr, page_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); - ASSERT(res != MAP_FAILED); + if (res == MAP_FAILED) { + LOG_ERROR(HW_Memory, "FAIL mapped addr {},{} @ {}:{}", mctx.mc_addr, aligned_addr, it->first, it->second); + } else { + LOG_INFO(HW_Memory, "OK mapped addr {},{} @ {}:{}", mctx.mc_addr, aligned_addr, it->first, it->second); + } } else { LOG_ERROR(HW_Memory, "fault in addr {:#x} at {:#x}", mctx.mc_addr, mctx.mc_rip); // print caller address sceKernelRemoveExceptionHandler(SIGSEGV); // to not catch the next signal @@ -128,14 +133,36 @@ void InitSwap() noexcept { void InitSwap() noexcept {} #endif +static const char *swapfile_names[] { + "/data/eden/games/swap0.bin", + "/data/eden/games/swap1.bin", + "/data/eden/games/swap2.bin", + "/data/eden/games/swap3.bin", + "/data/eden/games/swap4.bin" +}; +static size_t swapfile_count = 0; + void* AllocateMemoryPages(std::size_t size) noexcept { #ifdef _WIN32 void* addr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); ASSERT(addr != nullptr); #elif defined(__OPENORBIS__) - void* addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_VOID | MAP_PRIVATE, -1, 0); - ASSERT(addr != MAP_FAILED); - swap_regions.emplace_back(addr, size); + void* addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + if (addr == MAP_FAILED) { + LOG_WARNING(HW_Memory, "failed to mmap({} bytes) using swapfile {}", size, swapfile_names[swapfile_count]); + // int fd = open(swapfile_names[swapfile_count], O_TRUNC | O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + // ASSERT(fd > 0); + // ftruncate(fd, size); + // addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + // ASSERT(addr != MAP_FAILED); + // ++swapfile_count; + + addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_VOID | MAP_PRIVATE, -1, 0); + ASSERT(addr != MAP_FAILED); + swap_regions.emplace_back(addr, size); + } else { + LOG_INFO(HW_Memory, "mmap {} bytes", size); + } #else void* addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); ASSERT(addr != MAP_FAILED); diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 436a057a1e..3bfddcb80c 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -203,7 +203,9 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) { config.enable_cycle_counting = !m_uses_wall_clock; // Code cache size -#if defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) +#if defined(__OPENORBIS__) + config.code_cache_size = std::uint32_t(32_MiB); +#elif defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) config.code_cache_size = std::uint32_t(128_MiB); #else config.code_cache_size = std::uint32_t(512_MiB); @@ -305,6 +307,10 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) { default: break; } +#ifdef __OPENORBIS__ + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; +#endif m_jit.emplace(config); } diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 92e1a70458..f0bc4a7f1e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -254,7 +254,9 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s config.enable_cycle_counting = !m_uses_wall_clock; // Code cache size -#if defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) +#if defined(__OPENORBIS__) + config.code_cache_size = std::uint32_t(32_MiB); +#elif defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) config.code_cache_size = std::uint32_t(128_MiB); #else config.code_cache_size = std::uint32_t(512_MiB); @@ -355,6 +357,10 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s default: break; } +#ifdef __OPENORBIS__ + config.unsafe_optimizations = false; + config.optimizations = Dynarmic::no_optimizations; +#endif m_jit.emplace(config); } diff --git a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.h b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.h index 5ec78ff50e..7b794b9289 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.h +++ b/src/dynarmic/src/dynarmic/backend/x64/a32_emit_x64.h @@ -66,8 +66,14 @@ public: const void* code_ptr = nullptr; }; static_assert(sizeof(FastDispatchEntry) == 0x10); +#ifdef __OPENORBIS__ + static constexpr u64 fast_dispatch_table_mask = 0xFF0; + static constexpr size_t fast_dispatch_table_size = 0x100; +#else static constexpr u64 fast_dispatch_table_mask = 0xFFFF0; static constexpr size_t fast_dispatch_table_size = 0x10000; +#endif + void ClearFastDispatchTable(); void GenFastmemFallbacks(); void GenTerminalHandlers(); diff --git a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.h b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.h index dd556e36ce..b0c0db5f83 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.h +++ b/src/dynarmic/src/dynarmic/backend/x64/a64_emit_x64.h @@ -59,8 +59,13 @@ public: const void* code_ptr = nullptr; }; static_assert(sizeof(FastDispatchEntry) == 0x10); +#ifdef __OPENORBIS__ + static constexpr u64 fast_dispatch_table_mask = 0xFF0; + static constexpr size_t fast_dispatch_table_size = 0x100; +#else static constexpr u64 fast_dispatch_table_mask = 0xFFFFF0; static constexpr size_t fast_dispatch_table_size = 0x100000; +#endif void ClearFastDispatchTable(); void GenMemory128Accessors();