mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
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:
parent
96b01e4999
commit
cd842ac21f
3 changed files with 25 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue