JitCache: Track the ICache entry of jit blocks.

This guarantees that no invalidated jit block is still in the icache.
This commit is contained in:
degasus 2017-01-12 09:56:05 +01:00
parent c9c5437cb8
commit 352909fc4c
2 changed files with 23 additions and 8 deletions

View File

@ -118,6 +118,7 @@ JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address)
b.physicalAddress = PowerPC::JitCache_TranslateAddress(em_address).address; b.physicalAddress = PowerPC::JitCache_TranslateAddress(em_address).address;
b.msrBits = MSR & JitBlock::JIT_CACHE_MSR_MASK; b.msrBits = MSR & JitBlock::JIT_CACHE_MSR_MASK;
b.linkData.clear(); b.linkData.clear();
b.in_icache = 0;
num_blocks++; // commit the current block num_blocks++; // commit the current block
return &b; return &b;
} }
@ -136,7 +137,9 @@ void JitBaseBlockCache::FinalizeBlock(JitBlock& block, bool block_link, const u8
DestroyBlock(old_b, true); DestroyBlock(old_b, true);
} }
start_block_map[block.physicalAddress] = █ start_block_map[block.physicalAddress] = █
FastLookupEntryForAddress(block.effectiveAddress) = █ size_t icache = FastLookupEntryForAddress(block.effectiveAddress);
iCache[icache] = █
block.in_icache = icache;
u32 pAddr = block.physicalAddress; u32 pAddr = block.physicalAddress;
@ -184,13 +187,13 @@ JitBlock* JitBaseBlockCache::GetBlockFromStartAddress(u32 addr, u32 msr)
const u8* JitBaseBlockCache::Dispatch() const u8* JitBaseBlockCache::Dispatch()
{ {
JitBlock* block = FastLookupEntryForAddress(PC); JitBlock* block = iCache[FastLookupEntryForAddress(PC)];
while (!block || block->effectiveAddress != PC || while (!block || block->effectiveAddress != PC ||
block->msrBits != (MSR & JitBlock::JIT_CACHE_MSR_MASK)) block->msrBits != (MSR & JitBlock::JIT_CACHE_MSR_MASK))
{ {
MoveBlockIntoFastCache(PC, MSR & JitBlock::JIT_CACHE_MSR_MASK); MoveBlockIntoFastCache(PC, MSR & JitBlock::JIT_CACHE_MSR_MASK);
block = FastLookupEntryForAddress(PC); block = iCache[FastLookupEntryForAddress(PC)];
} }
return block->normalEntry; return block->normalEntry;
@ -320,7 +323,8 @@ void JitBaseBlockCache::DestroyBlock(JitBlock& block, bool invalidate)
} }
block.invalid = true; block.invalid = true;
start_block_map.erase(block.physicalAddress); start_block_map.erase(block.physicalAddress);
FastLookupEntryForAddress(block.effectiveAddress) = nullptr; if (iCache[block.in_icache] == &block)
iCache[block.in_icache] = nullptr;
UnlinkBlock(block); UnlinkBlock(block);
@ -350,12 +354,19 @@ void JitBaseBlockCache::MoveBlockIntoFastCache(u32 addr, u32 msr)
} }
else else
{ {
FastLookupEntryForAddress(addr) = block; // Drop old icache entry
if (iCache[block->in_icache] == block)
iCache[block->in_icache] = nullptr;
// And create a new one
size_t icache = FastLookupEntryForAddress(addr);
iCache[icache] = block;
block->in_icache = icache;
LinkBlock(*block); LinkBlock(*block);
} }
} }
JitBlock*& JitBaseBlockCache::FastLookupEntryForAddress(u32 address) size_t JitBaseBlockCache::FastLookupEntryForAddress(u32 address)
{ {
return iCache[(address >> 2) & iCache_Mask]; return (address >> 2) & iCache_Mask;
} }

View File

@ -74,6 +74,10 @@ struct JitBlock
u64 ticStart; // for profiling - time. u64 ticStart; // for profiling - time.
u64 ticStop; // for profiling - time. u64 ticStop; // for profiling - time.
u64 ticCounter; // for profiling - time. u64 ticCounter; // for profiling - time.
// This tracks the position if this block within the icache.
// We allow each block to have one icache entry.
size_t in_icache;
}; };
typedef void (*CompiledCode)(); typedef void (*CompiledCode)();
@ -163,7 +167,7 @@ private:
void MoveBlockIntoFastCache(u32 em_address, u32 msr); void MoveBlockIntoFastCache(u32 em_address, u32 msr);
// Fast but risky block lookup based on iCache. // Fast but risky block lookup based on iCache.
JitBlock*& FastLookupEntryForAddress(u32 address); size_t FastLookupEntryForAddress(u32 address);
// We store the metadata of all blocks in a linear way within this array. // We store the metadata of all blocks in a linear way within this array.
// Note: blocks[0] must not be used as it is referenced as invalid block in iCache. // Note: blocks[0] must not be used as it is referenced as invalid block in iCache.