diff --git a/CMakeLists.txt b/CMakeLists.txt index ff0e40b8c..1073d3bf4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1330,6 +1330,7 @@ if(NOT LIBRETRO) shell/android-studio/flycast/src/main/jni/src/android_keyboard.h) target_link_libraries(${PROJECT_NAME} PRIVATE android log) + target_link_options(${PROJECT_NAME} PRIVATE "-Wl,-z,max-page-size=16384") elseif(APPLE) string(TIMESTAMP YEAR "%Y") string(REGEX MATCH "^[^-]+" TAG_VERSION ${GIT_VERSION}) diff --git a/core/hw/mem/mem_watch.h b/core/hw/mem/mem_watch.h index 4d1be89ee..c1ae7ff1a 100644 --- a/core/hw/mem/mem_watch.h +++ b/core/hw/mem/mem_watch.h @@ -26,16 +26,14 @@ #include "hw/pvr/elan.h" #include "rend/TexCache.h" #include +#include namespace memwatch { struct Page { - Page() { - // don't initialize data - } - u8 data[PAGE_SIZE]; + std::unique_ptr data = std::make_unique(PAGE_SIZE); }; using PageMap = std::unordered_map; @@ -77,7 +75,7 @@ public: if (offset == (u32)-1) return false; offset &= ~PAGE_MASK; - auto rv = pages.emplace(offset, Page()); + auto rv = pages.try_emplace(offset); if (!rv.second) // already saved return true; diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 222cde7a9..601069d76 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -32,8 +32,9 @@ typedef std::map bm_Map; static bm_Set all_temp_blocks; static bm_List del_blocks; -bool unprotected_pages[RAM_SIZE_MAX/PAGE_SIZE]; -static std::set blocks_per_page[RAM_SIZE_MAX/PAGE_SIZE]; +static u32 pageCount; +bool *unprotected_pages; +static std::set *blocks_per_page; static bm_Map blkmap; // Stats @@ -302,10 +303,10 @@ void bm_ResetCache() // blkmap includes temp blocks as well all_temp_blocks.clear(); - for (auto& block_list : blocks_per_page) - block_list.clear(); + for (size_t i = 0; i < pageCount; i++) + blocks_per_page[i].clear(); - memset(unprotected_pages, 0, sizeof(unprotected_pages)); + memset(unprotected_pages, 0, pageCount); #ifdef DYNA_OPROF if (oprofHandle) @@ -337,6 +338,10 @@ void bm_ResetTempCache(bool full) void bm_Init() { + pageCount = RAM_SIZE_MAX / PAGE_SIZE; + unprotected_pages = new bool[pageCount]; + blocks_per_page = new std::set[pageCount]; + #ifdef DYNA_OPROF oprofHandle=op_open_agent(); if (oprofHandle==0) @@ -354,6 +359,8 @@ void bm_Term() oprofHandle=0; #endif bm_Reset(); + delete[] unprotected_pages; + delete[] blocks_per_page; } void bm_WriteBlockMap(const std::string& file) diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index fd6445f25..d72d18809 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -86,7 +86,7 @@ void bm_Term(); void bm_vmem_pagefill(void** ptr,u32 size_bytes); static inline bool bm_IsRamPageProtected(u32 addr) { - extern bool unprotected_pages[RAM_SIZE_MAX/PAGE_SIZE]; + extern bool *unprotected_pages; addr &= RAM_MASK; return !unprotected_pages[addr / PAGE_SIZE]; } diff --git a/core/hw/sh4/sh4_if.h b/core/hw/sh4/sh4_if.h index 217e53071..8cf249710 100644 --- a/core/hw/sh4/sh4_if.h +++ b/core/hw/sh4/sh4_if.h @@ -226,13 +226,13 @@ static_assert(sizeof(Sh4Context) == 512, "Invalid Sh4Context size"); // For other systems we could use PAGE_SIZE, except on windows that has a 64 KB granularity for memory mapping #define FPCB_PAD 64_KB #endif -struct alignas(PAGE_SIZE) Sh4RCB +struct Sh4RCB { void* fpcb[FPCB_SIZE]; u8 _pad[FPCB_PAD - sizeof(Sh4Context)]; Sh4Context cntx; }; -static_assert((sizeof(Sh4RCB) % PAGE_SIZE) == 0, "sizeof(Sh4RCB) not multiple of PAGE_SIZE"); +static_assert((sizeof(Sh4RCB) % MAX_PAGE_SIZE) == 0, "sizeof(Sh4RCB) not multiple of MAX_PAGE_SIZE"); extern Sh4RCB* p_sh4rcb; #define Sh4cntx (p_sh4rcb->cntx) diff --git a/core/linux/common.cpp b/core/linux/common.cpp index 76c3f0a75..69b647376 100644 --- a/core/linux/common.cpp +++ b/core/linux/common.cpp @@ -171,7 +171,7 @@ void common_linux_setup() signal(SIGINT, sigintHandler); #endif - DEBUG_LOG(BOOT, "Linux paging: %ld %08X %08X", sysconf(_SC_PAGESIZE), PAGE_SIZE, PAGE_MASK); + DEBUG_LOG(BOOT, "Linux paging: sysconf %ld PAGE_SIZE %ld PAGE_MASK %lX", sysconf(_SC_PAGESIZE), (unsigned long)PAGE_SIZE, (long)PAGE_MASK); verify(PAGE_MASK==(sysconf(_SC_PAGESIZE)-1)); } diff --git a/core/rend/TexCache.cpp b/core/rend/TexCache.cpp index f4d790d1e..fa0cac1aa 100644 --- a/core/rend/TexCache.cpp +++ b/core/rend/TexCache.cpp @@ -33,7 +33,12 @@ const std::array D_Adjust_LoD_Bias = { 0.f, -4.f, -2.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f }; -static std::vector VramLocks[VRAM_SIZE_MAX / PAGE_SIZE]; +static std::vector *VramLocks; + +static inline void initVramLocks() { + if (VramLocks == nullptr) + VramLocks = new std::vector[VRAM_SIZE_MAX / PAGE_SIZE]; +} //List functions // @@ -76,7 +81,7 @@ static std::mutex vramlist_lock; bool VramLockedWriteOffset(size_t offset) { - if (offset >= VRAM_SIZE) + if (offset >= VRAM_SIZE || VramLocks == nullptr) return false; size_t addr_hash = offset / PAGE_SIZE; @@ -292,6 +297,8 @@ bool BaseTextureCacheData::Delete() BaseTextureCacheData::BaseTextureCacheData(TSP tsp, TCW tcw) { + initVramLocks(); + if (tcw.VQ_Comp == 1 && tcw.MipMapped == 1) // Star Wars Demolition tcw.ScanOrder = 0; diff --git a/core/stdclass.cpp b/core/stdclass.cpp index 2147e7138..3e6b822c1 100644 --- a/core/stdclass.cpp +++ b/core/stdclass.cpp @@ -12,7 +12,9 @@ #include #ifdef _WIN32 - #include +#include +#elif defined(__ANDROID__) +#include #endif static std::string user_config_dir; @@ -205,6 +207,10 @@ void cResetEvent::Wait() state = false; } +#if defined(__ANDROID__) && (HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X64) +const unsigned long PAGE_SIZE = (unsigned long)sysconf(_SC_PAGESIZE); +#endif + void RamRegion::serialize(Serializer &ser) const { ser.serialize(data, size); } diff --git a/core/stdclass.h b/core/stdclass.h index 6a9092a34..ee3aa446f 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -13,17 +13,22 @@ #include #include -#ifdef __ANDROID__ -#include +#if defined(__ANDROID__) && (HOST_CPU == CPU_ARM64 || HOST_CPU == CPU_X64) #undef PAGE_MASK +#undef PAGE_SIZE +extern const unsigned long PAGE_SIZE; +#define MAX_PAGE_SIZE 16384ul #elif defined(__APPLE__) && defined(__aarch64__) -#define PAGE_SIZE 16384 +#define PAGE_SIZE 16384ul #elif !defined(PAGE_SIZE) -#define PAGE_SIZE 4096 +#define PAGE_SIZE 4096ul #endif #ifndef PAGE_MASK #define PAGE_MASK (PAGE_SIZE-1) #endif +#ifndef MAX_PAGE_SIZE +#define MAX_PAGE_SIZE PAGE_SIZE +#endif class cThread {