JitCache: Extract ErasePhysicalRange as function.
This commit is contained in:
parent
70caf447b9
commit
7f6b8e3555
|
@ -36,9 +36,10 @@ static void ClearCacheThreadSafe(u64 userdata, s64 cyclesdata)
|
||||||
JitInterface::ClearCache();
|
JitInterface::ClearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JitBlock::Overlap(u32 addr, u32 length)
|
bool JitBlock::OverlapsPhysicalRange(u32 address, u32 length) const
|
||||||
{
|
{
|
||||||
return physical_addresses.lower_bound(addr) != physical_addresses.lower_bound(addr + length);
|
return physical_addresses.lower_bound(address) !=
|
||||||
|
physical_addresses.lower_bound(address + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
JitBaseBlockCache::JitBaseBlockCache(JitBase& jit) : m_jit{jit}
|
JitBaseBlockCache::JitBaseBlockCache(JitBase& jit) : m_jit{jit}
|
||||||
|
@ -182,7 +183,7 @@ const u8* JitBaseBlockCache::Dispatch()
|
||||||
return block->normalEntry;
|
return block->normalEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool forced)
|
void JitBaseBlockCache::InvalidateICache(u32 address, u32 length, bool forced)
|
||||||
{
|
{
|
||||||
auto translated = PowerPC::JitCache_TranslateAddress(address);
|
auto translated = PowerPC::JitCache_TranslateAddress(address);
|
||||||
if (!translated.valid)
|
if (!translated.valid)
|
||||||
|
@ -199,45 +200,10 @@ void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool for
|
||||||
valid_block.Clear(pAddr / 32);
|
valid_block.Clear(pAddr / 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy JIT blocks
|
|
||||||
if (destroy_block)
|
if (destroy_block)
|
||||||
{
|
{
|
||||||
// Iterate over all macro blocks which overlap the given range.
|
// destroy JIT blocks
|
||||||
u32 range_mask = ~(BLOCK_RANGE_MAP_ELEMENTS - 1);
|
ErasePhysicalRange(pAddr, length);
|
||||||
auto start = block_range_map.lower_bound(pAddr & range_mask);
|
|
||||||
auto end = block_range_map.lower_bound(pAddr + length);
|
|
||||||
while (start != end)
|
|
||||||
{
|
|
||||||
// Iterate over all blocks in the macro block.
|
|
||||||
auto iter = start->second.begin();
|
|
||||||
while (iter != start->second.end())
|
|
||||||
{
|
|
||||||
JitBlock* block = *iter;
|
|
||||||
if (block->Overlap(pAddr, length))
|
|
||||||
{
|
|
||||||
// If the block overlaps, also remove all other occupied slots in the other macro blocks.
|
|
||||||
// This will leak empty macro blocks, but they may be reused or cleared later on.
|
|
||||||
for (u32 addr : block->physical_addresses)
|
|
||||||
if ((addr & range_mask) != start->first)
|
|
||||||
block_range_map[addr & range_mask].erase(block);
|
|
||||||
|
|
||||||
// And remove the block.
|
|
||||||
DestroyBlock(*block);
|
|
||||||
block_map.erase(block->physicalAddress);
|
|
||||||
iter = start->second.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the macro block is empty, drop it.
|
|
||||||
if (start->second.empty())
|
|
||||||
start = block_range_map.erase(start);
|
|
||||||
else
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the code was actually modified, we need to clear the relevant entries from the
|
// If the code was actually modified, we need to clear the relevant entries from the
|
||||||
// FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't
|
// FIFO write address cache, so we don't end up with FIFO checks in places they shouldn't
|
||||||
|
@ -254,6 +220,46 @@ void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool for
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitBaseBlockCache::ErasePhysicalRange(u32 address, u32 length)
|
||||||
|
{
|
||||||
|
// Iterate over all macro blocks which overlap the given range.
|
||||||
|
u32 range_mask = ~(BLOCK_RANGE_MAP_ELEMENTS - 1);
|
||||||
|
auto start = block_range_map.lower_bound(address & range_mask);
|
||||||
|
auto end = block_range_map.lower_bound(address + length);
|
||||||
|
while (start != end)
|
||||||
|
{
|
||||||
|
// Iterate over all blocks in the macro block.
|
||||||
|
auto iter = start->second.begin();
|
||||||
|
while (iter != start->second.end())
|
||||||
|
{
|
||||||
|
JitBlock* block = *iter;
|
||||||
|
if (block->OverlapsPhysicalRange(address, length))
|
||||||
|
{
|
||||||
|
// If the block overlaps, also remove all other occupied slots in the other macro blocks.
|
||||||
|
// This will leak empty macro blocks, but they may be reused or cleared later on.
|
||||||
|
for (u32 addr : block->physical_addresses)
|
||||||
|
if ((addr & range_mask) != start->first)
|
||||||
|
block_range_map[addr & range_mask].erase(block);
|
||||||
|
|
||||||
|
// And remove the block.
|
||||||
|
DestroyBlock(*block);
|
||||||
|
block_map.erase(block->physicalAddress);
|
||||||
|
iter = start->second.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the macro block is empty, drop it.
|
||||||
|
if (start->second.empty())
|
||||||
|
start = block_range_map.erase(start);
|
||||||
|
else
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32* JitBaseBlockCache::GetBlockBitSet() const
|
u32* JitBaseBlockCache::GetBlockBitSet() const
|
||||||
{
|
{
|
||||||
return valid_block.m_valid_block.get();
|
return valid_block.m_valid_block.get();
|
||||||
|
|
|
@ -25,7 +25,7 @@ class JitBase;
|
||||||
// address.
|
// address.
|
||||||
struct JitBlock
|
struct JitBlock
|
||||||
{
|
{
|
||||||
bool Overlap(u32 addr, u32 length);
|
bool OverlapsPhysicalRange(u32 address, u32 length) const;
|
||||||
|
|
||||||
// A special entry point for block linking; usually used to check the
|
// A special entry point for block linking; usually used to check the
|
||||||
// downcount.
|
// downcount.
|
||||||
|
@ -143,7 +143,8 @@ public:
|
||||||
// assembly version.)
|
// assembly version.)
|
||||||
const u8* Dispatch();
|
const u8* Dispatch();
|
||||||
|
|
||||||
void InvalidateICache(u32 address, const u32 length, bool forced);
|
void InvalidateICache(u32 address, u32 length, bool forced);
|
||||||
|
void ErasePhysicalRange(u32 address, u32 length);
|
||||||
|
|
||||||
u32* GetBlockBitSet() const;
|
u32* GetBlockBitSet() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue