mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-31 01:59:52 -06:00
Merge pull request #2494 from Sonicadvance1/common_disassembler
Break out the disassembler code from the WXWidgets UI.
This commit is contained in:
@ -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);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Core/MachineContext.h"
|
||||
#include "Core/PowerPC/CPUCoreBase.h"
|
||||
#include "Core/PowerPC/Profiler.h"
|
||||
|
||||
namespace JitInterface
|
||||
{
|
||||
@ -25,6 +26,8 @@ namespace JitInterface
|
||||
|
||||
// Debugging
|
||||
void WriteProfileResults(const std::string& filename);
|
||||
void GetProfileResults(ProfileStats* prof_stats);
|
||||
int GetHostCode(u32* address, const u8** code, u32* code_size);
|
||||
|
||||
// Memory Utilities
|
||||
bool HandleFault(uintptr_t access_address, SContext* ctx);
|
||||
|
@ -44,13 +44,24 @@
|
||||
|
||||
struct BlockStat
|
||||
{
|
||||
BlockStat(int bn, u64 c) : blockNum(bn), cost(c) {}
|
||||
BlockStat(int bn, u32 _addr, u64 c, u64 ticks, u32 size) :
|
||||
blockNum(bn), addr(_addr), cost(c), tick_counter(ticks), block_size(size) {}
|
||||
int blockNum;
|
||||
u32 addr;
|
||||
u64 cost;
|
||||
u64 tick_counter;
|
||||
u32 block_size;
|
||||
|
||||
bool operator <(const BlockStat &other) const
|
||||
{ return cost > other.cost; }
|
||||
};
|
||||
struct ProfileStats
|
||||
{
|
||||
std::vector<BlockStat> block_stats;
|
||||
u64 cost_sum;
|
||||
u64 timecost_sum;
|
||||
u64 countsPerSec;
|
||||
};
|
||||
|
||||
namespace Profiler
|
||||
{
|
||||
|
Reference in New Issue
Block a user