mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 1144423 - Display bytesize and percentages for both bytesize and counts in the allocations call tree. r=fitzgen,vp
This commit is contained in:
parent
e06dc9e42a
commit
2c501dbad6
@ -13,36 +13,75 @@ const { L10N } = require("devtools/performance/global");
|
||||
const { Heritage } = require("resource:///modules/devtools/ViewHelpers.jsm");
|
||||
const { AbstractTreeItem } = require("resource:///modules/devtools/AbstractTreeItem.jsm");
|
||||
|
||||
const MILLISECOND_UNITS = L10N.getStr("table.ms");
|
||||
const PERCENTAGE_UNITS = L10N.getStr("table.percentage");
|
||||
const URL_LABEL_TOOLTIP = L10N.getStr("table.url.tooltiptext");
|
||||
const VIEW_OPTIMIZATIONS_TOOLTIP = L10N.getStr("table.view-optimizations.tooltiptext");
|
||||
|
||||
const CALL_TREE_INDENTATION = 16; // px
|
||||
|
||||
// Used for rendering values in cells
|
||||
const FORMATTERS = {
|
||||
TIME: (value) => L10N.getFormatStr("table.ms2", L10N.numberWithDecimals(value, 2)),
|
||||
PERCENT: (value) => L10N.getFormatStr("table.percentage2", L10N.numberWithDecimals(value, 2)),
|
||||
NUMBER: (value) => value || 0,
|
||||
BYTESIZE: (value) => L10N.getFormatStr("table.bytes", (value || 0))
|
||||
};
|
||||
|
||||
/**
|
||||
* Definitions for rendering cells. Triads of class name, property name from
|
||||
* `frame.getInfo()`, and a formatter function.
|
||||
*/
|
||||
const CELLS = {
|
||||
duration: ["duration", "totalDuration", FORMATTERS.TIME],
|
||||
percentage: ["percentage", "totalPercentage", FORMATTERS.PERCENT],
|
||||
selfDuration: ["self-duration", "selfDuration", FORMATTERS.TIME],
|
||||
selfPercentage: ["self-percentage", "selfPercentage", FORMATTERS.PERCENT],
|
||||
samples: ["samples", "samples", FORMATTERS.NUMBER],
|
||||
|
||||
selfSize: ["self-size", "selfSize", FORMATTERS.BYTESIZE],
|
||||
selfSizePercentage: ["self-size-percentage", "selfSizePercentage", FORMATTERS.PERCENT],
|
||||
selfCount: ["self-count", "selfCount", FORMATTERS.NUMBER],
|
||||
selfCountPercentage: ["self-count-percentage", "selfCountPercentage", FORMATTERS.PERCENT],
|
||||
size: ["size", "totalSize", FORMATTERS.BYTESIZE],
|
||||
sizePercentage: ["size-percentage", "totalSizePercentage", FORMATTERS.PERCENT],
|
||||
count: ["count", "totalCount", FORMATTERS.NUMBER],
|
||||
countPercentage: ["count-percentage", "totalCountPercentage", FORMATTERS.PERCENT],
|
||||
};
|
||||
const CELL_TYPES = Object.keys(CELLS);
|
||||
|
||||
const DEFAULT_SORTING_PREDICATE = (frameA, frameB) => {
|
||||
let dataA = frameA.getDisplayedData();
|
||||
let dataB = frameB.getDisplayedData();
|
||||
if (this.inverted) {
|
||||
// Invert trees, sort by selfPercentage, and then totalPercentage
|
||||
if (dataA.selfPercentage === dataB.selfPercentage) {
|
||||
return dataA.totalPercentage < dataB.totalPercentage ? 1 : -1;
|
||||
}
|
||||
return dataA.selfPercentage < dataB.selfPercentage ? 1 : - 1;
|
||||
let isAllocations = "totalSize" in dataA;
|
||||
|
||||
if (isAllocations) {
|
||||
return this.inverted && dataA.selfSize !== dataB.selfSize ?
|
||||
(dataA.selfSize < dataB.selfSize ? 1 : - 1) :
|
||||
(dataA.totalSize < dataB.totalSize ? 1 : -1);
|
||||
}
|
||||
return dataA.totalPercentage < dataB.totalPercentage ? 1 : -1;
|
||||
|
||||
return this.inverted && dataA.selfPercentage !== dataB.selfPercentage ?
|
||||
(dataA.selfPercentage < dataB.selfPercentage ? 1 : - 1) :
|
||||
(dataA.totalPercentage < dataB.totalPercentage ? 1 : -1);
|
||||
};
|
||||
|
||||
const DEFAULT_AUTO_EXPAND_DEPTH = 3; // depth
|
||||
const DEFAULT_VISIBLE_CELLS = {
|
||||
duration: true,
|
||||
percentage: true,
|
||||
count: false,
|
||||
selfDuration: true,
|
||||
selfPercentage: true,
|
||||
selfCount: false,
|
||||
samples: true,
|
||||
function: true
|
||||
function: true,
|
||||
|
||||
// allocation columns
|
||||
count: false,
|
||||
selfCount: false,
|
||||
size: false,
|
||||
selfSize: false,
|
||||
countPercentage: false,
|
||||
selfCountPercentage: false,
|
||||
sizePercentage: false,
|
||||
selfSizePercentage: false,
|
||||
};
|
||||
|
||||
const clamp = (val, min, max) => Math.max(min, Math.min(max, val));
|
||||
@ -136,27 +175,14 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
let frameInfo = this.getDisplayedData();
|
||||
let cells = [];
|
||||
|
||||
if (this.visibleCells.duration) {
|
||||
cells.push(this._createTimeCell(document, frameInfo.totalDuration));
|
||||
}
|
||||
if (this.visibleCells.percentage) {
|
||||
cells.push(this._createExecutionCell(document, frameInfo.totalPercentage));
|
||||
}
|
||||
if (this.visibleCells.count) {
|
||||
cells.push(this._createCountCell(document, frameInfo.totalCount));
|
||||
}
|
||||
if (this.visibleCells.selfDuration) {
|
||||
cells.push(this._createTimeCell(document, frameInfo.selfDuration, true));
|
||||
}
|
||||
if (this.visibleCells.selfPercentage) {
|
||||
cells.push(this._createExecutionCell(document, frameInfo.selfPercentage, true));
|
||||
}
|
||||
if (this.visibleCells.selfCount) {
|
||||
cells.push(this._createCountCell(document, frameInfo.selfCount, true));
|
||||
}
|
||||
if (this.visibleCells.samples) {
|
||||
cells.push(this._createSamplesCell(document, frameInfo.samples));
|
||||
for (let type of CELL_TYPES) {
|
||||
if (this.visibleCells[type]) {
|
||||
// Inline for speed, but pass in the formatted value via
|
||||
// cell definition, as well as the element type.
|
||||
cells.push(this._createCell(document, CELLS[type][2](frameInfo[CELLS[type][1]]), CELLS[type][0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.visibleCells.function) {
|
||||
cells.push(this._createFunctionCell(document, arrowNode, frameInfo.name, frameInfo, this.level));
|
||||
}
|
||||
@ -204,38 +230,15 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
* Functions creating each cell in this call view.
|
||||
* Invoked by `_displaySelf`.
|
||||
*/
|
||||
_createTimeCell: function(doc, duration, isSelf = false) {
|
||||
_createCell: function (doc, value, type) {
|
||||
let cell = doc.createElement("description");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", isSelf ? "self-duration" : "duration");
|
||||
cell.setAttribute("type", type);
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", L10N.numberWithDecimals(duration, 2) + " " + MILLISECOND_UNITS);
|
||||
return cell;
|
||||
},
|
||||
_createExecutionCell: function(doc, percentage, isSelf = false) {
|
||||
let cell = doc.createElement("description");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", isSelf ? "self-percentage" : "percentage");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", L10N.numberWithDecimals(percentage, 2) + PERCENTAGE_UNITS);
|
||||
return cell;
|
||||
},
|
||||
_createCountCell: function(doc, count, isSelf = false) {
|
||||
let cell = doc.createElement("description");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", isSelf ? "self-count" : "count");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", count || 0);
|
||||
return cell;
|
||||
},
|
||||
_createSamplesCell: function(doc, count) {
|
||||
let cell = doc.createElement("description");
|
||||
cell.className = "plain call-tree-cell";
|
||||
cell.setAttribute("type", "samples");
|
||||
cell.setAttribute("crop", "end");
|
||||
cell.setAttribute("value", count || 0);
|
||||
cell.setAttribute("value", value);
|
||||
return cell;
|
||||
},
|
||||
|
||||
_createFunctionCell: function(doc, arrowNode, frameName, frameInfo, frameLevel) {
|
||||
let cell = doc.createElement("hbox");
|
||||
cell.className = "call-tree-cell";
|
||||
|
@ -308,15 +308,45 @@
|
||||
<vbox id="memory-calltree-view" flex="1">
|
||||
<hbox class="call-tree-headers-container">
|
||||
<label class="plain call-tree-header"
|
||||
type="count"
|
||||
type="self-size"
|
||||
crop="end"
|
||||
value="&performanceUI.table.totalAlloc;"
|
||||
value="Self Bytes"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-size-percentage"
|
||||
crop="end"
|
||||
value="Self Bytes %"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-count"
|
||||
crop="end"
|
||||
value="&performanceUI.table.selfAlloc;"
|
||||
tooltiptext="&performanceUI.table.selfAlloc.tooltip;"/>
|
||||
value="Self Count"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="self-count-percentage"
|
||||
crop="end"
|
||||
value="Self Count %"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="size"
|
||||
crop="end"
|
||||
value="Total Size"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="size-percentage"
|
||||
crop="end"
|
||||
value="Total Size %"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="count"
|
||||
crop="end"
|
||||
value="Total Count"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="count-percentage"
|
||||
crop="end"
|
||||
value="Total Count %"
|
||||
tooltiptext="&performanceUI.table.totalAlloc.tooltip;"/>
|
||||
<label class="plain call-tree-header"
|
||||
type="function"
|
||||
crop="end"
|
||||
|
@ -24,9 +24,15 @@ function* spawnTest() {
|
||||
"duration": false,
|
||||
"percentage": false,
|
||||
"count": true,
|
||||
"count-percentage": true,
|
||||
"size": true,
|
||||
"size-percentage": true,
|
||||
"self-duration": false,
|
||||
"self-percentage": false,
|
||||
"self-count": true,
|
||||
"self-count-percentage": true,
|
||||
"self-size": true,
|
||||
"self-size-percentage": true,
|
||||
"samples": false,
|
||||
"function": true
|
||||
});
|
||||
|
@ -88,8 +88,6 @@ let MemoryCallTreeView = Heritage.extend(DetailsSubview, {
|
||||
inverted: inverted,
|
||||
// Root nodes are hidden in inverted call trees.
|
||||
hidden: inverted,
|
||||
// Memory call trees should be sorted by allocations.
|
||||
sortingPredicate: (a, b) => a.frame.allocations < b.frame.allocations ? 1 : -1,
|
||||
// Call trees should only auto-expand when not inverted. Passing undefined
|
||||
// will default to the CALL_TREE_AUTO_EXPAND depth.
|
||||
autoExpandDepth: inverted ? 0 : undefined,
|
||||
@ -98,6 +96,12 @@ let MemoryCallTreeView = Heritage.extend(DetailsSubview, {
|
||||
visibleCells: {
|
||||
selfCount: true,
|
||||
count: true,
|
||||
selfSize: true,
|
||||
size: true,
|
||||
selfCountPercentage: true,
|
||||
countPercentage: true,
|
||||
selfSizePercentage: true,
|
||||
sizePercentage: true,
|
||||
function: true
|
||||
}
|
||||
});
|
||||
|
@ -92,13 +92,20 @@ category.storage=Storage
|
||||
category.events=Input & Events
|
||||
category.tools=Tools
|
||||
|
||||
# LOCALIZATION NOTE (table.ms):
|
||||
# This string is displayed in the call tree after units of time in milliseconds.
|
||||
table.ms=ms
|
||||
# LOCALIZATION NOTE (table.bytes):
|
||||
# This string is displayed in the call tree after bytesize units.
|
||||
# %S represents the value in bytes.
|
||||
table.bytes=%S B
|
||||
|
||||
# LOCALIZATION NOTE (table.percentage):
|
||||
# LOCALIZATION NOTE (table.ms2):
|
||||
# This string is displayed in the call tree after units of time in milliseconds.
|
||||
# %S represents the value in milliseconds.
|
||||
table.ms2=%S ms
|
||||
|
||||
# LOCALIZATION NOTE (table.percentage2):
|
||||
# This string is displayed in the call tree after units representing percentages.
|
||||
table.percentage=%
|
||||
# %S represents the value in percentage with two decimal points, localized.
|
||||
table.percentage2=%S%
|
||||
|
||||
# LOCALIZATION NOTE (table.root):
|
||||
# This string is displayed in the call tree for the root node.
|
||||
@ -165,4 +172,4 @@ timeline.records=RECORDS
|
||||
# %S is the percentage of the buffer used -- there are two "%"s after to escape
|
||||
# the % that is actually displayed.
|
||||
# Example: "Buffer 54% full"
|
||||
profiler.bufferFull=Buffer %S%% full
|
||||
profiler.bufferFull=Buffer %S%% full
|
||||
|
@ -234,8 +234,20 @@
|
||||
.call-tree-header[type="count"],
|
||||
.call-tree-cell[type="count"],
|
||||
.call-tree-header[type="self-count"],
|
||||
.call-tree-cell[type="self-count"] {
|
||||
width: 9vw;
|
||||
.call-tree-cell[type="self-count"],
|
||||
.call-tree-header[type="size"],
|
||||
.call-tree-cell[type="size"],
|
||||
.call-tree-header[type="self-size"],
|
||||
.call-tree-cell[type="self-size"],
|
||||
.call-tree-header[type="count-percentage"],
|
||||
.call-tree-cell[type="count-percentage"],
|
||||
.call-tree-header[type="self-count-percentage"],
|
||||
.call-tree-cell[type="self-count-percentage"],
|
||||
.call-tree-header[type="size-percentage"],
|
||||
.call-tree-cell[type="size-percentage"],
|
||||
.call-tree-header[type="self-size-percentage"],
|
||||
.call-tree-cell[type="self-size-percentage"] {
|
||||
width: 6vw;
|
||||
}
|
||||
|
||||
.call-tree-header[type="function"],
|
||||
|
Loading…
Reference in New Issue
Block a user