2016-12-08 19:30:41 -05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using System.Collections;
|
2016-12-11 14:25:29 -05:00
|
|
|
|
using Mesen.GUI.Controls;
|
2016-12-08 19:30:41 -05:00
|
|
|
|
|
|
|
|
|
namespace Mesen.GUI.Debugger.Controls
|
|
|
|
|
{
|
2016-12-11 14:25:29 -05:00
|
|
|
|
public partial class ctrlProfiler : BaseControl
|
2016-12-08 19:30:41 -05:00
|
|
|
|
{
|
2016-12-09 00:12:38 -05:00
|
|
|
|
public static event EventHandler OnFunctionSelected;
|
2016-12-08 19:30:41 -05:00
|
|
|
|
private Int64[] _exclusiveTime;
|
|
|
|
|
private Int64[] _inclusiveTime;
|
|
|
|
|
private Int64[] _callCount;
|
2017-09-28 21:10:48 -04:00
|
|
|
|
private object _resetLock = new object();
|
2016-12-08 19:30:41 -05:00
|
|
|
|
|
2016-12-09 00:12:38 -05:00
|
|
|
|
private int _sortColumn = 5;
|
|
|
|
|
private bool _sortOrder = true;
|
2016-12-08 19:30:41 -05:00
|
|
|
|
|
|
|
|
|
public ctrlProfiler()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
|
|
|
|
|
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
|
|
|
|
if(!designMode) {
|
|
|
|
|
lstFunctions.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RefreshData()
|
|
|
|
|
{
|
2017-09-28 21:10:48 -04:00
|
|
|
|
lock(_resetLock) {
|
|
|
|
|
_exclusiveTime = InteropEmu.DebugGetProfilerData(ProfilerDataType.FunctionExclusive);
|
|
|
|
|
_inclusiveTime = InteropEmu.DebugGetProfilerData(ProfilerDataType.FunctionInclusive);
|
|
|
|
|
_callCount = InteropEmu.DebugGetProfilerData(ProfilerDataType.FunctionCallCount);
|
|
|
|
|
}
|
2016-12-08 19:30:41 -05:00
|
|
|
|
RefreshList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetMaxAddrHexSize()
|
|
|
|
|
{
|
|
|
|
|
int size = _exclusiveTime.Length - 2;
|
|
|
|
|
int bitCount = 0;
|
|
|
|
|
int hexCount = 1;
|
|
|
|
|
while(size > 0) {
|
|
|
|
|
size /= 2;
|
|
|
|
|
if(bitCount == 4) {
|
|
|
|
|
hexCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hexCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RefreshList()
|
|
|
|
|
{
|
|
|
|
|
Int64 exclusiveTotal = _exclusiveTime.Sum();
|
|
|
|
|
|
|
|
|
|
int hexCount = GetMaxAddrHexSize();
|
|
|
|
|
|
|
|
|
|
lstFunctions.BeginUpdate();
|
|
|
|
|
lstFunctions.ListViewItemSorter = null;
|
|
|
|
|
lstFunctions.Items.Clear();
|
2016-12-09 00:12:38 -05:00
|
|
|
|
for(UInt32 i = 0; i < _exclusiveTime.Length; i++) {
|
2016-12-08 19:30:41 -05:00
|
|
|
|
if(_exclusiveTime[i] > 0) {
|
|
|
|
|
string functionName;
|
|
|
|
|
|
|
|
|
|
if(i == _exclusiveTime.Length - 2) {
|
|
|
|
|
functionName = "[Reset]";
|
|
|
|
|
} else if(i == _exclusiveTime.Length - 1) {
|
|
|
|
|
functionName = "[In-Memory Function]";
|
|
|
|
|
} else {
|
|
|
|
|
CodeLabel label = LabelManager.GetLabel((UInt32)i, AddressType.PrgRom);
|
|
|
|
|
functionName = "$" + i.ToString("X" + hexCount.ToString());
|
|
|
|
|
if(label != null) {
|
|
|
|
|
functionName = label.Label + " (" + functionName + ")";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ListViewItem item = lstFunctions.Items.Add(functionName);
|
2016-12-09 00:12:38 -05:00
|
|
|
|
item.Tag = i;
|
|
|
|
|
|
2016-12-08 19:30:41 -05:00
|
|
|
|
item.SubItems.Add(_callCount[i].ToString());
|
|
|
|
|
item.SubItems[1].Tag = _callCount[i];
|
|
|
|
|
|
|
|
|
|
item.SubItems.Add(_inclusiveTime[i].ToString());
|
|
|
|
|
item.SubItems[2].Tag = _inclusiveTime[i];
|
|
|
|
|
|
|
|
|
|
double ratio = ((double)_inclusiveTime[i] / exclusiveTotal)*100;
|
|
|
|
|
item.SubItems.Add(ratio.ToString("0.00"));
|
|
|
|
|
item.SubItems[3].Tag = (Int64)(ratio*100);
|
|
|
|
|
|
|
|
|
|
item.SubItems.Add(_exclusiveTime[i].ToString());
|
|
|
|
|
item.SubItems[4].Tag = _exclusiveTime[i];
|
|
|
|
|
|
|
|
|
|
ratio = ((double)_exclusiveTime[i] / exclusiveTotal)*100;
|
|
|
|
|
item.SubItems.Add(ratio.ToString("0.00"));
|
|
|
|
|
item.SubItems[5].Tag = (Int64)(ratio*100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lstFunctions.ListViewItemSorter = new ListComparer(_sortColumn, _sortOrder);
|
|
|
|
|
lstFunctions.EndUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void btnReset_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2017-09-28 21:10:48 -04:00
|
|
|
|
lock(_resetLock) {
|
|
|
|
|
InteropEmu.DebugResetProfiler();
|
|
|
|
|
}
|
2016-12-08 19:30:41 -05:00
|
|
|
|
RefreshData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void btnRefresh_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.RefreshData();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void lstFunctions_ColumnClick(object sender, ColumnClickEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(_sortColumn == e.Column) {
|
|
|
|
|
_sortOrder = !_sortOrder;
|
|
|
|
|
} else {
|
|
|
|
|
_sortColumn = e.Column;
|
|
|
|
|
_sortOrder = e.Column == 0 ? false : true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RefreshList();
|
|
|
|
|
}
|
2016-12-09 00:12:38 -05:00
|
|
|
|
|
|
|
|
|
private void lstFunctions_DoubleClick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(lstFunctions.SelectedItems.Count > 0) {
|
|
|
|
|
OnFunctionSelected?.Invoke(lstFunctions.SelectedItems[0].Tag, EventArgs.Empty);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-12-08 19:30:41 -05:00
|
|
|
|
|
|
|
|
|
private class ListComparer : IComparer
|
|
|
|
|
{
|
|
|
|
|
private int _columnIndex;
|
|
|
|
|
private bool _sortOrder;
|
|
|
|
|
|
|
|
|
|
public ListComparer(int columnIndex, bool sortOrder)
|
|
|
|
|
{
|
|
|
|
|
_columnIndex = columnIndex;
|
|
|
|
|
_sortOrder = sortOrder;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Compare(object x, object y)
|
|
|
|
|
{
|
|
|
|
|
if(_columnIndex == 0) {
|
|
|
|
|
if(_sortOrder) {
|
|
|
|
|
return String.Compare(((ListViewItem)y).SubItems[0].Text, ((ListViewItem)x).SubItems[0].Text);
|
|
|
|
|
} else {
|
|
|
|
|
return String.Compare(((ListViewItem)x).SubItems[0].Text, ((ListViewItem)y).SubItems[0].Text);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(_sortOrder) {
|
|
|
|
|
return (Int64)((ListViewItem)y).SubItems[_columnIndex].Tag > (Int64)((ListViewItem)x).SubItems[_columnIndex].Tag ? 1 : -1;
|
|
|
|
|
} else {
|
|
|
|
|
return (Int64)((ListViewItem)y).SubItems[_columnIndex].Tag > (Int64)((ListViewItem)x).SubItems[_columnIndex].Tag ? -1 : 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|