Merge pull request #396 from kayru/opt_icache_invalidation

JIT: Optimized iCache invalidation
This commit is contained in:
Pierre Bourdon 2014-05-23 22:25:58 +02:00
commit c6b7b4c790
2 changed files with 9 additions and 29 deletions

View File

@ -108,7 +108,10 @@ using namespace Gen;
} }
links_to.clear(); links_to.clear();
block_map.clear(); block_map.clear();
valid_block.reset();
valid_block.clear();
valid_block.resize(VALID_BLOCK_MASK_SIZE, false);
num_blocks = 0; num_blocks = 0;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS); 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* // Optimize the common case of length == 32 which is used by Interpreter::dcb*
bool destroy_block = true; bool destroy_block = true;
if (length == 32) if (length == 32)
{ {
if (!valid_block[pAddr / 32]) if (!valid_block[pAddr / 32])
destroy_block = false; destroy_block = false;
else else
@ -362,7 +365,7 @@ using namespace Gen;
{ {
std::map<pair<u32,u32>, u32>::iterator it1 = block_map.lower_bound(std::make_pair(pAddr, 0)), it2 = it1; std::map<pair<u32,u32>, u32>::iterator it1 = block_map.lower_bound(std::make_pair(pAddr, 0)), it2 = it1;
while (it2 != block_map.end() && it2->first.second < pAddr + length) while (it2 != block_map.end() && it2->first.second < pAddr + length)
{ {
JitBlock &b = blocks[it2->second]; JitBlock &b = blocks[it2->second];
*GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD; *GetICachePtr(b.originalAddress) = JIT_ICACHE_INVALID_WORD;
DestroyBlock(it2->second, true); DestroyBlock(it2->second, true);
@ -373,30 +376,6 @@ using namespace Gen;
block_map.erase(it1, it2); 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) void JitBlockCache::WriteLinkBlock(u8* location, const u8* address)
{ {

View File

@ -72,10 +72,11 @@ class JitBaseBlockCache
int num_blocks; int num_blocks;
std::multimap<u32, int> links_to; std::multimap<u32, int> links_to;
std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number std::map<std::pair<u32,u32>, u32> block_map; // (end_addr, start_addr) -> number
std::bitset<0x20000000 / 32> valid_block; std::vector<bool> valid_block;
enum 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; bool RangeIntersect(int s1, int e1, int s2, int e2) const;