Validate blocklinking in icache invalidate all.

Normally blocks are invalidated on entry.  But when blocklinking is on,
we don't validate on all entries.

This fixes Tales of Rebirth crashes (#7868.)
This commit is contained in:
Unknown W. Brackets 2015-07-19 13:08:32 -07:00
parent 96b01e4999
commit cd842ac21f
3 changed files with 25 additions and 0 deletions

View file

@ -425,6 +425,8 @@ u32 sceKernelIcacheInvalidateAll()
#ifdef LOG_CACHE
NOTICE_LOG(CPU, "Icache invalidated - should clear JIT someday");
#endif
// Note that this doesn't actually fully invalidate all with such a large range.
currentMIPS->InvalidateICache(0, 0x3FFFFFFF);
return 0;
}
@ -435,6 +437,8 @@ u32 sceKernelIcacheClearAll()
NOTICE_LOG(CPU, "Icache cleared - should clear JIT someday");
#endif
DEBUG_LOG(CPU, "Icache cleared - should clear JIT someday");
// Note that this doesn't actually fully invalidate all with such a large range.
currentMIPS->InvalidateICache(0, 0x3FFFFFFF);
return 0;
}

View file

@ -626,6 +626,11 @@ void JitBlockCache::InvalidateICache(u32 address, const u32 length) {
return;
}
if (pAddr == 0 && pEnd >= 0x1FFFFFFF) {
InvalidateChangedBlocks();
return;
}
// Blocks may start and end in overlapping ways, and destroying one invalidates iterators.
// So after destroying one, we start over.
do {
@ -647,6 +652,21 @@ void JitBlockCache::InvalidateICache(u32 address, const u32 length) {
} while (false);
}
void JitBlockCache::InvalidateChangedBlocks() {
// The primary goal of this is to make sure block linking is cleared up.
for (int block_num = 0; block_num < num_blocks_; ++block_num) {
JitBlock &b = blocks_[block_num];
if (b.invalid || b.IsPureProxy())
continue;
const u32 emuhack = GetEmuHackOpForBlock(block_num).encoding;
if (Memory::ReadUnchecked_U32(b.originalAddress) != emuhack) {
DEBUG_LOG(JIT, "Invalidating changed block at %08x", b.originalAddress);
DestroyBlock(block_num, true);
}
}
}
int JitBlockCache::GetBlockExitSize() {
#if defined(ARM)
// Will depend on the sequence found to encode the destination address.

View file

@ -147,6 +147,7 @@ public:
// DOES NOT WORK CORRECTLY WITH JIT INLINING
void InvalidateICache(u32 address, const u32 length);
void InvalidateChangedBlocks();
void DestroyBlock(int block_num, bool invalidate);
// No jit operations may be run between these calls.