From 0ba3948c427c2588d1b1bb143183738da9662bae Mon Sep 17 00:00:00 2001 From: "memberTwo.mb2" Date: Sat, 13 Sep 2008 20:58:24 +0000 Subject: [PATCH] JIT profiler: in block performance counter. MemoryView: raw memory display. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@522 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/Core/Src/Debugger/DebugInterface.h | 1 + .../Core/Src/Debugger/PPCDebugInterface.cpp | 19 ++++++++++++ .../Core/Src/Debugger/PPCDebugInterface.h | 1 + Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 21 ++++++++++++- Source/Core/Core/Src/PowerPC/Jit64/JitCache.h | 10 +++++++ Source/Core/Core/Src/PowerPC/Profiler.cpp | 30 +++++++++++++++---- Source/Core/Core/Src/PowerPC/Profiler.h | 28 +++++++++++++++++ Source/Core/DebuggerWX/src/MemoryView.cpp | 15 ++++++---- Source/Core/DebuggerWX/src/MemoryWindow.cpp | 13 ++++---- 9 files changed, 120 insertions(+), 18 deletions(-) diff --git a/Source/Core/Core/Src/Debugger/DebugInterface.h b/Source/Core/Core/Src/Debugger/DebugInterface.h index 896f514cbb..dcff6e65af 100644 --- a/Source/Core/Core/Src/Debugger/DebugInterface.h +++ b/Source/Core/Core/Src/Debugger/DebugInterface.h @@ -9,6 +9,7 @@ protected: virtual ~DebugInterface() {} public: virtual const char *disasm(unsigned int /*address*/) {return "NODEBUGGER";} + virtual const char *getRawMemoryString(unsigned int /*address*/){return "NODEBUGGER";} virtual int getInstructionSize(int /*instruction*/) {return 1;} virtual bool isAlive() {return true;} diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp index 65527fa768..0bffbb465b 100644 --- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp @@ -42,6 +42,25 @@ const char *PPCDebugInterface::disasm(unsigned int address) return tmp; } +const char *PPCDebugInterface::getRawMemoryString(unsigned int address) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + if (address < 0xE0000000) + { + static char str[256] ={0}; + if (sprintf(str,"%08X",readMemory(address))!=8) { + PanicAlert("getRawMemoryString -> WTF! ( as read somewhere;) )"); + return ":("; + } + return str; + } + return "No RAM"; + } + static const char tmp[] = ""; + return tmp; +} + unsigned int PPCDebugInterface::readMemory(unsigned int address) { return Memory::ReadUnchecked_U32(address); diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.h b/Source/Core/Core/Src/Debugger/PPCDebugInterface.h index 4d0a5cf31e..ce4d6601b6 100644 --- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.h +++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.h @@ -12,6 +12,7 @@ class PPCDebugInterface : public DebugInterface public: PPCDebugInterface(){} virtual const char *disasm(unsigned int address); + virtual const char *getRawMemoryString(unsigned int address); virtual int getInstructionSize(int instruction) {return 4;} virtual bool isAlive(); virtual bool isBreakpoint(unsigned int address); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index c94b29e599..a047f8c73e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -398,6 +398,15 @@ namespace Jit64 if (Profiler::g_ProfileBlocks) { ADD(32, M(&b.runCount), Imm8(1)); +#ifdef _WIN32 + b.ticCounter.QuadPart = 0; + b.ticStart.QuadPart = 0; + b.ticStop.QuadPart = 0; +#else +//TODO +#endif + // get start tic + PROFILER_QUERY_PERFORMACE_COUNTER(&b.ticStart); } //Start up the register allocators @@ -416,8 +425,18 @@ namespace Jit64 js.compilerPC = ops[i].address; js.op = &ops[i]; js.instructionNumber = i; - if (i == (int)size - 1) + if (i == (int)size - 1) { js.isLastInstruction = true; + if (Profiler::g_ProfileBlocks) { + // CAUTION!!! push on stack regs you use, do your stuff, then pop + PROFILER_VPUSH; + // get end tic + PROFILER_QUERY_PERFORMACE_COUNTER(&b.ticStop); + // tic counter += (end tic - start tic) + PROFILER_ADD_DIFF_LARGE_INTEGER(&b.ticCounter, &b.ticStop, &b.ticStart); + PROFILER_VPOP; + } + } // const GekkoOpInfo *info = GetOpInfo(); // if (js.isLastInstruction) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h index ea7c86d8b0..8a459baae6 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitCache.h @@ -18,6 +18,9 @@ #define _JITCACHE_H #include "../Gekko.h" +#ifdef _WIN32 +#include // -> LARGE_INTEGER +#endif namespace Jit64 { @@ -52,6 +55,13 @@ namespace Jit64 u32 codeSize; u32 originalSize; int runCount; // for profiling. +#ifdef _WIN32 + // we don't really need to save start and stop + // TODO (mb2): ticStart and ticStop -> "local var" mean "in block" ... low priority ;) + LARGE_INTEGER ticStart; // for profiling - time. + LARGE_INTEGER ticStop; // for profiling - time. + LARGE_INTEGER ticCounter; // for profiling - time. +#endif const u8 *checkedEntry; bool invalid; int flags; diff --git a/Source/Core/Core/Src/PowerPC/Profiler.cpp b/Source/Core/Core/Src/PowerPC/Profiler.cpp index 84d5cc6612..6cc8c51d3a 100644 --- a/Source/Core/Core/Src/PowerPC/Profiler.cpp +++ b/Source/Core/Core/Src/PowerPC/Profiler.cpp @@ -30,9 +30,9 @@ bool g_ProfileInstructions; struct BlockStat { - BlockStat(int bn, int c) : blockNum(bn), cost(c) {} + BlockStat(int bn, u64 c) : blockNum(bn), cost(c) {} int blockNum; - int cost; + u64 cost; bool operator <(const BlockStat &other) const { return cost > other.cost; @@ -43,14 +43,25 @@ void WriteProfileResults(const char *filename) { std::vector stats; stats.reserve(Jit64::GetNumBlocks()); u64 cost_sum = 0; +#ifdef _WIN32 + u64 timecost_sum = 0; + LARGE_INTEGER countsPerSec; + QueryPerformanceFrequency(&countsPerSec); +#endif for (int i = 0; i < Jit64::GetNumBlocks(); i++) { const Jit64::JitBlock *block = Jit64::GetBlock(i); - int cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more. + u64 cost = (block->originalSize / 4) * block->runCount; // rough heuristic. mem instructions should cost more. +#ifdef _WIN32 + u64 timecost = block->ticCounter.QuadPart; // Indeed ;) +#endif if (block->runCount >= 1) { // Todo: tweak. stats.push_back(BlockStat(i, cost)); } cost_sum += cost; +#ifdef _WIN32 + timecost_sum += timecost; +#endif } sort(stats.begin(), stats.end()); @@ -59,14 +70,21 @@ void WriteProfileResults(const char *filename) { PanicAlert("failed to open %s", filename); return; } - fprintf(f, "Profile\n"); + fprintf(f, "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n"); for (unsigned int i = 0; i < stats.size(); i++) { const Jit64::JitBlock *block = Jit64::GetBlock(stats[i].blockNum); if (block) { std::string name = g_symbolDB.GetDescription(block->originalAddress); - double percent = 100 * (double)stats[i].cost / (double)cost_sum; - fprintf(f, "%08x - %s - %i (%f%%)\n", block->originalAddress, name.c_str(), stats[i].cost, percent); + double percent = 100.0 * (double)stats[i].cost / (double)cost_sum; +#ifdef _WIN32 + double timePercent = 100.0 * (double)block->ticCounter.QuadPart / (double)timecost_sum; + fprintf(f, "%08x\t%s\t%llu\t%llu\t%llf\t%llf\t%lf\t%i\n", + block->originalAddress, name.c_str(), stats[i].cost, block->ticCounter.QuadPart, percent, timePercent, (double)block->ticCounter.QuadPart*1000.0/(double)countsPerSec.QuadPart, block->codeSize); +#else + fprintf(f, "%08x\t%s\t%llu\t???\t%llf\t???\t???\t%i\n", + block->originalAddress, name.c_str(), stats[i].cost, /*block->ticCounter.QuadPart,*/ percent, /*timePercent, (double)block->ticCounter.QuadPart*1000.0/(double)countsPerSec.QuadPart,*/ block->codeSize); +#endif } } fclose(f); diff --git a/Source/Core/Core/Src/PowerPC/Profiler.h b/Source/Core/Core/Src/PowerPC/Profiler.h index f3d6aa5121..0dae6dbfd1 100644 --- a/Source/Core/Core/Src/PowerPC/Profiler.h +++ b/Source/Core/Core/Src/PowerPC/Profiler.h @@ -19,6 +19,34 @@ #ifndef _PROFILER_H #define _PROFILER_H +#ifdef _WIN32 +#define PROFILER_QUERY_PERFORMACE_COUNTER(pt) \ + LEA(32, EAX, M(pt)); PUSH(EAX); \ + CALL(QueryPerformanceCounter) +// TODO: r64 way +// asm write : (u64) dt += t1-t0 +#define PROFILER_ADD_DIFF_LARGE_INTEGER(pdt, pt1, pt0) \ + MOV(32, R(EAX), M(pt1.LowPart)); \ + SUB(32, R(EAX), M(pt0.LowPart)); \ + MOV(32, R(ECX), M(pt1.HighPart)); \ + SBB(32, R(ECX), M(pt0.HighPart)); \ + ADD(32, R(EAX), M(pdt.LowPart)); \ + MOV(32, R(EDX), M(pdt.HighPart)); \ + ADC(32, R(EDX), R(ECX)); \ + MOV(32, M(pdt.LowPart), R(EAX)); \ + MOV(32, M(pdt.HighPart), R(EDX)) + +#define PROFILER_VPUSH PUSH(EAX);PUSH(ECX);PUSH(EDX) +#define PROFILER_VPOP POP(EDX);POP(ECX);POP(EAX) +#else +// TODO +#define PROFILER_QUERY_PERFORMACE_COUNTER(pt) +#define PROFILER_ADD_DIFF_LARGE_INTEGER(pdt, pt1, pt0) +#define PROFILER_VPUSH +#define PROFILER_VPOP +#endif + + namespace Profiler { extern bool g_ProfileBlocks; diff --git a/Source/Core/DebuggerWX/src/MemoryView.cpp b/Source/Core/DebuggerWX/src/MemoryView.cpp index cec77bb559..d6ffd0a9b0 100644 --- a/Source/Core/DebuggerWX/src/MemoryView.cpp +++ b/Source/Core/DebuggerWX/src/MemoryView.cpp @@ -223,8 +223,9 @@ void CMemoryView::OnErase(wxEraseEvent& event) void CMemoryView::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this); + int fontSize = 8; wxRect rc = GetClientRect(); - wxFont font(7, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT); + wxFont font(fontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_LIGHT); dc.SetFont(font); struct branch { @@ -254,7 +255,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) dc.SetPen(nullPen); dc.SetBrush(bgBrush); dc.DrawRectangle(0, 0, 16, rc.height); - dc.DrawRectangle(0, 0, rc.width, 5); + dc.DrawRectangle(0, 0, rc.width, 5+8); // TODO - clean up this freaking mess!!!!! int i; @@ -294,6 +295,10 @@ void CMemoryView::OnPaint(wxPaintEvent& event) dc.SetBrush(currentBrush); dc.SetTextForeground(_T("#600000")); dc.DrawText(temp, 17, rowY1); + char mem[256] = {0}; + strcpy(mem, debugger->getRawMemoryString(address)); + dc.SetTextForeground(_T("#000080")); + dc.DrawText(wxString::FromAscii(mem), 17+fontSize*(8), rowY1); dc.SetTextForeground(_T("#000000")); if (debugger->isAlive()) @@ -347,7 +352,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) dc.SetTextForeground(_T("#000000")); } - dc.DrawText(wxString::FromAscii(dis2), 126, rowY1); + dc.DrawText(wxString::FromAscii(dis2), 17+fontSize*(8+8+8), rowY1); } if (strcmp(dis, "blr")) @@ -359,7 +364,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) dc.SetTextForeground(_T("#8000FF")); } - dc.DrawText(wxString::FromAscii(dis), 70, rowY1); + dc.DrawText(wxString::FromAscii(dis), 17+fontSize*(8+8), rowY1); if (desc[0] == 0) { @@ -372,7 +377,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE); if (strlen(desc)) { - dc.DrawText(wxString::FromAscii(desc), 235, rowY1); + dc.DrawText(wxString::FromAscii(desc), 17+fontSize*(8+8+8+30), rowY1); } if (debugger->isBreakpoint(address)) diff --git a/Source/Core/DebuggerWX/src/MemoryWindow.cpp b/Source/Core/DebuggerWX/src/MemoryWindow.cpp index 879b59c7c8..5d710fcb2d 100644 --- a/Source/Core/DebuggerWX/src/MemoryWindow.cpp +++ b/Source/Core/DebuggerWX/src/MemoryWindow.cpp @@ -70,14 +70,15 @@ CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id, { wxBoxSizer* sizerBig = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sizerRight = new wxBoxSizer(wxVERTICAL); - wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL); + // didn't see anything usefull in the left part + //wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL); DebugInterface* di = new PPCDebugInterface(); - sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); + //sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(20, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); memview = new CMemoryView(di, this, wxID_ANY); - sizerBig->Add(sizerLeft, 2, wxEXPAND); - sizerBig->Add(memview, 5, wxEXPAND); + //sizerBig->Add(sizerLeft, 1, wxEXPAND); + sizerBig->Add(memview, 20, wxEXPAND); sizerBig->Add(sizerRight, 0, wxEXPAND | wxALL, 3); sizerRight->Add(buttonGo = new wxButton(this, IDM_DEBUG_GO, _T("&Go"))); sizerRight->Add(addrbox = new wxTextCtrl(this, IDM_ADDRBOX, _T(""))); @@ -85,8 +86,8 @@ CMemoryWindow::CMemoryWindow(wxWindow* parent, wxWindowID id, SetSizer(sizerBig); - sizerLeft->SetSizeHints(this); - sizerLeft->Fit(this); + //sizerLeft->SetSizeHints(this); + //sizerLeft->Fit(this); sizerRight->SetSizeHints(this); sizerRight->Fit(this); sizerBig->SetSizeHints(this);