CPU/CodeCache: Fix currently-invalidated blocks breaking memory states

This commit is contained in:
Connor McLaughlin 2022-01-06 22:46:54 +10:00
parent 30a53fbb3c
commit 541947c6f8

View file

@ -649,6 +649,9 @@ recompile:
AddBlockToHostCodeMap(block); AddBlockToHostCodeMap(block);
#endif #endif
// block is valid again
block->invalidated = false;
// re-insert into the block map since we removed it earlier. // re-insert into the block map since we removed it earlier.
s_blocks.emplace(block->key.bits, block); s_blocks.emplace(block->key.bits, block);
return true; return true;
@ -836,7 +839,7 @@ void InvalidCodeFunction()
#endif #endif
static void InvalidateBlock(CodeBlock* block) static void InvalidateBlock(CodeBlock* block, bool allow_frame_invalidation)
{ {
// Invalidate forces the block to be checked again. // Invalidate forces the block to be checked again.
Log_DebugPrintf("Invalidating block at 0x%08X", block->GetPC()); Log_DebugPrintf("Invalidating block at 0x%08X", block->GetPC());
@ -845,16 +848,24 @@ static void InvalidateBlock(CodeBlock* block)
if (block->can_link) if (block->can_link)
{ {
const u32 frame_number = System::GetFrameNumber(); const u32 frame_number = System::GetFrameNumber();
const u32 frame_diff = frame_number - block->invalidate_frame_number; if (allow_frame_invalidation)
if (frame_diff <= INVALIDATE_THRESHOLD_TO_DISABLE_LINKING)
{ {
Log_DevPrintf("Block 0x%08X has been invalidated in %u frames, disabling linking", block->GetPC(), frame_diff); const u32 frame_diff = frame_number - block->invalidate_frame_number;
block->can_link = false; if (frame_diff <= INVALIDATE_THRESHOLD_TO_DISABLE_LINKING)
{
Log_DevPrintf("Block 0x%08X has been invalidated in %u frames, disabling linking", block->GetPC(), frame_diff);
block->can_link = false;
}
else
{
// It's been a while since this block was modified, so it's all good.
block->invalidate_frame_number = frame_number;
}
} }
else else
{ {
// It's been a while since this block was modified, so it's all good. // don't trigger frame number based invalidation for this block (e.g. memory save states)
block->invalidate_frame_number = frame_number; block->invalidate_frame_number = frame_number - INVALIDATE_THRESHOLD_TO_DISABLE_LINKING - 1;
} }
} }
@ -870,7 +881,7 @@ void InvalidateBlocksWithPageIndex(u32 page_index)
DebugAssert(page_index < Bus::RAM_8MB_CODE_PAGE_COUNT); DebugAssert(page_index < Bus::RAM_8MB_CODE_PAGE_COUNT);
auto& blocks = m_ram_block_map[page_index]; auto& blocks = m_ram_block_map[page_index];
for (CodeBlock* block : blocks) for (CodeBlock* block : blocks)
InvalidateBlock(block); InvalidateBlock(block, true);
// Block will be re-added next execution. // Block will be re-added next execution.
blocks.clear(); blocks.clear();
@ -883,7 +894,7 @@ void InvalidateAll()
{ {
CodeBlock* block = it.second; CodeBlock* block = it.second;
if (block && !block->invalidated) if (block && !block->invalidated)
InvalidateBlock(block); InvalidateBlock(block, false);
} }
Bus::ClearRAMCodePageFlags(); Bus::ClearRAMCodePageFlags();