Break out the disassembler code from the WXWidgets UI.

This cleans up some of the code between core and UI for disassembling and dumping code blocks.
Should help the QT UI in bringing up its debug UI since it won't have to deal with this garbage now.
This commit is contained in:
Ryan Houdek
2015-05-31 16:21:47 -05:00
parent 210d7c4d54
commit d0ae3f7d24
9 changed files with 300 additions and 238 deletions

View File

@ -116,20 +116,44 @@ namespace JitInterface
void WriteProfileResults(const std::string& filename)
{
ProfileStats prof_stats;
GetProfileResults(&prof_stats);
File::IOFile f(filename, "w");
if (!f)
{
PanicAlert("Failed to open %s", filename.c_str());
return;
}
fprintf(f.GetHandle(), "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n");
for (auto& stat : prof_stats.block_stats)
{
std::string name = g_symbolDB.GetDescription(stat.addr);
double percent = 100.0 * (double)stat.cost / (double)prof_stats.cost_sum;
double timePercent = 100.0 * (double)stat.tick_counter / (double)prof_stats.timecost_sum;
fprintf(f.GetHandle(), "%08x\t%s\t%" PRIu64 "\t%" PRIu64 "\t%.2f\t%.2f\t%.2f\t%i\n",
stat.addr, name.c_str(), stat.cost,
stat.tick_counter, percent, timePercent,
(double)stat.tick_counter*1000.0/(double)prof_stats.countsPerSec, stat.block_size);
}
}
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(jit->GetBlockCache()->GetNumBlocks());
// Can't really do this with no jit core available
if (!jit)
return;
PowerPC::CPUState old_state = PowerPC::GetState();
if (old_state == PowerPC::CPUState::CPU_RUNNING)
PowerPC::Pause();
Core::EState old_state = Core::GetState();
if (old_state == Core::CORE_RUN)
Core::SetState(Core::CORE_PAUSE);
std::vector<BlockStat> stats;
stats.reserve(jit->GetBlockCache()->GetNumBlocks());
u64 cost_sum = 0;
u64 timecost_sum = 0;
u64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec);
for (int i = 0; i < jit->GetBlockCache()->GetNumBlocks(); i++)
{
const JitBlock *block = jit->GetBlockCache()->GetBlock(i);
@ -138,37 +162,60 @@ namespace JitInterface
u64 timecost = block->ticCounter;
// Todo: tweak.
if (block->runCount >= 1)
stats.emplace_back(i, cost);
cost_sum += cost;
timecost_sum += timecost;
prof_stats->block_stats.emplace_back(i, block->originalAddress,
cost, timecost, block->codeSize);
prof_stats->cost_sum += cost;
prof_stats->timecost_sum += timecost;
}
sort(stats.begin(), stats.end());
File::IOFile f(filename, "w");
if (!f)
sort(prof_stats->block_stats.begin(), prof_stats->block_stats.end());
if (old_state == Core::CORE_RUN)
Core::SetState(Core::CORE_RUN);
}
int GetHostCode(u32* address, const u8** code, u32* code_size)
{
if (!jit)
{
PanicAlert("Failed to open %s", filename.c_str());
return;
*code_size = 0;
return 1;
}
fprintf(f.GetHandle(), "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n");
for (auto& stat : stats)
int block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(*address);
if (block_num < 0)
{
const JitBlock *block = jit->GetBlockCache()->GetBlock(stat.blockNum);
if (block)
for (int i = 0; i < 500; i++)
{
std::string name = g_symbolDB.GetDescription(block->originalAddress);
double percent = 100.0 * (double)stat.cost / (double)cost_sum;
double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum;
fprintf(f.GetHandle(), "%08x\t%s\t%" PRIu64 "\t%" PRIu64 "\t%.2f\t%.2f\t%.2f\t%i\n",
block->originalAddress, name.c_str(), stat.cost,
block->ticCounter, percent, timePercent,
(double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize);
block_num = jit->GetBlockCache()->GetBlockNumberFromStartAddress(*address - 4 * i);
if (block_num >= 0)
break;
}
if (block_num >= 0)
{
JitBlock* block = jit->GetBlockCache()->GetBlock(block_num);
if (!(block->originalAddress <= *address &&
block->originalSize + block->originalAddress >= *address))
block_num = -1;
}
// Do not merge this "if" with the above - block_num changes inside it.
if (block_num < 0)
{
*code_size = 0;
return 2;
}
}
if (old_state == PowerPC::CPUState::CPU_RUNNING)
PowerPC::Start();
JitBlock* block = jit->GetBlockCache()->GetBlock(block_num);
*code = (const u8*)jit->GetBlockCache()->GetCompiledCodeFromBlock(block_num);
*code_size = block->codeSize;
*address = block->originalAddress;
return 0;
}
bool HandleFault(uintptr_t access_address, SContext* ctx)
{
return jit->HandleFault(access_address, ctx);