Simplify block link code.

This commit is contained in:
Jean-Philip Desjardins 2018-06-27 08:20:55 -04:00
parent 241e7a9809
commit 3952e74d32
3 changed files with 41 additions and 43 deletions

View File

@ -39,6 +39,8 @@ extern "C"
#endif
#define INVALID_LINK_SLOT (~0U)
CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
: m_begin(begin)
, m_end(end)
@ -48,6 +50,10 @@ CBasicBlock::CBasicBlock(CMIPS& context, uint32 begin, uint32 end)
#endif
{
assert(m_end >= m_begin);
for(uint32 i = 0; i < LINK_SLOT_MAX; i++)
{
m_linkBlockTrampolineOffset[i] = INVALID_LINK_SLOT;
}
}
#ifdef AOT_BUILD_CACHE
@ -287,37 +293,28 @@ bool CBasicBlock::IsEmpty() const
(m_end == MIPS_INVALID_PC);
}
void CBasicBlock::LinkNextBlock(CBasicBlock* otherBlock)
void CBasicBlock::LinkBlock(LINK_SLOT linkSlot, CBasicBlock* otherBlock)
{
assert(!IsEmpty());
assert(!otherBlock->IsEmpty());
assert(m_nextBlockTrampolineOffset != -1);
assert(linkSlot < LINK_SLOT_MAX);
assert(m_linkBlockTrampolineOffset[linkSlot] != INVALID_LINK_SLOT);
auto patchValue = reinterpret_cast<uintptr_t>(otherBlock->m_function.GetCode());
auto code = reinterpret_cast<uint8*>(m_function.GetCode());
*reinterpret_cast<uintptr_t*>(code + m_nextBlockTrampolineOffset) = patchValue;
}
void CBasicBlock::LinkBranchBlock(CBasicBlock* otherBlock)
{
assert(!IsEmpty());
assert(!otherBlock->IsEmpty());
assert(m_branchBlockTrampolineOffset != -1);
auto patchValue = reinterpret_cast<uintptr_t>(otherBlock->m_function.GetCode());
auto code = reinterpret_cast<uint8*>(m_function.GetCode());
*reinterpret_cast<uintptr_t*>(code + m_branchBlockTrampolineOffset) = patchValue;
*reinterpret_cast<uintptr_t*>(code + m_linkBlockTrampolineOffset[linkSlot]) = patchValue;
}
void CBasicBlock::HandleExternalFunctionReference(uintptr_t symbol, uint32 offset)
{
if(symbol == reinterpret_cast<uintptr_t>(&NextBlockTrampoline))
{
if(m_branchBlockTrampolineOffset == -1)
if(m_linkBlockTrampolineOffset[LINK_SLOT_BRANCH] == INVALID_LINK_SLOT)
{
m_branchBlockTrampolineOffset = offset;
m_linkBlockTrampolineOffset[LINK_SLOT_BRANCH] = offset;
}
else
{
m_nextBlockTrampolineOffset = offset;
m_linkBlockTrampolineOffset[LINK_SLOT_NEXT] = offset;
}
}
}

View File

@ -43,6 +43,13 @@ namespace Jitter
class CBasicBlock
{
public:
enum LINK_SLOT
{
LINK_SLOT_NEXT,
LINK_SLOT_BRANCH,
LINK_SLOT_MAX,
};
CBasicBlock(CMIPS&, uint32 = MIPS_INVALID_PC, uint32 = MIPS_INVALID_PC);
virtual ~CBasicBlock() = default;
void Execute();
@ -53,8 +60,7 @@ public:
bool IsCompiled() const;
bool IsEmpty() const;
void LinkNextBlock(CBasicBlock*);
void LinkBranchBlock(CBasicBlock*);
void LinkBlock(LINK_SLOT, CBasicBlock*);
#ifdef AOT_BUILD_CACHE
static void SetAotBlockOutputStream(Framework::CStdStream*);
@ -84,6 +90,5 @@ private:
#else
void (*m_function)(void*);
#endif
uint32 m_nextBlockTrampolineOffset = -1;
uint32 m_branchBlockTrampolineOffset = -1;
uint32 m_linkBlockTrampolineOffset[LINK_SLOT_MAX];
};

View File

@ -268,8 +268,15 @@ public:
#endif
protected:
//Outgoing block link
struct BLOCK_LINK
{
CBasicBlock::LINK_SLOT slot;
uint32 address;
};
typedef std::list<BasicBlockPtr> BlockList;
typedef std::multimap<uint32, uint32> BlockLinkMap;
typedef std::multimap<uint32, BLOCK_LINK> BlockLinkMap;
bool HasBlockAt(uint32 address) const
{
@ -301,11 +308,11 @@ protected:
auto nextBlock = m_blockLookup.FindBlockAt(nextBlockAddress);
if(!nextBlock->IsEmpty())
{
block->LinkNextBlock(nextBlock);
block->LinkBlock(CBasicBlock::LINK_SLOT_NEXT, nextBlock);
}
else
{
m_pendingNextBlockLinks.insert(std::make_pair(nextBlockAddress, startAddress));
m_pendingBlockLinks.insert(std::make_pair(nextBlockAddress, BLOCK_LINK { CBasicBlock::LINK_SLOT_NEXT, startAddress }));
}
}
@ -314,36 +321,26 @@ protected:
auto branchBlock = m_blockLookup.FindBlockAt(branchAddress);
if(!branchBlock->IsEmpty())
{
block->LinkBranchBlock(branchBlock);
block->LinkBlock(CBasicBlock::LINK_SLOT_BRANCH, branchBlock);
}
else
{
m_pendingBranchBlockLinks.insert(std::make_pair(branchAddress, startAddress));
m_pendingBlockLinks.insert(std::make_pair(branchAddress, BLOCK_LINK { CBasicBlock::LINK_SLOT_BRANCH, startAddress }));
}
}
//Resolve any block links that could be valid now that block has been created
{
auto lowerBound = m_pendingNextBlockLinks.lower_bound(startAddress);
auto upperBound = m_pendingNextBlockLinks.upper_bound(startAddress);
auto lowerBound = m_pendingBlockLinks.lower_bound(startAddress);
auto upperBound = m_pendingBlockLinks.upper_bound(startAddress);
for(auto blockLinkIterator = lowerBound; blockLinkIterator != upperBound; blockLinkIterator++)
{
auto referringBlock = m_blockLookup.FindBlockAt(blockLinkIterator->second);
const auto& blockLink = blockLinkIterator->second;
auto referringBlock = m_blockLookup.FindBlockAt(blockLink.address);
if(referringBlock->IsEmpty()) continue;
referringBlock->LinkNextBlock(block);
referringBlock->LinkBlock(blockLink.slot, block);
}
m_pendingNextBlockLinks.erase(lowerBound, upperBound);
}
{
auto lowerBound = m_pendingBranchBlockLinks.lower_bound(startAddress);
auto upperBound = m_pendingBranchBlockLinks.upper_bound(startAddress);
for(auto blockLinkIterator = lowerBound; blockLinkIterator != upperBound; blockLinkIterator++)
{
auto referringBlock = m_blockLookup.FindBlockAt(blockLinkIterator->second);
if(referringBlock->IsEmpty()) continue;
referringBlock->LinkBranchBlock(block);
}
m_pendingBranchBlockLinks.erase(lowerBound, upperBound);
m_pendingBlockLinks.erase(lowerBound, upperBound);
}
}
@ -398,8 +395,7 @@ protected:
BlockList m_blocks;
BasicBlockPtr m_emptyBlock;
BlockLinkMap m_pendingNextBlockLinks;
BlockLinkMap m_pendingBranchBlockLinks;
BlockLinkMap m_pendingBlockLinks;
CMIPS& m_context;
uint32 m_maxAddress = 0;