mirror of https://github.com/buggins/dlangide.git
DMD profiling on windows workaround
This commit is contained in:
parent
f36056d37e
commit
b412b9a037
|
@ -38,13 +38,13 @@ void sortFunctionNodes(FunctionNode[] nodes, TraceSortOrder sortOrder) {
|
||||||
import std.algorithm.sorting : sort;
|
import std.algorithm.sorting : sort;
|
||||||
final switch(sortOrder) {
|
final switch(sortOrder) {
|
||||||
case TraceSortOrder.BY_FUNCTION_TIME:
|
case TraceSortOrder.BY_FUNCTION_TIME:
|
||||||
sort!((a,b) => a.function_time < b.function_time)(nodes);
|
sort!((a,b) => a.function_time > b.function_time)(nodes);
|
||||||
break;
|
break;
|
||||||
case TraceSortOrder.BY_TOTAL_TIME:
|
case TraceSortOrder.BY_TOTAL_TIME:
|
||||||
sort!((a,b) => a.function_and_descendant_time < b.function_and_descendant_time)(nodes);
|
sort!((a,b) => a.function_and_descendant_time > b.function_and_descendant_time)(nodes);
|
||||||
break;
|
break;
|
||||||
case TraceSortOrder.BY_CALL_COUNT:
|
case TraceSortOrder.BY_CALL_COUNT:
|
||||||
sort!((a,b) => a.number_of_calls < b.number_of_calls)(nodes);
|
sort!((a,b) => a.number_of_calls > b.number_of_calls)(nodes);
|
||||||
break;
|
break;
|
||||||
case TraceSortOrder.BY_NAME:
|
case TraceSortOrder.BY_NAME:
|
||||||
sort!((a,b) => a.name < b.name)(nodes);
|
sort!((a,b) => a.name < b.name)(nodes);
|
||||||
|
@ -65,7 +65,7 @@ class DMDTraceLogParser {
|
||||||
FunctionNode[] nodesByName;
|
FunctionNode[] nodesByName;
|
||||||
//FunctionEdge[string] caller_graph;
|
//FunctionEdge[string] caller_graph;
|
||||||
//FunctionEdge[string] called_graph;
|
//FunctionEdge[string] called_graph;
|
||||||
private ulong ticks_per_second;
|
ulong ticks_per_second;
|
||||||
|
|
||||||
this(string fname) {
|
this(string fname) {
|
||||||
filename = fname;
|
filename = fname;
|
||||||
|
@ -187,6 +187,11 @@ class DMDTraceLogParser {
|
||||||
caller = false;
|
caller = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (function_name.length != 0)
|
||||||
|
{
|
||||||
|
nodes[text(function_name)] = new FunctionNode(function_name,
|
||||||
|
function_times, function_and_descendant, function_only, caller_graph, called_graph);
|
||||||
|
}
|
||||||
makeSorted();
|
makeSorted();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ module dlangide.ui.dmdprofilerview;
|
||||||
|
|
||||||
import dlangui.widgets.layouts;
|
import dlangui.widgets.layouts;
|
||||||
import dlangui.widgets.widget;
|
import dlangui.widgets.widget;
|
||||||
|
import dlangui.widgets.grid;
|
||||||
import dlangui.widgets.scroll;
|
import dlangui.widgets.scroll;
|
||||||
import dlangui.widgets.controls;
|
import dlangui.widgets.controls;
|
||||||
import dlangide.ui.frame;
|
import dlangide.ui.frame;
|
||||||
|
@ -9,13 +10,291 @@ import dlangide.ui.commands;
|
||||||
import dlangui.core.i18n;
|
import dlangui.core.i18n;
|
||||||
import dlangide.tools.d.dmdtrace;
|
import dlangide.tools.d.dmdtrace;
|
||||||
|
|
||||||
class DMDProfilerView : ScrollWidget {
|
class DMDProfilerView : WidgetGroupDefaultDrawing {
|
||||||
protected IDEFrame _frame;
|
protected IDEFrame _frame;
|
||||||
protected DMDTraceLogParser _data;
|
protected DMDTraceLogParser _data;
|
||||||
|
protected TraceFunctionList _fullFunctionList;
|
||||||
this(string ID, IDEFrame frame, DMDTraceLogParser data) {
|
this(string ID, IDEFrame frame, DMDTraceLogParser data) {
|
||||||
super(ID);
|
super(ID);
|
||||||
_frame = frame;
|
_frame = frame;
|
||||||
_data = data;
|
_data = data;
|
||||||
contentWidget = new TextWidget(null, "DMD profiler view"d);
|
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
|
_fullFunctionList = new TraceFunctionList("FULL_FUNCTION_LIST", "All functions"d, _data.nodesByTotalTime, _data.ticks_per_second); // new TextWidget(null, "DMD profiler view"d);
|
||||||
|
addChild(_fullFunctionList);
|
||||||
|
}
|
||||||
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
|
override void layout(Rect rc) {
|
||||||
|
super.layout(rc);
|
||||||
|
applyMargins(rc);
|
||||||
|
applyPadding(rc);
|
||||||
|
Rect rc1 = rc;
|
||||||
|
rc1.right = rc1.left + rc.width / 2;
|
||||||
|
_fullFunctionList.layout(rc1);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
Measure widget according to desired width and height constraints. (Step 1 of two phase layout).
|
||||||
|
|
||||||
|
*/
|
||||||
|
override void measure(int parentWidth, int parentHeight) {
|
||||||
|
_fullFunctionList.measure(parentWidth, parentHeight);
|
||||||
|
measuredContent(parentWidth, parentHeight, _fullFunctionList.measuredWidth, _fullFunctionList.measuredHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TraceFuncionGrid : StringGridWidgetBase {
|
||||||
|
protected FunctionNode[] _list;
|
||||||
|
protected dstring[] _colTitles;
|
||||||
|
protected ulong _ticksPerSecond;
|
||||||
|
this(string ID, FunctionNode[] list, ulong ticks_per_second) {
|
||||||
|
super(ID);
|
||||||
|
_ticksPerSecond = ticks_per_second;
|
||||||
|
_list = list;
|
||||||
|
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
|
fullColumnOnLeft(false);
|
||||||
|
fullRowOnTop(false);
|
||||||
|
resize(4, cast(int)list.length);
|
||||||
|
setColTitle(0, "Function name"d);
|
||||||
|
setColTitle(1, "Called"d);
|
||||||
|
setColTitle(2, "F us"d);
|
||||||
|
setColTitle(3, "F+D us"d);
|
||||||
|
showRowHeaders = false;
|
||||||
|
rowSelect = true;
|
||||||
|
minVisibleRows = 10;
|
||||||
|
minVisibleCols = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private dchar[128] _numberFormatBuf;
|
||||||
|
dstring formatNumber(ulong v, dchar[] buffer) {
|
||||||
|
dchar[64] buf;
|
||||||
|
int k = 0;
|
||||||
|
if (!v) {
|
||||||
|
buf[k++] = '0';
|
||||||
|
} else {
|
||||||
|
while (v) {
|
||||||
|
buf[k++] = '0' + (cast(int)(v % 10));
|
||||||
|
v /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// reverse order
|
||||||
|
for (int i = 0; i < k; i++)
|
||||||
|
buffer[i] = buf[k - i - 1];
|
||||||
|
return cast(dstring)buffer[0..k];
|
||||||
|
}
|
||||||
|
dstring formatDurationTicks(ulong n) {
|
||||||
|
ulong v = n * 1000000 / _ticksPerSecond;
|
||||||
|
return formatNumber(v, _numberFormatBuf[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// get cell text
|
||||||
|
override dstring cellText(int col, int row) {
|
||||||
|
if (row < 0 || row >= _list.length)
|
||||||
|
return ""d;
|
||||||
|
FunctionNode entry = _list[row];
|
||||||
|
switch (col) {
|
||||||
|
case 0:
|
||||||
|
string fn = entry.name;
|
||||||
|
if (fn.length > 256)
|
||||||
|
fn = fn[0..256] ~ "...";
|
||||||
|
return fn.to!dstring;
|
||||||
|
case 1:
|
||||||
|
return formatNumber(entry.number_of_calls, _numberFormatBuf);
|
||||||
|
case 2:
|
||||||
|
return formatDurationTicks(entry.function_time);
|
||||||
|
case 3:
|
||||||
|
return formatDurationTicks(entry.function_and_descendant_time);
|
||||||
|
default:
|
||||||
|
return ""d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// set cell text
|
||||||
|
override StringGridWidgetBase setCellText(int col, int row, dstring text) {
|
||||||
|
// do nothing
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/// returns row header title
|
||||||
|
override dstring rowTitle(int row) {
|
||||||
|
return ""d;
|
||||||
|
}
|
||||||
|
/// set row header title
|
||||||
|
override StringGridWidgetBase setRowTitle(int row, dstring title) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns row header title
|
||||||
|
override dstring colTitle(int col) {
|
||||||
|
return _colTitles[col];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set col header title
|
||||||
|
override StringGridWidgetBase setColTitle(int col, dstring title) {
|
||||||
|
_colTitles[col] = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void autofit() {
|
||||||
|
autoFitColumnWidths();
|
||||||
|
fillColumnWidth(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set new size
|
||||||
|
override void resize(int c, int r) {
|
||||||
|
if (c == cols && r == rows)
|
||||||
|
return;
|
||||||
|
int oldcols = cols;
|
||||||
|
int oldrows = rows;
|
||||||
|
super.resize(c, r);
|
||||||
|
_colTitles.length = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Point measureCell(int x, int y) {
|
||||||
|
if (_customCellAdapter && _customCellAdapter.isCustomCell(x, y)) {
|
||||||
|
return _customCellAdapter.measureCell(x, y);
|
||||||
|
}
|
||||||
|
//Log.d("measureCell ", x, ", ", y);
|
||||||
|
FontRef fnt = font;
|
||||||
|
dstring txt;
|
||||||
|
if (x >= 0 && y >= 0)
|
||||||
|
txt = cellText(x, y);
|
||||||
|
else if (y < 0 && x >= 0)
|
||||||
|
txt = colTitle(x);
|
||||||
|
else if (y >= 0 && x < 0)
|
||||||
|
txt = rowTitle(y);
|
||||||
|
Point sz = fnt.textSize(txt);
|
||||||
|
if (sz.y < fnt.height)
|
||||||
|
sz.y = fnt.height;
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// draw cell content
|
||||||
|
protected override void drawCell(DrawBuf buf, Rect rc, int col, int row) {
|
||||||
|
if (_customCellAdapter && _customCellAdapter.isCustomCell(col, row)) {
|
||||||
|
return _customCellAdapter.drawCell(buf, rc, col, row);
|
||||||
|
}
|
||||||
|
if (BACKEND_GUI)
|
||||||
|
rc.shrink(2, 1);
|
||||||
|
else
|
||||||
|
rc.right--;
|
||||||
|
FontRef fnt = font;
|
||||||
|
dstring txt = cellText(col, row);
|
||||||
|
Point sz = fnt.textSize(txt);
|
||||||
|
Align ha = Align.Right;
|
||||||
|
//if (sz.y < rc.height)
|
||||||
|
applyAlign(rc, sz, ha, Align.VCenter);
|
||||||
|
int offset = BACKEND_CONSOLE ? 0 : 1;
|
||||||
|
fnt.drawText(buf, rc.left + offset, rc.top + offset, txt, textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// draw cell content
|
||||||
|
protected override void drawHeaderCell(DrawBuf buf, Rect rc, int col, int row) {
|
||||||
|
if (BACKEND_GUI)
|
||||||
|
rc.shrink(2, 1);
|
||||||
|
else
|
||||||
|
rc.right--;
|
||||||
|
FontRef fnt = font;
|
||||||
|
dstring txt;
|
||||||
|
if (row < 0 && col >= 0)
|
||||||
|
txt = colTitle(col);
|
||||||
|
else if (row >= 0 && col < 0)
|
||||||
|
txt = rowTitle(row);
|
||||||
|
if (!txt.length)
|
||||||
|
return;
|
||||||
|
Point sz = fnt.textSize(txt);
|
||||||
|
Align ha = Align.Left;
|
||||||
|
if (col < 0)
|
||||||
|
ha = Align.Right;
|
||||||
|
//if (row < 0)
|
||||||
|
// ha = Align.HCenter;
|
||||||
|
applyAlign(rc, sz, ha, Align.VCenter);
|
||||||
|
int offset = BACKEND_CONSOLE ? 0 : 1;
|
||||||
|
uint cl = textColor;
|
||||||
|
cl = style.customColor("grid_cell_text_color_header", cl);
|
||||||
|
fnt.drawText(buf, rc.left + offset, rc.top + offset, txt, cl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// draw cell background
|
||||||
|
protected override void drawHeaderCellBackground(DrawBuf buf, Rect rc, int c, int r) {
|
||||||
|
bool selectedCol = (c == col) && !_rowSelect;
|
||||||
|
bool selectedRow = r == row;
|
||||||
|
bool selectedCell = selectedCol && selectedRow;
|
||||||
|
if (_rowSelect && selectedRow)
|
||||||
|
selectedCell = true;
|
||||||
|
if (!selectedCell && _multiSelect) {
|
||||||
|
selectedCell = Point(c, r) in _selection || (_rowSelect && Point(0, r) in _selection);
|
||||||
|
}
|
||||||
|
// draw header cell background
|
||||||
|
DrawableRef dw = c < 0 ? _cellRowHeaderBackgroundDrawable : _cellHeaderBackgroundDrawable;
|
||||||
|
uint cl = _cellHeaderBackgroundColor;
|
||||||
|
if (c >= 0 || r >= 0) {
|
||||||
|
if (c < 0 && selectedRow) {
|
||||||
|
cl = _cellHeaderSelectedBackgroundColor;
|
||||||
|
dw = _cellRowHeaderSelectedBackgroundDrawable;
|
||||||
|
} else if (r < 0 && selectedCol) {
|
||||||
|
cl = _cellHeaderSelectedBackgroundColor;
|
||||||
|
dw = _cellHeaderSelectedBackgroundDrawable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!dw.isNull)
|
||||||
|
dw.drawTo(buf, rc);
|
||||||
|
else
|
||||||
|
buf.fillRect(rc, cl);
|
||||||
|
static if (BACKEND_GUI) {
|
||||||
|
uint borderColor = _cellHeaderBorderColor;
|
||||||
|
buf.drawLine(Point(rc.right - 1, rc.bottom), Point(rc.right - 1, rc.top), _cellHeaderBorderColor); // vertical
|
||||||
|
buf.drawLine(Point(rc.left, rc.bottom - 1), Point(rc.right - 1, rc.bottom - 1), _cellHeaderBorderColor); // horizontal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// draw cell background
|
||||||
|
protected override void drawCellBackground(DrawBuf buf, Rect rc, int c, int r) {
|
||||||
|
bool selectedCol = c == col;
|
||||||
|
bool selectedRow = r == row;
|
||||||
|
bool selectedCell = selectedCol && selectedRow;
|
||||||
|
if (_rowSelect && selectedRow)
|
||||||
|
selectedCell = true;
|
||||||
|
if (!selectedCell && _multiSelect) {
|
||||||
|
selectedCell = Point(c, r) in _selection || (_rowSelect && Point(0, r) in _selection);
|
||||||
|
}
|
||||||
|
uint borderColor = _cellBorderColor;
|
||||||
|
if (c < fixedCols || r < fixedRows) {
|
||||||
|
// fixed cell background
|
||||||
|
buf.fillRect(rc, _fixedCellBackgroundColor);
|
||||||
|
borderColor = _fixedCellBorderColor;
|
||||||
|
}
|
||||||
|
static if (BACKEND_GUI) {
|
||||||
|
buf.drawLine(Point(rc.left, rc.bottom + 1), Point(rc.left, rc.top), borderColor); // vertical
|
||||||
|
buf.drawLine(Point(rc.left, rc.bottom - 1), Point(rc.right - 1, rc.bottom - 1), borderColor); // horizontal
|
||||||
|
}
|
||||||
|
if (selectedCell) {
|
||||||
|
static if (BACKEND_GUI) {
|
||||||
|
if (_rowSelect)
|
||||||
|
buf.drawFrame(rc, _selectionColorRowSelect, Rect(0,1,0,1), _cellBorderColor);
|
||||||
|
else
|
||||||
|
buf.drawFrame(rc, _selectionColor, Rect(1,1,1,1), _cellBorderColor);
|
||||||
|
} else {
|
||||||
|
if (_rowSelect)
|
||||||
|
buf.fillRect(rc, _selectionColorRowSelect);
|
||||||
|
else
|
||||||
|
buf.fillRect(rc, _selectionColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
|
override void layout(Rect rc) {
|
||||||
|
super.layout(rc);
|
||||||
|
autofit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TraceFunctionList : VerticalLayout {
|
||||||
|
TraceFuncionGrid _grid;
|
||||||
|
|
||||||
|
this(string ID, dstring title, FunctionNode[] list, ulong ticks_per_second) {
|
||||||
|
super(ID);
|
||||||
|
addChild(new TextWidget("gridTitle", title).layoutWidth(FILL_PARENT));
|
||||||
|
_grid = new TraceFuncionGrid("FUNCTION_LIST", list, ticks_per_second);
|
||||||
|
addChild(_grid);
|
||||||
|
layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue