summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2017-01-11 22:41:30 +0100
committerdegasus <wickmarkus@web.de>2017-01-22 16:50:46 +0100
commit830ae6a2c181c9fadb0dec1cd7bbb17bafb99ad9 (patch)
tree406bde3e9612df5f4ba56ed70e0b3f8af1879acf /Source/Core
parent43cdbab5154d7a95aafa11949dd159dc5aa1aad9 (diff)
JitCache: Store the JitBlock in the std::map.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp2
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp3
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/JitCache.cpp77
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/JitCache.h16
6 files changed, 34 insertions, 68 deletions
diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
index 39006acf01..1e41dc63c2 100644
--- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
+++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
@@ -123,7 +123,7 @@ static bool CheckDSI(u32 data)
void CachedInterpreter::Jit(u32 address)
{
- if (m_code.size() >= CODE_SIZE / sizeof(Instruction) - 0x1000 || m_block_cache.IsFull() ||
+ if (m_code.size() >= CODE_SIZE / sizeof(Instruction) - 0x1000 ||
SConfig::GetInstance().bJITNoBlockCache)
{
ClearCache();
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
index 580bab2577..f7b75223e2 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp
@@ -543,7 +543,7 @@ void Jit64::Jit(u32 em_address)
}
if (IsAlmostFull() || m_far_code.IsAlmostFull() || trampolines.IsAlmostFull() ||
- blocks.IsFull() || SConfig::GetInstance().bJITNoBlockCache)
+ SConfig::GetInstance().bJITNoBlockCache)
{
ClearCache();
}
diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
index 85c8b12cc0..dac66a2e4b 100644
--- a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
+++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp
@@ -466,7 +466,7 @@ void JitIL::Trace()
void JitIL::Jit(u32 em_address)
{
if (IsAlmostFull() || m_far_code.IsAlmostFull() || trampolines.IsAlmostFull() ||
- blocks.IsFull() || SConfig::GetInstance().bJITNoBlockCache)
+ SConfig::GetInstance().bJITNoBlockCache)
{
ClearCache();
}
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
index a424166574..c0db4b4e76 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp
@@ -368,8 +368,7 @@ void JitArm64::SingleStep()
void JitArm64::Jit(u32)
{
- if (IsAlmostFull() || farcode.IsAlmostFull() || blocks.IsFull() ||
- SConfig::GetInstance().bJITNoBlockCache)
+ if (IsAlmostFull() || farcode.IsAlmostFull() || SConfig::GetInstance().bJITNoBlockCache)
{
ClearCache();
}
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
index 12bbd5ab21..134b3ebca4 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
@@ -47,14 +47,11 @@ void JitBaseBlockCache::Init()
s_clear_jit_cache_thread_safe = CoreTiming::RegisterEvent("clearJitCache", ClearCacheThreadSafe);
JitRegister::Init(SConfig::GetInstance().m_perfDir);
- iCache.fill(nullptr);
Clear();
}
void JitBaseBlockCache::Shutdown()
{
- num_blocks = 1;
-
JitRegister::Shutdown();
}
@@ -63,26 +60,21 @@ void JitBaseBlockCache::Shutdown()
void JitBaseBlockCache::Clear()
{
#if defined(_DEBUG) || defined(DEBUGFAST)
- if (IsFull())
- Core::DisplayMessage("Clearing block cache.", 3000);
- else
- Core::DisplayMessage("Clearing code cache.", 3000);
+ Core::DisplayMessage("Clearing code cache.", 3000);
#endif
m_jit.js.fifoWriteAddresses.clear();
m_jit.js.pairedQuantizeAddresses.clear();
- for (int i = 1; i < num_blocks; i++)
+ for (auto& e : start_block_map)
{
- if (!block.invalid)
- DestroyBlock(blocks[i]);
+ DestroyBlock(e.second);
}
+ start_block_map.clear();
links_to.clear();
block_map.clear();
valid_block.ClearAll();
- num_blocks = 1;
- blocks[0].msrBits = 0xFFFFFFFF;
- blocks[0].invalid = true;
+ iCache.fill(nullptr);
}
void JitBaseBlockCache::Reset()
@@ -96,11 +88,6 @@ void JitBaseBlockCache::SchedulateClearCacheThreadSafe()
CoreTiming::ScheduleEvent(0, s_clear_jit_cache_thread_safe, 0, CoreTiming::FromThread::NON_CPU);
}
-bool JitBaseBlockCache::IsFull() const
-{
- return num_blocks >= MAX_NUM_BLOCKS - 1;
-}
-
JitBlock** JitBaseBlockCache::GetICache()
{
return iCache.data();
@@ -108,26 +95,36 @@ JitBlock** JitBaseBlockCache::GetICache()
void JitBaseBlockCache::RunOnBlocks(std::function<void(const JitBlock&)> f)
{
- for (int i = 0; i < num_blocks; i++)
- f(blocks[i]);
+ for (const auto& e : start_block_map)
+ f(e.second);
}
JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address)
{
- JitBlock& b = blocks[num_blocks];
- b.invalid = false;
+ u32 physicalAddress = PowerPC::JitCache_TranslateAddress(em_address).address;
+ JitBlock& b = start_block_map.emplace(physicalAddress, JitBlock())->second;
b.effectiveAddress = em_address;
- b.physicalAddress = PowerPC::JitCache_TranslateAddress(em_address).address;
+ b.physicalAddress = physicalAddress;
b.msrBits = MSR & JIT_CACHE_MSR_MASK;
b.linkData.clear();
b.in_icache = 0;
- num_blocks++; // commit the current block
return &b;
}
+void JitBaseBlockCache::FreeBlock(JitBlock* block)
+{
+ auto iter = start_block_map.equal_range(block->physicalAddress);
+ while (iter.first != iter.second)
+ {
+ if (&iter.first->second == block)
+ start_block_map.erase(iter.first);
+ else
+ iter.first++;
+ }
+}
+
void JitBaseBlockCache::FinalizeBlock(JitBlock& block, bool block_link, const u8* code_ptr)
{
- start_block_map.emplace(block.physicalAddress, &block);
size_t icache = FastLookupEntryForAddress(block.effectiveAddress);
iCache[icache] = &block;
block.in_icache = icache;
@@ -168,8 +165,8 @@ JitBlock* JitBaseBlockCache::GetBlockFromStartAddress(u32 addr, u32 msr)
auto iter = start_block_map.equal_range(translated_addr);
for (; iter.first != iter.second; iter.first++)
{
- JitBlock& b = *iter.first->second;
- if (!b.invalid && b.effectiveAddress == addr && b.msrBits == (msr & JIT_CACHE_MSR_MASK))
+ JitBlock& b = iter.first->second;
+ if (b.effectiveAddress == addr && b.msrBits == (msr & JIT_CACHE_MSR_MASK))
return &b;
}
@@ -214,7 +211,9 @@ void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length, bool for
auto it = block_map.lower_bound(std::make_pair(pAddr, 0));
while (it != block_map.end() && it->first.second < pAddr + length)
{
- DestroyBlock(*it->second);
+ JitBlock* block = it->second;
+ DestroyBlock(*block);
+ FreeBlock(block);
it = block_map.erase(it);
}
@@ -250,17 +249,12 @@ void JitBaseBlockCache::WriteDestroyBlock(const JitBlock& block)
void JitBaseBlockCache::LinkBlockExits(JitBlock& block)
{
- if (block.invalid)
- {
- // This block is dead. Don't relink it.
- return;
- }
for (auto& e : block.linkData)
{
if (!e.linkStatus)
{
JitBlock* destinationBlock = GetBlockFromStartAddress(e.exitAddress, block.msrBits);
- if (destinationBlock && !destinationBlock->invalid)
+ if (destinationBlock)
{
WriteLinkBlock(e, destinationBlock);
e.linkStatus = true;
@@ -305,24 +299,9 @@ void JitBaseBlockCache::UnlinkBlock(const JitBlock& block)
void JitBaseBlockCache::DestroyBlock(JitBlock& block)
{
- if (block.invalid)
- {
- PanicAlert("Invalidating invalid block %p", &block);
- return;
- }
- block.invalid = true;
if (iCache[block.in_icache] == &block)
iCache[block.in_icache] = nullptr;
- auto iter = start_block_map.equal_range(block.physicalAddress);
- while (iter.first != iter.second)
- {
- if (iter.first->second == &block)
- iter.first = start_block_map.erase(iter.first);
- else
- iter.first++;
- }
-
UnlinkBlock(block);
// Delete linking addresses
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
index 341d7c8d6d..0f1c36efef 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.h
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.h
@@ -47,11 +47,6 @@ struct JitBlock
u32 originalSize;
int runCount; // for profiling.
- // Whether this struct refers to a valid block. This is mostly useful as
- // a debugging aid.
- // FIXME: Change current users of invalid bit to assertions?
- bool invalid;
-
// Information about exits to a known address from this block.
// This is used to implement block linking.
struct LinkData
@@ -112,7 +107,6 @@ public:
// is valid (MSR.IR and MSR.DR, the address translation bits).
static constexpr u32 JIT_CACHE_MSR_MASK = 0x30;
- static constexpr int MAX_NUM_BLOCKS = 65536 * 2;
static constexpr u32 iCache_Num_Elements = 0x10000;
static constexpr u32 iCache_Mask = iCache_Num_Elements - 1;
@@ -125,13 +119,12 @@ public:
void Reset();
void SchedulateClearCacheThreadSafe();
- bool IsFull() const;
-
// Code Cache
JitBlock** GetICache();
void RunOnBlocks(std::function<void(const JitBlock&)> f);
JitBlock* AllocateBlock(u32 em_address);
+ void FreeBlock(JitBlock* block);
void FinalizeBlock(JitBlock& block, bool block_link, const u8* code_ptr);
// Look for the block in the slow but accurate way.
@@ -166,11 +159,6 @@ private:
// Fast but risky block lookup based on iCache.
size_t FastLookupEntryForAddress(u32 address);
- // 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.
- std::array<JitBlock, MAX_NUM_BLOCKS> blocks; // number -> JitBlock
- int num_blocks = 1;
-
// links_to hold all exit points of all valid blocks in a reverse way.
// It is used to query all blocks which links to an address.
std::multimap<u32, JitBlock*> links_to; // destination_PC -> number
@@ -182,7 +170,7 @@ private:
// Map indexed by the physical address of the entry point.
// This is used to query the block based on the current PC in a slow way.
// TODO: This is redundant with block_map.
- std::multimap<u32, JitBlock*> start_block_map; // start_addr -> block
+ std::multimap<u32, JitBlock> start_block_map; // start_addr -> block
// This bitsets shows which cachelines overlap with any blocks.
// It is used to provide a fast way to query if no icache invalidation is needed.