From de1e2127dca770c5256497bd56bb72f135df47b6 Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Fri, 23 May 2014 20:32:00 +0200 Subject: [PATCH 1/3] JIT: JitBaseBlockCache::valid_block is now std::vector This was previously a std::bitset, which resulted in generation of suboptimal code by VS2013 compiler. See https://gist.github.com/kayru/753db9607d680e26194b --- Source/Core/Core/PowerPC/JitCommon/JitCache.cpp | 9 ++++++--- Source/Core/Core/PowerPC/JitCommon/JitCache.h | 5 +++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp index 49ffa7c69b..30856fb48f 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp @@ -108,7 +108,10 @@ using namespace Gen; } links_to.clear(); block_map.clear(); - valid_block.reset(); + + valid_block.clear(); + valid_block.resize(VALID_BLOCK_MASK_SIZE, false); + num_blocks = 0; memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS); } @@ -349,7 +352,7 @@ using namespace Gen; // Optimize the common case of length == 32 which is used by Interpreter::dcb* bool destroy_block = true; if (length == 32) - { + { if (!valid_block[pAddr / 32]) destroy_block = false; else @@ -362,7 +365,7 @@ using namespace Gen; { std::map, u32>::iterator it1 = block_map.lower_bound(std::make_pair(pAddr, 0)), it2 = it1; while (it2 != block_map.end() && it2->first.second < pAddr + length) - { + { JitBlock &b = blocks[it2->second]; *GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD; DestroyBlock(it2->second, true); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h index 968cdaf142..0837dd371a 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h @@ -72,10 +72,11 @@ class JitBaseBlockCache int num_blocks; std::multimap links_to; std::map, u32> block_map; // (end_addr, start_addr) -> number - std::bitset<0x20000000 / 32> valid_block; + std::vector valid_block; enum { - MAX_NUM_BLOCKS = 65536*2 + MAX_NUM_BLOCKS = 65536*2, + VALID_BLOCK_MASK_SIZE = 0x20000000 / 32, }; bool RangeIntersect(int s1, int e1, int s2, int e2) const; From d08abfc14e857c236043ff8414ea48499c4904cf Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Fri, 23 May 2014 20:40:29 +0200 Subject: [PATCH 2/3] JIT: JitBaseBlockCache::InvalidateICache no longer memsets iCache memory to INVALID_BYTE. This is redundant, since we reset the valid_block bits any way. However, this was a source of a significant performance issues in some games. In particular, Metal Gear Solid: Twin Snakes. --- .../Core/Core/PowerPC/JitCommon/JitCache.cpp | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp index 30856fb48f..c4cb493a78 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp @@ -376,30 +376,6 @@ using namespace Gen; block_map.erase(it1, it2); } } - - // invalidate iCache. - // icbi can be called with any address, so we should check - if ((address & ~JIT_ICACHE_MASK) != 0x80000000 && (address & ~JIT_ICACHE_MASK) != 0x00000000 && - (address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area - (address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (address & ~JIT_ICACHEEX_MASK) != 0x10000000) - { - return; - } - if (address & JIT_ICACHE_VMEM_BIT) - { - u32 cacheaddr = address & JIT_ICACHE_MASK; - memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, length); - } - else if (address & JIT_ICACHE_EXRAM_BIT) - { - u32 cacheaddr = address & JIT_ICACHEEX_MASK; - memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, length); - } - else - { - u32 cacheaddr = address & JIT_ICACHE_MASK; - memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, length); - } } void JitBlockCache::WriteLinkBlock(u8* location, const u8* address) { From ac75766c250f4aa2855155ed738bbd79a2858d70 Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Fri, 23 May 2014 21:14:48 +0200 Subject: [PATCH 3/3] removed trailing whitespace --- Source/Core/Core/PowerPC/JitCommon/JitCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp index c4cb493a78..71143fc955 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp @@ -108,7 +108,7 @@ using namespace Gen; } links_to.clear(); block_map.clear(); - + valid_block.clear(); valid_block.resize(VALID_BLOCK_MASK_SIZE, false);