Commit dc597e34 authored by Jean-Philip Desjardins's avatar Jean-Philip Desjardins
Browse files

Add empty block concept.

parent b30658ba
......@@ -171,6 +171,12 @@ void CBasicBlock::Compile()
void CBasicBlock::CompileRange(CMipsJitter* jitter)
{
if(IsEmpty())
{
jitter->JumpTo(reinterpret_cast<void*>(&EmptyBlockHandler));
return;
}
uint32 fixedEnd = m_end;
bool needsPcAdjust = false;
......@@ -275,3 +281,15 @@ bool CBasicBlock::IsCompiled() const
return (m_function != nullptr);
#endif
}
bool CBasicBlock::IsEmpty() const
{
return
(m_begin == MIPS_INVALID_PC) &&
(m_end == MIPS_INVALID_PC);
}
void CBasicBlock::EmptyBlockHandler(CMIPS* context)
{
context->m_emptyBlockHandler(context);
}
......@@ -43,7 +43,7 @@ namespace Jitter
class CBasicBlock
{
public:
CBasicBlock(CMIPS&, uint32, uint32);
CBasicBlock(CMIPS&, uint32 = MIPS_INVALID_PC, uint32 = MIPS_INVALID_PC);
virtual ~CBasicBlock() = default;
void Execute();
void Compile();
......@@ -51,6 +51,7 @@ public:
uint32 GetBeginAddress() const;
uint32 GetEndAddress() const;
bool IsCompiled() const;
bool IsEmpty() const;
#ifdef AOT_BUILD_CACHE
static void SetAotBlockOutputStream(Framework::CStdStream*);
......@@ -65,6 +66,8 @@ protected:
void CompileProlog(CMipsJitter*);
private:
static void EmptyBlockHandler(CMIPS*);
#ifdef AOT_BUILD_CACHE
static Framework::CStdStream* m_aotBlockOutputStream;
static std::mutex m_aotBlockOutputStreamMutex;
......
......@@ -138,6 +138,8 @@ public:
void* m_vuMem = nullptr;
std::function<void (CMIPS*)> m_emptyBlockHandler;
CMIPSArchitecture* m_pArch = nullptr;
CMIPSCoprocessor* m_pCOP[4];
CMemoryMap* m_pMemoryMap = nullptr;
......
......@@ -226,7 +226,18 @@ public:
, m_maxAddress(maxAddress)
, m_blockLookup(maxAddress)
{
assert(!context.m_emptyBlockHandler);
m_emptyBlock = std::make_shared<CBasicBlock>(context, MIPS_INVALID_PC, MIPS_INVALID_PC);
m_emptyBlock->Compile();
context.m_emptyBlockHandler =
[&] (CMIPS* context)
{
uint32 address = context->m_pAddrTranslator(&m_context, m_context.m_State.nPC);
PartitionFunction(address);
auto block = FindBlockStartingAt(address);
assert(!block->IsEmpty());
block->Execute();
};
}
virtual ~CMipsExecutor() = default;
......@@ -234,21 +245,14 @@ public:
int Execute(int cycles)
{
assert(TranslateFunction == m_context.m_pAddrTranslator);
CBasicBlock* block(nullptr);
auto block = m_emptyBlock.get();
m_context.m_State.cycleQuota += cycles;
while(m_context.m_State.cycleQuota > 0)
{
uint32 address = TranslateFunction(&m_context, m_context.m_State.nPC);
if(!block || address != block->GetBeginAddress())
if(address != block->GetBeginAddress())
{
block = FindBlockStartingAt(address);
if(!block)
{
//We need to partition the space and compile the blocks
PartitionFunction(address);
block = FindBlockStartingAt(address);
assert(block);
}
}
#ifdef DEBUGGER_INCLUDED
......@@ -264,7 +268,7 @@ public:
CBasicBlock* FindBlockStartingAt(uint32 address) const
{
auto result = m_blockLookup.FindBlockAt(address);
if(result && (result->GetBeginAddress() != address)) return nullptr;
if(!result || (result->GetBeginAddress() != address)) return m_emptyBlock.get();
return result;
}
......@@ -419,7 +423,7 @@ protected:
if(address != endAddress)
{
auto possibleBlock = FindBlockStartingAt(address);
if(possibleBlock)
if(!possibleBlock->IsEmpty())
{
//assert(possibleBlock->GetEndAddress() <= endAddress);
//Add its beginning and end in the partition points
......@@ -476,6 +480,7 @@ protected:
}
BlockList m_blocks;
BasicBlockPtr m_emptyBlock;
CMIPS& m_context;
uint32 m_maxAddress = 0;
......
......@@ -104,7 +104,7 @@ void CEeExecutor::ClearActiveBlocksInRange(uint32 start, uint32 end)
uint32 rangeSize = end - start;
SetMemoryProtected(m_ram + start, rangeSize, false);
auto currentBlock = FindBlockStartingAt(m_context.m_State.nPC);
assert(currentBlock != nullptr);
assert(!currentBlock->IsEmpty());
ClearActiveBlocksInRangeInternal(start, end, currentBlock);
}
......
......@@ -105,8 +105,8 @@ void CVuExecutor::PartitionFunction(uint32 functionAddress)
//Check if there's a block already exising that this address
if(address != endAddress)
{
CBasicBlock* possibleBlock = FindBlockStartingAt(address);
if(possibleBlock != NULL)
auto possibleBlock = FindBlockStartingAt(address);
if(!possibleBlock->IsEmpty())
{
assert(possibleBlock->GetEndAddress() <= endAddress);
//Add its beginning and end in the partition points
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment