mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #4647 from degasus/jitcache
JitCache: Clean up block id handling.
This commit is contained in:
commit
356619642b
@ -140,8 +140,7 @@ void CachedInterpreter::Jit(u32 address)
|
||||
return;
|
||||
}
|
||||
|
||||
int block_num = m_block_cache.AllocateBlock(PC);
|
||||
JitBlock* b = m_block_cache.GetBlock(block_num);
|
||||
JitBlock* b = m_block_cache.AllocateBlock(PC);
|
||||
|
||||
js.blockStart = PC;
|
||||
js.firstFPInstructionFound = false;
|
||||
@ -212,7 +211,7 @@ void CachedInterpreter::Jit(u32 address)
|
||||
b->codeSize = (u32)(GetCodePtr() - b->checkedEntry);
|
||||
b->originalSize = code_block.m_num_instructions;
|
||||
|
||||
m_block_cache.FinalizeBlock(block_num, jo.enableBlocklink, b->checkedEntry);
|
||||
m_block_cache.FinalizeBlock(*b, jo.enableBlocklink, b->checkedEntry);
|
||||
}
|
||||
|
||||
void CachedInterpreter::ClearCache()
|
||||
|
@ -589,9 +589,8 @@ void Jit64::Jit(u32 em_address)
|
||||
return;
|
||||
}
|
||||
|
||||
int block_num = blocks.AllocateBlock(em_address);
|
||||
JitBlock* b = blocks.GetBlock(block_num);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b, nextPC));
|
||||
JitBlock* b = blocks.AllocateBlock(em_address);
|
||||
blocks.FinalizeBlock(*b, jo.enableBlocklink, DoJit(em_address, &code_buffer, b, nextPC));
|
||||
}
|
||||
|
||||
const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBlock* b, u32 nextPC)
|
||||
|
@ -507,9 +507,8 @@ void JitIL::Jit(u32 em_address)
|
||||
return;
|
||||
}
|
||||
|
||||
int block_num = blocks.AllocateBlock(em_address);
|
||||
JitBlock* b = blocks.GetBlock(block_num);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, DoJit(em_address, &code_buffer, b, nextPC));
|
||||
JitBlock* b = blocks.AllocateBlock(em_address);
|
||||
blocks.FinalizeBlock(*b, jo.enableBlocklink, DoJit(em_address, &code_buffer, b, nextPC));
|
||||
}
|
||||
|
||||
const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBlock* b, u32 nextPC)
|
||||
|
@ -398,10 +398,9 @@ void JitArm64::Jit(u32)
|
||||
return;
|
||||
}
|
||||
|
||||
int block_num = blocks.AllocateBlock(em_address);
|
||||
JitBlock* b = blocks.GetBlock(block_num);
|
||||
JitBlock* b = blocks.AllocateBlock(em_address);
|
||||
const u8* BlockPtr = DoJit(em_address, &code_buffer, b, nextPC);
|
||||
blocks.FinalizeBlock(block_num, jo.enableBlocklink, BlockPtr);
|
||||
blocks.FinalizeBlock(*b, jo.enableBlocklink, BlockPtr);
|
||||
}
|
||||
|
||||
const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer* code_buf, JitBlock* b, u32 nextPC)
|
||||
|
@ -71,7 +71,7 @@ void JitBaseBlockCache::Clear()
|
||||
m_jit.js.pairedQuantizeAddresses.clear();
|
||||
for (int i = 1; i < num_blocks; i++)
|
||||
{
|
||||
DestroyBlock(i, false);
|
||||
DestroyBlock(blocks[i], false);
|
||||
}
|
||||
links_to.clear();
|
||||
block_map.clear();
|
||||
@ -96,12 +96,7 @@ void JitBaseBlockCache::SchedulateClearCacheThreadSafe()
|
||||
|
||||
bool JitBaseBlockCache::IsFull() const
|
||||
{
|
||||
return GetNumBlocks() >= MAX_NUM_BLOCKS - 1;
|
||||
}
|
||||
|
||||
JitBlock* JitBaseBlockCache::GetBlock(int no)
|
||||
{
|
||||
return &blocks[no];
|
||||
return num_blocks >= MAX_NUM_BLOCKS - 1;
|
||||
}
|
||||
|
||||
JitBlock* JitBaseBlockCache::GetBlocks()
|
||||
@ -109,17 +104,18 @@ JitBlock* JitBaseBlockCache::GetBlocks()
|
||||
return blocks.data();
|
||||
}
|
||||
|
||||
int JitBaseBlockCache::GetNumBlocks() const
|
||||
{
|
||||
return num_blocks;
|
||||
}
|
||||
|
||||
int* JitBaseBlockCache::GetICache()
|
||||
{
|
||||
return iCache.data();
|
||||
}
|
||||
|
||||
int JitBaseBlockCache::AllocateBlock(u32 em_address)
|
||||
void JitBaseBlockCache::RunOnBlocks(std::function<void(const JitBlock&)> f)
|
||||
{
|
||||
for (int i = 0; i < num_blocks; i++)
|
||||
f(blocks[i]);
|
||||
}
|
||||
|
||||
JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address)
|
||||
{
|
||||
JitBlock& b = blocks[num_blocks];
|
||||
b.invalid = false;
|
||||
@ -128,48 +124,47 @@ int JitBaseBlockCache::AllocateBlock(u32 em_address)
|
||||
b.msrBits = MSR & JitBlock::JIT_CACHE_MSR_MASK;
|
||||
b.linkData.clear();
|
||||
num_blocks++; // commit the current block
|
||||
return num_blocks - 1;
|
||||
return &b;
|
||||
}
|
||||
|
||||
void JitBaseBlockCache::FinalizeBlock(int block_num, bool block_link, const u8* code_ptr)
|
||||
void JitBaseBlockCache::FinalizeBlock(JitBlock& block, bool block_link, const u8* code_ptr)
|
||||
{
|
||||
JitBlock& b = blocks[block_num];
|
||||
if (start_block_map.count(b.physicalAddress))
|
||||
if (start_block_map.count(block.physicalAddress))
|
||||
{
|
||||
// We already have a block at this address; invalidate the old block.
|
||||
// This should be very rare. This will only happen if the same block
|
||||
// is called both with DR/IR enabled or disabled.
|
||||
WARN_LOG(DYNA_REC, "Invalidating compiled block at same address %08x", b.physicalAddress);
|
||||
int old_block_num = start_block_map[b.physicalAddress];
|
||||
const JitBlock& old_b = blocks[old_block_num];
|
||||
WARN_LOG(DYNA_REC, "Invalidating compiled block at same address %08x", block.physicalAddress);
|
||||
JitBlock& old_b = *start_block_map[block.physicalAddress];
|
||||
block_map.erase(
|
||||
std::make_pair(old_b.physicalAddress + 4 * old_b.originalSize - 1, old_b.physicalAddress));
|
||||
DestroyBlock(old_block_num, true);
|
||||
DestroyBlock(old_b, true);
|
||||
}
|
||||
start_block_map[b.physicalAddress] = block_num;
|
||||
FastLookupEntryForAddress(b.effectiveAddress) = block_num;
|
||||
const int block_num = static_cast<int>(&block - &blocks[0]);
|
||||
start_block_map[block.physicalAddress] = █
|
||||
FastLookupEntryForAddress(block.effectiveAddress) = block_num;
|
||||
|
||||
u32 pAddr = b.physicalAddress;
|
||||
u32 pAddr = block.physicalAddress;
|
||||
|
||||
for (u32 block = pAddr / 32; block <= (pAddr + (b.originalSize - 1) * 4) / 32; ++block)
|
||||
valid_block.Set(block);
|
||||
for (u32 addr = pAddr / 32; addr <= (pAddr + (block.originalSize - 1) * 4) / 32; ++addr)
|
||||
valid_block.Set(addr);
|
||||
|
||||
block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num;
|
||||
block_map[std::make_pair(pAddr + 4 * block.originalSize - 1, pAddr)] = █
|
||||
|
||||
if (block_link)
|
||||
{
|
||||
for (const auto& e : b.linkData)
|
||||
for (const auto& e : block.linkData)
|
||||
{
|
||||
links_to.emplace(e.exitAddress, block_num);
|
||||
links_to.emplace(e.exitAddress, &block);
|
||||
}
|
||||
|
||||
LinkBlock(block_num);
|
||||
LinkBlock(block);
|
||||
}
|
||||
|
||||
JitRegister::Register(b.checkedEntry, b.codeSize, "JIT_PPC_%08x", b.physicalAddress);
|
||||
JitRegister::Register(block.checkedEntry, block.codeSize, "JIT_PPC_%08x", block.physicalAddress);
|
||||
}
|
||||
|
||||
int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr, u32 msr)
|
||||
JitBlock* JitBaseBlockCache::GetBlockFromStartAddress(u32 addr, u32 msr)
|
||||
{
|
||||
u32 translated_addr = addr;
|
||||
if (UReg_MSR(msr).IR)
|
||||
@ -177,23 +172,20 @@ int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr, u32 msr)
|
||||
auto translated = PowerPC::JitCache_TranslateAddress(addr);
|
||||
if (!translated.valid)
|
||||
{
|
||||
return -1;
|
||||
return nullptr;
|
||||
}
|
||||
translated_addr = translated.address;
|
||||
}
|
||||
|
||||
auto map_result = start_block_map.find(translated_addr);
|
||||
if (map_result == start_block_map.end())
|
||||
return -1;
|
||||
int block_num = map_result->second;
|
||||
const JitBlock& b = blocks[block_num];
|
||||
if (b.invalid)
|
||||
return -1;
|
||||
if (b.effectiveAddress != addr)
|
||||
return -1;
|
||||
if (b.msrBits != (msr & JitBlock::JIT_CACHE_MSR_MASK))
|
||||
return -1;
|
||||
return block_num;
|
||||
return nullptr;
|
||||
|
||||
JitBlock* b = map_result->second;
|
||||
if (b->invalid || b->effectiveAddress != addr ||
|
||||
b->msrBits != (msr & JitBlock::JIT_CACHE_MSR_MASK))
|
||||
return nullptr;
|
||||
return b;
|
||||
}
|
||||
|
||||
const u8* JitBaseBlockCache::Dispatch()
|
||||
@ -235,7 +227,7 @@ 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, true);
|
||||
DestroyBlock(*it->second, true);
|
||||
it = block_map.erase(it);
|
||||
}
|
||||
|
||||
@ -269,59 +261,53 @@ void JitBaseBlockCache::WriteDestroyBlock(const JitBlock& block)
|
||||
// Can be faster by doing a queue for blocks to link up, and only process those
|
||||
// Should probably be done
|
||||
|
||||
void JitBaseBlockCache::LinkBlockExits(int i)
|
||||
void JitBaseBlockCache::LinkBlockExits(JitBlock& block)
|
||||
{
|
||||
JitBlock& b = blocks[i];
|
||||
if (b.invalid)
|
||||
if (block.invalid)
|
||||
{
|
||||
// This block is dead. Don't relink it.
|
||||
return;
|
||||
}
|
||||
for (auto& e : b.linkData)
|
||||
for (auto& e : block.linkData)
|
||||
{
|
||||
if (!e.linkStatus)
|
||||
{
|
||||
int destinationBlock = GetBlockNumberFromStartAddress(e.exitAddress, b.msrBits);
|
||||
if (destinationBlock != -1)
|
||||
JitBlock* destinationBlock = GetBlockFromStartAddress(e.exitAddress, block.msrBits);
|
||||
if (destinationBlock && !destinationBlock->invalid)
|
||||
{
|
||||
if (!blocks[destinationBlock].invalid)
|
||||
{
|
||||
WriteLinkBlock(e, &blocks[destinationBlock]);
|
||||
WriteLinkBlock(e, destinationBlock);
|
||||
e.linkStatus = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JitBaseBlockCache::LinkBlock(int i)
|
||||
void JitBaseBlockCache::LinkBlock(JitBlock& block)
|
||||
{
|
||||
LinkBlockExits(i);
|
||||
const JitBlock& b = blocks[i];
|
||||
auto ppp = links_to.equal_range(b.effectiveAddress);
|
||||
LinkBlockExits(block);
|
||||
auto ppp = links_to.equal_range(block.effectiveAddress);
|
||||
|
||||
for (auto iter = ppp.first; iter != ppp.second; ++iter)
|
||||
{
|
||||
const JitBlock& b2 = blocks[iter->second];
|
||||
if (b.msrBits == b2.msrBits)
|
||||
LinkBlockExits(iter->second);
|
||||
JitBlock& b2 = *iter->second;
|
||||
if (block.msrBits == b2.msrBits)
|
||||
LinkBlockExits(b2);
|
||||
}
|
||||
}
|
||||
|
||||
void JitBaseBlockCache::UnlinkBlock(int i)
|
||||
void JitBaseBlockCache::UnlinkBlock(const JitBlock& block)
|
||||
{
|
||||
JitBlock& b = blocks[i];
|
||||
auto ppp = links_to.equal_range(b.effectiveAddress);
|
||||
auto ppp = links_to.equal_range(block.effectiveAddress);
|
||||
|
||||
for (auto iter = ppp.first; iter != ppp.second; ++iter)
|
||||
{
|
||||
JitBlock& sourceBlock = blocks[iter->second];
|
||||
if (sourceBlock.msrBits != b.msrBits)
|
||||
JitBlock& sourceBlock = *iter->second;
|
||||
if (sourceBlock.msrBits != block.msrBits)
|
||||
continue;
|
||||
|
||||
for (auto& e : sourceBlock.linkData)
|
||||
{
|
||||
if (e.exitAddress == b.effectiveAddress)
|
||||
if (e.exitAddress == block.effectiveAddress)
|
||||
{
|
||||
WriteLinkBlock(e, nullptr);
|
||||
e.linkStatus = false;
|
||||
@ -330,51 +316,45 @@ void JitBaseBlockCache::UnlinkBlock(int i)
|
||||
}
|
||||
}
|
||||
|
||||
void JitBaseBlockCache::DestroyBlock(int block_num, bool invalidate)
|
||||
void JitBaseBlockCache::DestroyBlock(JitBlock& block, bool invalidate)
|
||||
{
|
||||
if (block_num < 0 || block_num >= num_blocks)
|
||||
{
|
||||
PanicAlert("DestroyBlock: Invalid block number %d", block_num);
|
||||
return;
|
||||
}
|
||||
JitBlock& b = blocks[block_num];
|
||||
if (b.invalid)
|
||||
if (block.invalid)
|
||||
{
|
||||
if (invalidate)
|
||||
PanicAlert("Invalidating invalid block %d", block_num);
|
||||
PanicAlert("Invalidating invalid block %p", &block);
|
||||
return;
|
||||
}
|
||||
b.invalid = true;
|
||||
start_block_map.erase(b.physicalAddress);
|
||||
FastLookupEntryForAddress(b.effectiveAddress) = 0;
|
||||
block.invalid = true;
|
||||
start_block_map.erase(block.physicalAddress);
|
||||
FastLookupEntryForAddress(block.effectiveAddress) = 0;
|
||||
|
||||
UnlinkBlock(block_num);
|
||||
UnlinkBlock(block);
|
||||
|
||||
// Delete linking addresses
|
||||
auto it = links_to.equal_range(b.effectiveAddress);
|
||||
auto it = links_to.equal_range(block.effectiveAddress);
|
||||
while (it.first != it.second)
|
||||
{
|
||||
if (it.first->second == block_num)
|
||||
if (it.first->second == &block)
|
||||
it.first = links_to.erase(it.first);
|
||||
else
|
||||
it.first++;
|
||||
}
|
||||
|
||||
// Raise an signal if we are going to call this block again
|
||||
WriteDestroyBlock(b);
|
||||
WriteDestroyBlock(block);
|
||||
}
|
||||
|
||||
void JitBaseBlockCache::MoveBlockIntoFastCache(u32 addr, u32 msr)
|
||||
{
|
||||
int block_num = GetBlockNumberFromStartAddress(addr, msr);
|
||||
if (block_num < 0)
|
||||
JitBlock* block = GetBlockFromStartAddress(addr, msr);
|
||||
if (!block)
|
||||
{
|
||||
Jit(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
FastLookupEntryForAddress(addr) = block_num;
|
||||
LinkBlock(block_num);
|
||||
FastLookupEntryForAddress(addr) = static_cast<int>(block - &blocks[0]);
|
||||
LinkBlock(*block);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@ -126,17 +127,17 @@ public:
|
||||
bool IsFull() const;
|
||||
|
||||
// Code Cache
|
||||
JitBlock* GetBlock(int block_num);
|
||||
JitBlock* GetBlocks();
|
||||
int GetNumBlocks() const;
|
||||
int* GetICache();
|
||||
void RunOnBlocks(std::function<void(const JitBlock&)> f);
|
||||
|
||||
int AllocateBlock(u32 em_address);
|
||||
void FinalizeBlock(int block_num, bool block_link, const u8* code_ptr);
|
||||
JitBlock* AllocateBlock(u32 em_address);
|
||||
void FinalizeBlock(JitBlock& block, bool block_link, const u8* code_ptr);
|
||||
|
||||
// Look for the block in the slow but accurate way.
|
||||
// This function shall be used if FastLookupEntryForAddress() failed.
|
||||
int GetBlockNumberFromStartAddress(u32 em_address, u32 msr);
|
||||
// This might return nullptr if there is no such block.
|
||||
JitBlock* GetBlockFromStartAddress(u32 em_address, u32 msr);
|
||||
|
||||
// Get the normal entry for the block associated with the current program
|
||||
// counter. This will JIT code if necessary. (This is the reference
|
||||
@ -155,10 +156,10 @@ private:
|
||||
virtual void WriteLinkBlock(const JitBlock::LinkData& source, const JitBlock* dest) = 0;
|
||||
virtual void WriteDestroyBlock(const JitBlock& block);
|
||||
|
||||
void LinkBlockExits(int i);
|
||||
void LinkBlock(int i);
|
||||
void UnlinkBlock(int i);
|
||||
void DestroyBlock(int block_num, bool invalidate);
|
||||
void LinkBlockExits(JitBlock& block);
|
||||
void LinkBlock(JitBlock& block);
|
||||
void UnlinkBlock(const JitBlock& block);
|
||||
void DestroyBlock(JitBlock& block, bool invalidate);
|
||||
|
||||
void MoveBlockIntoFastCache(u32 em_address, u32 msr);
|
||||
|
||||
@ -172,16 +173,16 @@ private:
|
||||
|
||||
// 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, int> links_to; // destination_PC -> number
|
||||
std::multimap<u32, JitBlock*> links_to; // destination_PC -> number
|
||||
|
||||
// Map indexed by the physical memory location.
|
||||
// It is used to invalidate blocks based on memory location.
|
||||
std::map<std::pair<u32, u32>, u32> block_map; // (end_addr, start_addr) -> number
|
||||
std::map<std::pair<u32, u32>, JitBlock*> block_map; // (end_addr, start_addr) -> block
|
||||
|
||||
// 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, and both should be a multimap.
|
||||
std::map<u32, u32> start_block_map; // start_addr -> number
|
||||
std::map<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.
|
||||
|
@ -134,26 +134,23 @@ void GetProfileResults(ProfileStats* prof_stats)
|
||||
prof_stats->cost_sum = 0;
|
||||
prof_stats->timecost_sum = 0;
|
||||
prof_stats->block_stats.clear();
|
||||
prof_stats->block_stats.reserve(g_jit->GetBlockCache()->GetNumBlocks());
|
||||
|
||||
Core::EState old_state = Core::GetState();
|
||||
if (old_state == Core::CORE_RUN)
|
||||
Core::SetState(Core::CORE_PAUSE);
|
||||
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec);
|
||||
for (int i = 0; i < g_jit->GetBlockCache()->GetNumBlocks(); i++)
|
||||
{
|
||||
const JitBlock* block = g_jit->GetBlockCache()->GetBlock(i);
|
||||
g_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) {
|
||||
// Rough heuristic. Mem instructions should cost more.
|
||||
u64 cost = block->originalSize * (block->runCount / 4);
|
||||
u64 timecost = block->ticCounter;
|
||||
u64 cost = block.originalSize * (block.runCount / 4);
|
||||
u64 timecost = block.ticCounter;
|
||||
// Todo: tweak.
|
||||
if (block->runCount >= 1)
|
||||
prof_stats->block_stats.emplace_back(i, block->effectiveAddress, cost, timecost,
|
||||
block->runCount, block->codeSize);
|
||||
if (block.runCount >= 1)
|
||||
prof_stats->block_stats.emplace_back(block.effectiveAddress, cost, timecost, block.runCount,
|
||||
block.codeSize);
|
||||
prof_stats->cost_sum += cost;
|
||||
prof_stats->timecost_sum += timecost;
|
||||
}
|
||||
});
|
||||
|
||||
sort(prof_stats->block_stats.begin(), prof_stats->block_stats.end());
|
||||
if (old_state == Core::CORE_RUN)
|
||||
@ -168,34 +165,31 @@ int GetHostCode(u32* address, const u8** code, u32* code_size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int block_num = g_jit->GetBlockCache()->GetBlockNumberFromStartAddress(*address, MSR);
|
||||
if (block_num < 0)
|
||||
JitBlock* block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address, MSR);
|
||||
if (!block)
|
||||
{
|
||||
for (int i = 0; i < 500; i++)
|
||||
{
|
||||
block_num = g_jit->GetBlockCache()->GetBlockNumberFromStartAddress(*address - 4 * i, MSR);
|
||||
if (block_num >= 0)
|
||||
block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address - 4 * i, MSR);
|
||||
if (block)
|
||||
break;
|
||||
}
|
||||
|
||||
if (block_num >= 0)
|
||||
if (block)
|
||||
{
|
||||
JitBlock* block = g_jit->GetBlockCache()->GetBlock(block_num);
|
||||
if (!(block->effectiveAddress <= *address &&
|
||||
block->originalSize + block->effectiveAddress >= *address))
|
||||
block_num = -1;
|
||||
block = nullptr;
|
||||
}
|
||||
|
||||
// Do not merge this "if" with the above - block_num changes inside it.
|
||||
if (block_num < 0)
|
||||
if (!block)
|
||||
{
|
||||
*code_size = 0;
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
JitBlock* block = g_jit->GetBlockCache()->GetBlock(block_num);
|
||||
|
||||
*code = block->checkedEntry;
|
||||
*code_size = block->codeSize;
|
||||
*address = block->effectiveAddress;
|
||||
|
@ -43,11 +43,10 @@
|
||||
|
||||
struct BlockStat
|
||||
{
|
||||
BlockStat(int bn, u32 _addr, u64 c, u64 ticks, u64 run, u32 size)
|
||||
: blockNum(bn), addr(_addr), cost(c), tick_counter(ticks), run_count(run), block_size(size)
|
||||
BlockStat(u32 _addr, u64 c, u64 ticks, u64 run, u32 size)
|
||||
: addr(_addr), cost(c), tick_counter(ticks), run_count(run), block_size(size)
|
||||
{
|
||||
}
|
||||
int blockNum;
|
||||
u32 addr;
|
||||
u64 cost;
|
||||
u64 tick_counter;
|
||||
|
Loading…
Reference in New Issue
Block a user