diff --git a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp index bc764db668..7831f734e0 100644 --- a/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/Jit64/JitAsm.cpp @@ -99,7 +99,7 @@ void Jit64AsmRoutineManager::Generate() no_mem = J_CC(CC_NZ); } AND(32, R(RSCRATCH), Imm32(JIT_ICACHE_MASK)); - MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCache)); + MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCache.data())); MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0)); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii || SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU || SConfig::GetInstance().m_LocalCoreStartupParameter.bTLBHack) @@ -112,7 +112,7 @@ void Jit64AsmRoutineManager::Generate() TEST(32, R(RSCRATCH), Imm32(JIT_ICACHE_VMEM_BIT)); FixupBranch no_vmem = J_CC(CC_Z); AND(32, R(RSCRATCH), Imm32(JIT_ICACHE_MASK)); - MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheVMEM)); + MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheVMEM.data())); MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0)); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) exit_vmem = J(); @@ -123,7 +123,7 @@ void Jit64AsmRoutineManager::Generate() TEST(32, R(RSCRATCH), Imm32(JIT_ICACHE_EXRAM_BIT)); FixupBranch no_exram = J_CC(CC_Z); AND(32, R(RSCRATCH), Imm32(JIT_ICACHEEX_MASK)); - MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheEx)); + MOV(64, R(RSCRATCH2), Imm64((u64)jit->GetBlockCache()->iCacheEx.data())); MOV(32, R(RSCRATCH), MComplex(RSCRATCH2, RSCRATCH, SCALE_1, 0)); SetJumpTarget(no_exram); diff --git a/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp index 2ae8edba21..60fa7199c2 100644 --- a/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm32/JitAsm.cpp @@ -116,7 +116,7 @@ void JitArmAsmRoutineManager::Generate() Operand2 iCacheMask = Operand2(0xE, 2); // JIT_ICACHE_MASK BIC(R12, R12, iCacheMask); // R12 contains PC & JIT_ICACHE_MASK here. - MOVI2R(R14, (u32)jit->GetBlockCache()->iCache); + MOVI2R(R14, (u32)jit->GetBlockCache()->iCache.data()); LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here // R12 Confirmed this is the correct iCache Location loaded. diff --git a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp index 2b5e4a5982..ee36b50e63 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp @@ -31,7 +31,7 @@ void JitArm64AsmRoutineManager::Generate() LDR(INDEX_UNSIGNED, W28, X29, PPCSTATE_OFF(pc)); // Load the current PC into W28 BFM(W28, WSP, 3, 2); // Wipe the top 3 bits. Same as PC & JIT_ICACHE_MASK - MOVI2R(X27, (u64)jit->GetBlockCache()->iCache); + MOVI2R(X27, (u64)jit->GetBlockCache()->iCache.data()); LDR(W27, X27, X28); FixupBranch JitBlock = TBNZ(W27, 7); // Test the 7th bit diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp index c577ddaf3d..08bbb1474d 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp @@ -41,47 +41,27 @@ using namespace Gen; void JitBaseBlockCache::Init() { + if (m_initialized) + { + PanicAlert("JitBaseBlockCache::Init() - iCache is already initialized"); + return; + } + #if defined USE_OPROFILE && USE_OPROFILE agent = op_open_agent(); #endif - blocks = new JitBlock[MAX_NUM_BLOCKS]; - blockCodePointers = new const u8*[MAX_NUM_BLOCKS]; - if (iCache == nullptr && iCacheEx == nullptr && iCacheVMEM == nullptr) - { - iCache = new u8[JIT_ICACHE_SIZE]; - iCacheEx = new u8[JIT_ICACHEEX_SIZE]; - iCacheVMEM = new u8[JIT_ICACHE_SIZE]; - } - else - { - PanicAlert("JitBaseBlockCache::Init() - iCache is already initialized"); - } - if (iCache == nullptr || iCacheEx == nullptr || iCacheVMEM == nullptr) - { - PanicAlert("JitBaseBlockCache::Init() - unable to allocate iCache"); - } - memset(iCache, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE); - memset(iCacheEx, JIT_ICACHE_INVALID_BYTE, JIT_ICACHEEX_SIZE); - memset(iCacheVMEM, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE); + iCache.fill(JIT_ICACHE_INVALID_BYTE); + iCacheEx.fill(JIT_ICACHE_INVALID_BYTE); + iCacheVMEM.fill(JIT_ICACHE_INVALID_BYTE); Clear(); + + m_initialized = true; } void JitBaseBlockCache::Shutdown() { - delete[] blocks; - delete[] blockCodePointers; - if (iCache != nullptr) - delete[] iCache; - iCache = nullptr; - if (iCacheEx != nullptr) - delete[] iCacheEx; - iCacheEx = nullptr; - if (iCacheVMEM != nullptr) - delete[] iCacheVMEM; - iCacheVMEM = nullptr; - blocks = nullptr; - blockCodePointers = nullptr; num_blocks = 0; + m_initialized = false; #if defined USE_OPROFILE && USE_OPROFILE op_close_agent(agent); #endif @@ -112,7 +92,7 @@ using namespace Gen; valid_block.ClearAll(); num_blocks = 0; - memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS); + blockCodePointers.fill(nullptr); } void JitBaseBlockCache::Reset() @@ -203,31 +183,31 @@ using namespace Gen; const u8 **JitBaseBlockCache::GetCodePointers() { - return blockCodePointers; + return blockCodePointers.data(); } u32* JitBaseBlockCache::GetICachePtr(u32 addr) { if (addr & JIT_ICACHE_VMEM_BIT) - return (u32*)(jit->GetBlockCache()->iCacheVMEM + (addr & JIT_ICACHE_MASK)); + return (u32*)(&jit->GetBlockCache()->iCacheVMEM[addr & JIT_ICACHE_MASK]); else if (addr & JIT_ICACHE_EXRAM_BIT) - return (u32*)(jit->GetBlockCache()->iCacheEx + (addr & JIT_ICACHEEX_MASK)); + return (u32*)(&jit->GetBlockCache()->iCacheEx[addr & JIT_ICACHEEX_MASK]); else - return (u32*)(jit->GetBlockCache()->iCache + (addr & JIT_ICACHE_MASK)); + return (u32*)(&jit->GetBlockCache()->iCache[addr & JIT_ICACHE_MASK]); } int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr) { - if (!blocks) - return -1; - u32 inst; - inst = *GetICachePtr(addr); + u32 inst = *GetICachePtr(addr); if (inst & 0xfc000000) // definitely not a JIT block return -1; + if ((int)inst >= num_blocks) return -1; + if (blocks[inst].originalAddress != addr) return -1; + return inst; } diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h index 9cc25b85bc..c8049295e3 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -106,17 +107,19 @@ public: class JitBaseBlockCache { - const u8 **blockCodePointers; - JitBlock *blocks; + enum + { + MAX_NUM_BLOCKS = 65536 * 2, + }; + + std::array blockCodePointers; + std::array blocks; int num_blocks; std::multimap links_to; std::map, u32> block_map; // (end_addr, start_addr) -> number ValidBlockBitSet valid_block; - enum - { - MAX_NUM_BLOCKS = 65536*2, - }; + bool m_initialized; bool RangeIntersect(int s1, int e1, int s2, int e2) const; void LinkBlockExits(int i); @@ -128,9 +131,7 @@ class JitBaseBlockCache virtual void WriteDestroyBlock(const u8* location, u32 address) = 0; public: - JitBaseBlockCache() : - blockCodePointers(nullptr), blocks(nullptr), num_blocks(0), - iCache(nullptr), iCacheEx(nullptr), iCacheVMEM(nullptr) + JitBaseBlockCache() : num_blocks(0), m_initialized(false) { } @@ -148,9 +149,9 @@ public: JitBlock *GetBlock(int block_num); int GetNumBlocks() const; const u8 **GetCodePointers(); - u8 *iCache; - u8 *iCacheEx; - u8 *iCacheVMEM; + std::array iCache; + std::array iCacheEx; + std::array iCacheVMEM; u32* GetICachePtr(u32 addr);