Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(778)

Unified Diff: chrome_linux/resources/inspector/ProfilesPanel.js

Issue 14690006: Update reference builds to r197396. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/reference_builds/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome_linux/resources/inspector/ProfilesPanel.js
===================================================================
--- chrome_linux/resources/inspector/ProfilesPanel.js (revision 197568)
+++ chrome_linux/resources/inspector/ProfilesPanel.js (working copy)
@@ -306,7 +306,10 @@
this._registerProfileType(new WebInspector.CPUProfileType());
if (!WebInspector.WorkerManager.isWorkerFrontend())
this._registerProfileType(new WebInspector.CSSSelectorProfileType());
-this._registerProfileType(new WebInspector.HeapSnapshotProfileType());
+var heapSnapshotProfileType = new WebInspector.HeapSnapshotProfileType();
+this._registerProfileType(heapSnapshotProfileType);
+if (WebInspector.experimentsSettings.heapObjectsTracking.isEnabled())
+this._registerProfileType(new WebInspector.TrackingHeapSnapshotProfileType(this, heapSnapshotProfileType));
if (!WebInspector.WorkerManager.isWorkerFrontend() && WebInspector.experimentsSettings.nativeMemorySnapshots.isEnabled()) {
this._registerProfileType(new WebInspector.NativeSnapshotProfileType());
this._registerProfileType(new WebInspector.NativeMemoryProfileType());
@@ -319,6 +322,7 @@
this._createFileSelectorElement();
this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
+this._registerShortcuts();
WebInspector.ContextMenu.registerProvider(this);
}
@@ -351,7 +355,12 @@
return null;
},
+_registerShortcuts: function()
+{
+this.registerShortcuts(WebInspector.ProfilesPanelDescriptor.ShortcutKeys.StartStopRecording, this.toggleRecordButton.bind(this));
+},
+
_loadFromFile: function(file)
{
this._createFileSelectorElement();
@@ -385,10 +394,12 @@
return this._statusBarButtons.select("element").concat(this._profileTypeStatusBarItemsContainer, this._profileViewStatusBarItemsContainer);
},
-toggleRecordButton: function()
+
+toggleRecordButton: function(event)
{
var isProfiling = this._selectedProfileType.buttonClicked();
this.setRecordingProfile(this._selectedProfileType.id, isProfiling);
+return true;
},
_populateAllProfiles: function()
@@ -904,7 +915,7 @@
searchMatchFound: function(view, matches)
{
-view.profile._profilesTreeElement.searchMatches = matches;
+view.profileHeader._profilesTreeElement.searchMatches = matches;
},
searchCanceled: function()
@@ -1842,39 +1853,40 @@
this.dataGrid = new WebInspector.DataGrid(columns);
this.dataGrid.addEventListener(WebInspector.DataGrid.Events.SortingChanged, this._sortProfile, this);
this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
+this.dataGrid.show(this.element);
-if (WebInspector.experimentsSettings.cpuFlameChart.isEnabled()) {
-this._splitView = new WebInspector.SplitView(false, "flameChartSplitLocation");
-this._splitView.show(this.element);
+this.viewSelectComboBox = new WebInspector.StatusBarComboBox(this._changeView.bind(this));
-this._flameChart = new WebInspector.FlameChart(this);
-this._flameChart.addEventListener(WebInspector.FlameChart.Events.SelectedNode, this._revealProfilerNode.bind(this));
-this._flameChart.show(this._splitView.firstElement());
+var options = {};
+if (WebInspector.experimentsSettings.cpuFlameChart.isEnabled())
+options[WebInspector.CPUProfileView._TypeFlame] = this.viewSelectComboBox.createOption(WebInspector.UIString("Flame Chart"), "", WebInspector.CPUProfileView._TypeFlame);
+options[WebInspector.CPUProfileView._TypeHeavy] = this.viewSelectComboBox.createOption(WebInspector.UIString("Heavy (Bottom Up)"), "", WebInspector.CPUProfileView._TypeHeavy);
+options[WebInspector.CPUProfileView._TypeTree] = this.viewSelectComboBox.createOption(WebInspector.UIString("Tree (Top Down)"), "", WebInspector.CPUProfileView._TypeTree);
-this.dataGrid.show(this._splitView.secondElement());
-} else
-this.dataGrid.show(this.element);
+var optionName = this._viewType.get() || WebInspector.CPUProfileView._TypeFlame;
+var option = options[optionName] || options[WebInspector.CPUProfileView._TypeFlame];
+this.viewSelectComboBox.select(option);
-this.viewSelectComboBox = new WebInspector.StatusBarComboBox(this._changeView.bind(this));
+this._statusBarButtonsElement = document.createElement("span");
-var heavyViewOption = this.viewSelectComboBox.createOption(WebInspector.UIString("Heavy (Bottom Up)"), "", WebInspector.CPUProfileView._TypeHeavy);
-var treeViewOption = this.viewSelectComboBox.createOption(WebInspector.UIString("Tree (Top Down)"), "", WebInspector.CPUProfileView._TypeTree);
-this.viewSelectComboBox.select(this._viewType.get() === WebInspector.CPUProfileView._TypeHeavy ? heavyViewOption : treeViewOption);
-
this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item");
this.percentButton.addEventListener("click", this._percentClicked, this);
+this._statusBarButtonsElement.appendChild(this.percentButton.element);
this.focusButton = new WebInspector.StatusBarButton(WebInspector.UIString("Focus selected function."), "focus-profile-node-status-bar-item");
this.focusButton.setEnabled(false);
this.focusButton.addEventListener("click", this._focusClicked, this);
+this._statusBarButtonsElement.appendChild(this.focusButton.element);
this.excludeButton = new WebInspector.StatusBarButton(WebInspector.UIString("Exclude selected function."), "exclude-profile-node-status-bar-item");
this.excludeButton.setEnabled(false);
this.excludeButton.addEventListener("click", this._excludeClicked, this);
+this._statusBarButtonsElement.appendChild(this.excludeButton.element);
this.resetButton = new WebInspector.StatusBarButton(WebInspector.UIString("Restore all functions."), "reset-profile-status-bar-item");
this.resetButton.visible = false;
this.resetButton.addEventListener("click", this._resetClicked, this);
+this._statusBarButtonsElement.appendChild(this.resetButton.element);
this.profileHead = (null);
this.profileHeader = profileHeader;
@@ -1887,6 +1899,7 @@
ProfilerAgent.getCPUProfile(this.profileHeader.uid, this._getCPUProfileCallback.bind(this));
}
+WebInspector.CPUProfileView._TypeFlame = "Flame";
WebInspector.CPUProfileView._TypeTree = "Tree";
WebInspector.CPUProfileView._TypeHeavy = "Heavy";
@@ -1943,7 +1956,7 @@
get statusBarItems()
{
-return [this.viewSelectComboBox.element, this.percentButton.element, this.focusButton.element, this.excludeButton.element, this.resetButton.element];
+return [this.viewSelectComboBox.element, this._statusBarButtonsElement];
},
@@ -2204,12 +2217,39 @@
profileNode.revealAndSelect();
},
+_ensureFlameChartCreated: function()
+{
+if (this._flameChart)
+return;
+this._flameChart = new WebInspector.FlameChart(this);
+this._flameChart.addEventListener(WebInspector.FlameChart.Events.SelectedNode, this._onSelectedNode.bind(this));
+},
+
+
+_onSelectedNode: function(event)
+{
+var node = event.data;
+if (!node || !node.url)
+return;
+var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(node.url);
+if (!uiSourceCode)
+return;
+WebInspector.showPanel("scripts").showUISourceCode(uiSourceCode, node.lineNumber);
+},
+
_changeView: function()
{
if (!this.profileHeader)
return;
switch (this.viewSelectComboBox.selectedOption().value) {
+case WebInspector.CPUProfileView._TypeFlame:
+this._ensureFlameChartCreated();
+this.dataGrid.detach();
+this._flameChart.show(this.element);
+this._viewType.set(WebInspector.CPUProfileView._TypeFlame);
+this._statusBarButtonsElement.enableStyleClass("hidden", true);
+return;
case WebInspector.CPUProfileView._TypeTree:
this.profileDataGridTree = this._getTopDownProfileDataGridTree();
this._sortProfile();
@@ -2219,8 +2259,15 @@
this.profileDataGridTree = this._getBottomUpProfileDataGridTree();
this._sortProfile();
this._viewType.set(WebInspector.CPUProfileView._TypeHeavy);
+break;
}
+this._statusBarButtonsElement.enableStyleClass("hidden", false);
+
+if (this._flameChart)
+this._flameChart.detach();
+this.dataGrid.show(this.element);
+
if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
return;
@@ -3004,10 +3051,10 @@
this._overviewContainer = this.element.createChild("div", "overview-container");
this._overviewGrid = new WebInspector.OverviewGrid("flame-chart");
+this._overviewCanvas = this._overviewContainer.createChild("canvas", "flame-chart-overview-canvas");
this._overviewContainer.appendChild(this._overviewGrid.element);
this._overviewCalculator = new WebInspector.FlameChart.OverviewCalculator();
this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
-this._overviewCanvas = this._overviewContainer.createChild("canvas");
this._chartContainer = this.element.createChild("div", "chart-container");
this._timelineGrid = new WebInspector.TimelineGrid();
@@ -3015,6 +3062,7 @@
this._calculator = new WebInspector.FlameChart.Calculator();
this._canvas = this._chartContainer.createChild("canvas");
+this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this));
WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind(this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "col-resize");
this._cpuProfileView = cpuProfileView;
@@ -3025,8 +3073,6 @@
this._paddingLeft = 15;
this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), false);
this.element.addEventListener("click", this._onClick.bind(this), false);
-this._popoverHelper = new WebInspector.PopoverHelper(this._chartContainer, this._getPopoverAnchor.bind(this), this._showPopover.bind(this));
-this._popoverHelper.setTimeout(250);
this._linkifier = new WebInspector.Linkifier();
this._highlightedNodeIndex = -1;
@@ -3174,7 +3220,6 @@
_onWindowChanged: function(event)
{
-this._hidePopover();
this._scheduleUpdate();
},
@@ -3186,7 +3231,6 @@
this._dragStartPoint = event.pageX;
this._dragStartWindowLeft = this._windowLeft;
this._dragStartWindowRight = this._windowRight;
-this._hidePopover();
return true;
},
@@ -3335,58 +3379,50 @@
return this._timelineData;
},
-_getPopoverAnchor: function(element, event)
+_onMouseMove: function(event)
{
if (this._isDragging)
-return null;
+return;
var nodeIndex = this._coordinatesToNodeIndex(event.offsetX, event.offsetY);
+if (this._highlightedNodeIndex === nodeIndex)
+return;
+
this._highlightedNodeIndex = nodeIndex;
-this.update();
-
-if (nodeIndex === -1)
-return null;
-
-var anchorBox = new AnchorBox();
-this._entryToAnchorBox(this._timelineData.entries[nodeIndex], anchorBox);
-anchorBox.x += event.pageX - event.offsetX;
-anchorBox.y += event.pageY - event.offsetY;
-
-return anchorBox;
+this._scheduleUpdate();
},
-_showPopover: function(anchor, popover)
+_prepareHighlightedEntryInfo: function()
{
if (this._isDragging)
-return;
+return null;
var entry = this._timelineData.entries[this._highlightedNodeIndex];
+if (!entry)
+return null;
var node = entry.node;
if (!node)
-return;
-var contentHelper = new WebInspector.PopoverContentHelper(node.functionName);
+return null;
+
+var entryInfo = [];
+function pushEntryInfoRow(title, text)
+{
+var row = {};
+row.title = title;
+row.text = text;
+entryInfo.push(row);
+}
+
+pushEntryInfoRow(WebInspector.UIString("Name"), node.functionName);
if (this._cpuProfileView.samples) {
-contentHelper.appendTextRow(WebInspector.UIString("Self time"), Number.secondsToString(entry.selfTime / 1000, true));
-contentHelper.appendTextRow(WebInspector.UIString("Total time"), Number.secondsToString(entry.duration / 1000, true));
+pushEntryInfoRow(WebInspector.UIString("Self time"), Number.secondsToString(entry.selfTime / 1000, true));
+pushEntryInfoRow(WebInspector.UIString("Total time"), Number.secondsToString(entry.duration / 1000, true));
}
-contentHelper.appendTextRow(WebInspector.UIString("Aggregated self time"), Number.secondsToString(node.selfTime / 1000, true));
-contentHelper.appendTextRow(WebInspector.UIString("Aggregated total time"), Number.secondsToString(node.totalTime / 1000, true));
-if (node.numberOfCalls)
-contentHelper.appendTextRow(WebInspector.UIString("Number of calls"), node.numberOfCalls);
-if (node.url) {
-var link = this._linkifier.linkifyLocation(node.url, node.lineNumber);
-contentHelper.appendElementRow("Location", link);
-}
-
-popover.show(contentHelper._contentTable, anchor);
+pushEntryInfoRow(WebInspector.UIString("Aggregated self time"), Number.secondsToString(node.selfTime / 1000, true));
+pushEntryInfoRow(WebInspector.UIString("Aggregated total time"), Number.secondsToString(node.totalTime / 1000, true));
+return entryInfo;
},
-_hidePopover: function()
-{
-this._popoverHelper.hidePopover();
-this._linkifier.reset();
-},
-
_onClick: function(e)
{
if (this._highlightedNodeIndex === -1)
@@ -3397,11 +3433,17 @@
_onMouseWheel: function(e)
{
-var zoomFactor = (e.wheelDelta > 0) ? 0.9 : 1.1;
-var windowPoint = (this._pixelWindowLeft + e.offsetX) / this._totalPixels;
-var overviewReferencePoint = Math.floor(windowPoint * this._pixelWindowWidth);
-this._overviewGrid.zoom(zoomFactor, overviewReferencePoint);
-this._hidePopover();
+if (e.wheelDeltaY) {
+const zoomFactor = 1.1;
+const mouseWheelZoomSpeed = 1 / 120;
+
+var zoom = Math.pow(zoomFactor, -e.wheelDeltaY * mouseWheelZoomSpeed);
+var overviewReference = (this._pixelWindowLeft + e.offsetX - this._paddingLeft) / this._totalPixels;
+this._overviewGrid.zoom(zoom, overviewReference);
+} else {
+var shift = Number.constrain(-1 * this._windowWidth / 4 * e.wheelDeltaX / 120, -this._windowLeft, 1 - this._windowRight);
+this._overviewGrid.setWindow(this._windowLeft + shift, this._windowRight + shift);
+}
},
@@ -3412,7 +3454,7 @@
return -1;
var timelineEntries = timelineData.entries;
var cursorTime = (x + this._pixelWindowLeft - this._paddingLeft) * this._pixelToTime;
-var cursorLevel = Math.floor((this._canvas.height - y) / this._barHeight);
+var cursorLevel = Math.floor((this._canvas.height / window.devicePixelRatio - y) / this._barHeight);
for (var i = 0; i < timelineEntries.length; ++i) {
if (cursorTime < timelineEntries[i].startTime)
@@ -3427,15 +3469,11 @@
onResize: function()
{
this._updateOverviewCanvas = true;
-this._hidePopover();
this._scheduleUpdate();
},
_drawOverviewCanvas: function(width, height)
{
-this._overviewCanvas.width = width;
-this._overviewCanvas.height = height;
-
if (!this._timelineData)
return;
@@ -3443,25 +3481,43 @@
var drawData = new Uint8Array(width);
var scaleFactor = width / this._totalTime;
+var maxStackDepth = 5;
for (var nodeIndex = 0; nodeIndex < timelineEntries.length; ++nodeIndex) {
var entry = timelineEntries[nodeIndex];
var start = Math.floor(entry.startTime * scaleFactor);
var finish = Math.floor((entry.startTime + entry.duration) * scaleFactor);
-for (var x = start; x < finish; ++x)
+for (var x = start; x < finish; ++x) {
drawData[x] = Math.max(drawData[x], entry.depth + 1);
+maxStackDepth = Math.max(maxStackDepth, entry.depth + 1);
}
+}
+var ratio = window.devicePixelRatio;
+var canvasWidth = width * ratio;
+var canvasHeight = height * ratio;
+this._overviewCanvas.width = canvasWidth;
+this._overviewCanvas.height = canvasHeight;
+this._overviewCanvas.style.width = width + "px";
+this._overviewCanvas.style.height = height + "px";
+
var context = this._overviewCanvas.getContext("2d");
-var yScaleFactor = 2;
-context.lineWidth = 0.5;
-context.strokeStyle = "rgba(20,0,0,0.8)";
-context.fillStyle="rgba(214,225,254, 0.8)";
-context.moveTo(0, height - 1);
-for (var x = 0; x < width; ++x)
-context.lineTo(x, height - drawData[x] * yScaleFactor - 1);
-context.lineTo(width - 1, height - 1);
-context.lineTo(0, height - 1);
+
+var yScaleFactor = canvasHeight / (maxStackDepth * 1.1);
+context.lineWidth = 1;
+context.translate(0.5, 0.5);
+context.strokeStyle = "rgba(20,0,0,0.4)";
+context.fillStyle = "rgba(214,225,254,0.8)";
+context.moveTo(-1, canvasHeight - 1);
+if (drawData)
+context.lineTo(-1, Math.round(height - drawData[0] * yScaleFactor - 1));
+var value;
+for (var x = 0; x < width; ++x) {
+value = Math.round(canvasHeight - drawData[x] * yScaleFactor - 1);
+context.lineTo(x * ratio, value);
+}
+context.lineTo(canvasWidth + 1, value);
+context.lineTo(canvasWidth + 1, canvasHeight - 1);
context.fill();
context.stroke();
context.closePath();
@@ -3471,7 +3527,7 @@
_entryToAnchorBox: function(entry, anchorBox)
{
anchorBox.x = Math.floor(entry.startTime * this._timeToPixel) - this._pixelWindowLeft + this._paddingLeft;
-anchorBox.y = this._canvas.height - (entry.depth + 1) * this._barHeight;
+anchorBox.y = this._canvas.height / window.devicePixelRatio - (entry.depth + 1) * this._barHeight;
anchorBox.width = Math.floor(entry.duration * this._timeToPixel);
anchorBox.height = this._barHeight;
if (anchorBox.x < 0) {
@@ -3488,12 +3544,20 @@
if (!timelineData)
return;
var timelineEntries = timelineData.entries;
-this._canvas.height = height;
-this._canvas.width = width;
+
+var ratio = window.devicePixelRatio;
+var canvasWidth = width * ratio;
+var canvasHeight = height * ratio;
+this._canvas.width = canvasWidth;
+this._canvas.height = canvasHeight;
+this._canvas.style.width = width + "px";
+this._canvas.style.height = height + "px";
+
var barHeight = this._barHeight;
var context = this._canvas.getContext("2d");
var textPaddingLeft = 2;
+context.scale(ratio, ratio);
context.font = (barHeight - 3) + "px sans-serif";
context.textBaseline = "top";
this._dotsWidth = context.measureText("\u2026").width;
@@ -3525,16 +3589,50 @@
var xText = Math.max(0, anchorBox.x);
var widthText = anchorBox.width - textPaddingLeft + anchorBox.x - xText;
-var title = this._prepareTitle(context, entry.node.functionName, widthText);
+var title = this._prepareText(context, entry.node.functionName, widthText);
if (title) {
context.fillStyle = "#333";
context.fillText(title, xText + textPaddingLeft, anchorBox.y - 1);
}
}
+
+var entryInfo = this._prepareHighlightedEntryInfo();
+if (entryInfo)
+this._printEntryInfo(context, entryInfo, 0, 25);
},
-_prepareTitle: function(context, title, maxSize)
+_printEntryInfo: function(context, entryInfo, x, y)
{
+const lineHeight = 18;
+const maxTextWidth = 290;
+const paddingLeft = 10;
+const paddingTop = 5;
+const paddingLeftText = 10;
+var maxTitleWidth = 0;
+context.font = "bold " + (this._barHeight - 3) + "px sans-serif";
+for (var i = 0; i < entryInfo.length; ++i)
+maxTitleWidth = Math.max(maxTitleWidth, context.measureText(entryInfo[i].title).width);
+
+context.beginPath();
+context.rect(x, y, maxTextWidth + 5, lineHeight * entryInfo.length + 5);
+context.strokeStyle = "rgba(0,0,0,0)";
+context.fillStyle = "rgba(254,254,254,0.8)";
+context.fill();
+context.stroke();
+
+context.fillStyle = "#333";
+for (var i = 0; i < entryInfo.length; ++i)
+context.fillText(entryInfo[i].title, x + paddingLeft, y + lineHeight * i);
+
+context.font = (this._barHeight - 3) + "px sans-serif";
+for (var i = 0; i < entryInfo.length; ++i) {
+var text = this._prepareText(context, entryInfo[i].text, maxTextWidth - maxTitleWidth - 2 * paddingLeft);
+context.fillText(text, x + paddingLeft + maxTitleWidth + paddingLeft, y + lineHeight * i);
+}
+},
+
+_prepareText: function(context, title, maxSize)
+{
if (maxSize < this._dotsWidth)
return null;
var titleWidth = context.measureText(title).width;
@@ -3563,6 +3661,11 @@
return "\u2026" + substring;
match = dotRegExp.exec(title);
}
+var i = 0;
+do {
+++i;
+} while (context.measureText(title.substring(0, i)).width < maxSize);
+return title.substring(0, i - 1) + "\u2026";
},
_scheduleUpdate: function()
@@ -3607,7 +3710,7 @@
this._timelineGrid.updateDividers(this._calculator);
this._overviewGrid.updateDividers(this._overviewCalculator);
if (this._updateOverviewCanvas) {
-this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight);
+this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
this._updateOverviewCanvas = false;
}
},
@@ -7705,6 +7808,12 @@
this.parent = parent;
this.parent.addEventListener("profile added", this._onProfileHeaderAdded, this);
+if (profile._profileSamples) {
+this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile);
+this._trackingOverviewGrid.addEventListener(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this));
+this._trackingOverviewGrid.show(this.element);
+}
+
this.viewsContainer = document.createElement("div");
this.viewsContainer.addStyleClass("views-container");
this.element.appendChild(this.viewsContainer);
@@ -7765,38 +7874,31 @@
this.dataGrid = (this.constructorsDataGrid);
this.currentView = this.constructorsView;
-this.viewSelectElement = document.createElement("select");
-this.viewSelectElement.className = "status-bar-item";
-this.viewSelectElement.addEventListener("change", this._onSelectedViewChanged.bind(this), false);
+this.viewSelect = new WebInspector.StatusBarComboBox(this._onSelectedViewChanged.bind(this));
this.views = [{title: "Summary", view: this.constructorsView, grid: this.constructorsDataGrid},
{title: "Comparison", view: this.diffView, grid: this.diffDataGrid},
{title: "Containment", view: this.containmentView, grid: this.containmentDataGrid},
{title: "Dominators", view: this.dominatorView, grid: this.dominatorDataGrid}];
this.views.current = 0;
-for (var i = 0; i < this.views.length; ++i) {
-var view = this.views[i];
-var option = document.createElement("option");
-option.label = WebInspector.UIString(view.title);
-this.viewSelectElement.appendChild(option);
-}
+for (var i = 0; i < this.views.length; ++i)
+this.viewSelect.createOption(WebInspector.UIString(this.views[i].title));
this._profileUid = profile.uid;
this._profileTypeId = profile.profileType().id;
-this.baseSelectElement = document.createElement("select");
-this.baseSelectElement.className = "status-bar-item";
-this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false);
+this.baseSelect = new WebInspector.StatusBarComboBox(this._changeBase.bind(this));
+this.baseSelect.element.addStyleClass("hidden");
this._updateBaseOptions();
-this.filterSelectElement = document.createElement("select");
-this.filterSelectElement.className = "status-bar-item";
-this.filterSelectElement.addEventListener("change", this._changeFilter.bind(this), false);
+this.filterSelect = new WebInspector.StatusBarComboBox(this._changeFilter.bind(this));
this._updateFilterOptions();
this.helpButton = new WebInspector.StatusBarButton("", "heap-snapshot-help-status-bar-item status-bar-item");
this.helpButton.addEventListener("click", this._helpClicked, this);
+this.selectedSizeText = new WebInspector.StatusBarText("");
+
this._popoverHelper = new WebInspector.ObjectPopoverHelper(this.element, this._getHoverAnchor.bind(this), this._resolveObjectForPopover.bind(this), undefined, true);
this.profile.load(profileCallback.bind(this));
@@ -7813,14 +7915,30 @@
}
if (profileIndex > 0)
-this.baseSelectElement.selectedIndex = profileIndex - 1;
+this.baseSelect.setSelectedIndex(profileIndex - 1);
else
-this.baseSelectElement.selectedIndex = profileIndex;
+this.baseSelect.setSelectedIndex(profileIndex);
this.dataGrid.setDataSource(heapSnapshotProxy);
}
}
WebInspector.HeapSnapshotView.prototype = {
+_onIdsRangeChanged: function(event)
+{
+var minId = event.data.minId;
+var maxId = event.data.maxId;
+this.selectedSizeText.setText(WebInspector.UIString("Selected size: %s", Number.bytesToString(event.data.size)));
+if (this.constructorsDataGrid._minNodeId !== minId || this.constructorsDataGrid._maxNodeId !== maxId) {
+
+this.constructorsDataGrid._minNodeId = minId;
+this.constructorsDataGrid._maxNodeId = maxId;
+if (this.constructorsDataGrid.snapshot) {
+this.constructorsDataGrid._profileIndex = 1;
+this.constructorsDataGrid._populateChildren();
+}
+}
+},
+
dispose: function()
{
this.profile.dispose();
@@ -7835,15 +7953,7 @@
get statusBarItems()
{
-
-function appendArrowImage(element, hidden)
-{
-var span = document.createElement("span");
-span.className = "status-bar-select-container" + (hidden ? " hidden" : "");
-span.appendChild(element);
-return span;
-}
-return [appendArrowImage(this.viewSelectElement), appendArrowImage(this.baseSelectElement, true), appendArrowImage(this.filterSelectElement), this.helpButton.element];
+return [this.viewSelect.element, this.baseSelect.element, this.filterSelect.element, this.helpButton.element, this.selectedSizeText.element];
},
get profile()
@@ -8025,10 +8135,10 @@
_changeBase: function()
{
-if (this._baseProfileUid === this._profiles()[this.baseSelectElement.selectedIndex].uid)
+if (this._baseProfileUid === this._profiles()[this.baseSelect.selectedIndex()].uid)
return;
-this._baseProfileUid = this._profiles()[this.baseSelectElement.selectedIndex].uid;
+this._baseProfileUid = this._profiles()[this.baseSelect.selectedIndex()].uid;
var dataGrid = (this.dataGrid);
if (dataGrid.snapshot)
@@ -8046,12 +8156,12 @@
_changeFilter: function()
{
-var profileIndex = this.filterSelectElement.selectedIndex - 1;
+var profileIndex = this.filterSelect.selectedIndex() - 1;
this.dataGrid.filterSelectIndexChanged(this._profiles(), profileIndex);
WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, {
action: WebInspector.UserMetrics.UserActionNames.HeapSnapshotFilterChanged,
-label: this.filterSelectElement[this.filterSelectElement.selectedIndex].label
+label: this.filterSelect.selectedOption().label
});
if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
@@ -8131,12 +8241,13 @@
changeView: function(viewTitle, callback)
{
var viewIndex = null;
-for (var i = 0; i < this.views.length; ++i)
+for (var i = 0; i < this.views.length; ++i) {
if (this.views[i].title === viewTitle) {
viewIndex = i;
break;
}
-if (this.views.current === viewIndex) {
+}
+if (this.views.current === viewIndex || viewIndex == null) {
setTimeout(callback, 0);
return;
}
@@ -8150,7 +8261,7 @@
}
this.views[viewIndex].grid.addEventListener(WebInspector.HeapSnapshotSortableDataGrid.Events.ContentShown, dataGridContentShown, this);
-this.viewSelectElement.selectedIndex = viewIndex;
+this.viewSelect.setSelectedIndex(viewIndex);
this._changeView(viewIndex);
},
@@ -8169,7 +8280,7 @@
dataGrid.setDataSource(snapshotProxy);
if (dataGrid === this.diffDataGrid) {
if (!this._baseProfileUid)
-this._baseProfileUid = this._profiles()[this.baseSelectElement.selectedIndex].uid;
+this._baseProfileUid = this._profiles()[this.baseSelect.selectedIndex()].uid;
this.baseProfile.load(didLoadBaseSnaphot.bind(this));
}
}
@@ -8189,14 +8300,24 @@
_updateSelectorsVisibility: function()
{
if (this.currentView === this.diffView)
-this.baseSelectElement.parentElement.removeStyleClass("hidden");
+this.baseSelect.element.removeStyleClass("hidden");
else
-this.baseSelectElement.parentElement.addStyleClass("hidden");
+this.baseSelect.element.addStyleClass("hidden");
-if (this.currentView === this.constructorsView)
-this.filterSelectElement.parentElement.removeStyleClass("hidden");
-else
-this.filterSelectElement.parentElement.addStyleClass("hidden");
+if (this.currentView === this.constructorsView) {
+if (this._trackingOverviewGrid) {
+this._trackingOverviewGrid.element.removeStyleClass("hidden");
+this._trackingOverviewGrid.update(true);
+this.viewsContainer.addStyleClass("reserve-80px-at-top");
+}
+this.filterSelect.element.removeStyleClass("hidden");
+} else {
+this.filterSelect.element.addStyleClass("hidden");
+if (this._trackingOverviewGrid) {
+this._trackingOverviewGrid.element.addStyleClass("hidden");
+this.viewsContainer.removeStyleClass("reserve-80px-at-top");
+}
+}
},
_changeView: function(selectedIndex)
@@ -8337,6 +8458,8 @@
{
height = Number.constrain(height, Preferences.minConsoleHeight, this.element.clientHeight - Preferences.minConsoleHeight);
this.viewsContainer.style.bottom = (height + this.retainmentViewHeader.clientHeight) + "px";
+if (this._trackingOverviewGrid && this.currentView === this.constructorsView)
+this.viewsContainer.addStyleClass("reserve-80px-at-top");
this.retainmentView.element.style.height = height + "px";
this.retainmentViewHeader.style.bottom = height + "px";
this.currentView.doResize();
@@ -8346,16 +8469,14 @@
{
var list = this._profiles();
-if (this.baseSelectElement.length === list.length)
+if (this.baseSelect.size() === list.length)
return;
-for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) {
-var baseOption = document.createElement("option");
+for (var i = this.baseSelect.size(), n = list.length; i < n; ++i) {
var title = list[i].title;
if (WebInspector.ProfilesPanelDescriptor.isUserInitiatedProfile(title))
title = WebInspector.UIString("Snapshot %d", WebInspector.ProfilesPanelDescriptor.userInitiatedProfileIndex(title));
-baseOption.label = title;
-this.baseSelectElement.appendChild(baseOption);
+this.baseSelect.createOption(title);
}
},
@@ -8363,20 +8484,16 @@
{
var list = this._profiles();
-if (this.filterSelectElement.length - 1 === list.length)
+if (this.filterSelect.size() - 1 === list.length)
return;
-if (!this.filterSelectElement.length) {
-var filterOption = document.createElement("option");
-filterOption.label = WebInspector.UIString("All objects");
-this.filterSelectElement.appendChild(filterOption);
-}
+if (!this.filterSelect.size())
+this.filterSelect.createOption(WebInspector.UIString("All objects"));
if (this.profile.fromFile())
return;
-for (var i = this.filterSelectElement.length - 1, n = list.length; i < n; ++i) {
+for (var i = this.filterSelect.size() - 1, n = list.length; i < n; ++i) {
var profile = list[i];
-var filterOption = document.createElement("option");
var title = list[i].title;
if (WebInspector.ProfilesPanelDescriptor.isUserInitiatedProfile(title)) {
var profileIndex = WebInspector.ProfilesPanelDescriptor.userInitiatedProfileIndex(title);
@@ -8385,8 +8502,7 @@
else
title = WebInspector.UIString("Objects allocated between Snapshots %d and %d", profileIndex - 1, profileIndex);
}
-filterOption.label = title;
-this.filterSelectElement.appendChild(filterOption);
+this.filterSelect.createOption(title);
}
},
@@ -8437,8 +8553,70 @@
return false;
},
-get treeItemTitle()
+startRecordingProfile: function()
{
+this._lastSeenIndex = -1;
+this._profileSamples = {
+'sizes': [],
+'ids': [],
+'timestamps': [],
+'max': []
+};
+this._recording = true;
+this._currentIndex = 0;
+HeapProfilerAgent.startTrackingHeapObjects();
+},
+
+stopRecordingProfile: function()
+{
+HeapProfilerAgent.stopTrackingHeapObjects();
+this.addProfile(this.createTemporaryProfile());
+HeapProfilerAgent.takeHeapSnapshot(true);
+this._recording = false;
+},
+
+toggleRecording: function()
+{
+if (this._recording)
+this.stopRecordingProfile();
+else
+this.startRecordingProfile();
+return this._recording;
+},
+
+
+heapStatsUpdate: function(samples)
+{
+if (!this._profileSamples) {
+HeapProfilerAgent.stopTrackingHeapObjects();
+return;
+}
+var index;
+for (var i = 0; i < samples.length; i += 3) {
+index = samples[i];
+var count = samples[i+1];
+var size = samples[i+2];
+this._profileSamples.sizes[index] = size;
+if (size > this._profileSamples.max[index])
+this._profileSamples.max[index] = size;
+}
+this._lastUpdatedIndex = index;
+},
+
+
+lastSeenObjectId: function(lastSeenObjectId, timestamp)
+{
+this._profileSamples.ids[this._currentIndex] = lastSeenObjectId;
+this._profileSamples.timestamps[this._currentIndex] = timestamp;
+if (!this._profileSamples.max[this._currentIndex]) {
+this._profileSamples.max[this._currentIndex] = 0;
+this._profileSamples.sizes[this._currentIndex] = 0;
+}
+++this._currentIndex;
+},
+
+get treeItemTitle()
+{
return WebInspector.UIString("HEAP SNAPSHOTS");
},
@@ -8472,7 +8650,10 @@
addProfileHeader: function(profileHeader)
{
-this.addProfile(this.createProfile(profileHeader));
+var profile = this.createProfile(profileHeader);
+profile._profileSamples = this._profileSamples;
+this._profileSamples = null;
+this.addProfile(profile);
},
@@ -8523,6 +8704,65 @@
}
+
+WebInspector.TrackingHeapSnapshotProfileType = function(profilesPanel, profileType)
+{
+WebInspector.ProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Track Allocations"));
+this._profilesPanel = profilesPanel;
+this._parentType = profileType;
+}
+
+WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD";
+
+WebInspector.TrackingHeapSnapshotProfileType.prototype = {
+get buttonTooltip()
+{
+return this._recording ? WebInspector.UIString("Stop recording heap profile.") : WebInspector.UIString("Start recording heap profile.");
+},
+
+
+isInstantProfile: function()
+{
+return false;
+},
+
+
+buttonClicked: function()
+{
+var profile = this.findTemporaryProfile();
+var result = this._parentType.toggleRecording();
+if (!result && profile)
+this._profilesPanel._removeProfileHeader(profile);
+return result;
+},
+
+get treeItemTitle()
+{
+return WebInspector.UIString("TRACK HEAP SNAPSHOTS");
+},
+
+get description()
+{
+return WebInspector.UIString("Run heap profiler continuously to track JavaScript allocations over time.");
+},
+
+
+createTemporaryProfile: function(title)
+{
+title = title || WebInspector.UIString("Recording\u2026");
+return new WebInspector.HeapProfileHeader(this, title);
+},
+
+
+resetProfiles: function()
+{
+this._reset();
+},
+
+__proto__: WebInspector.ProfileType.prototype
+}
+
+
WebInspector.HeapProfileHeader = function(type, title, uid, maxJSObjectId)
{
WebInspector.ProfileHeader.call(this, type, title, uid);
@@ -8742,6 +8982,219 @@
}
}
}
+
+
+WebInspector.HeapTrackingOverviewGrid = function(heapProfileHeader)
+{
+WebInspector.View.call(this);
+this.registerRequiredCSS("flameChart.css");
+this.element.id = "heap-recording-view";
+
+this._overviewContainer = this.element.createChild("div", "overview-container");
+this._overviewGrid = new WebInspector.OverviewGrid("heap-recording");
+this._overviewCanvas = this._overviewContainer.createChild("canvas", "heap-recording-overview-canvas");
+this._overviewContainer.appendChild(this._overviewGrid.element);
+this._overviewCalculator = new WebInspector.HeapTrackingOverviewGrid.OverviewCalculator();
+this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
+
+this._profileSamples = heapProfileHeader._profileSamples;
+var timestamps = this._profileSamples.timestamps;
+var startTime = timestamps[0];
+this._totalTime = timestamps[timestamps.length - 1] - startTime;
+this._windowLeft = 0.0;
+this._windowRight = 1.0;
+}
+
+WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged = "IdsRangeChanged";
+
+WebInspector.HeapTrackingOverviewGrid.prototype = {
+
+_drawOverviewCanvas: function(width, height)
+{
+var sizes = this._profileSamples.sizes;
+var usedSizes = this._profileSamples.max;
+var timestamps = this._profileSamples.timestamps;
+
+var scaleFactor = width / this._totalTime;
+var maxUsedSize = 0;
+var currentX = 0;
+
+function aggregateAndCall(sizes, callback)
+{
+var size = 0;
+var currentX = 0;
+for (var i = 1; i < timestamps.length; ++i) {
+var x = Math.floor((timestamps[i] - startTime) * scaleFactor) ;
+if (x !== currentX) {
+if (size)
+callback(currentX, size);
+size = 0;
+currentX = x;
+}
+size += sizes[i];
+}
+callback(currentX, size);
+}
+
+
+function maxUsedSizeCallback(x, size)
+{
+maxUsedSize = Math.max(maxUsedSize, size);
+}
+
+aggregateAndCall(usedSizes, maxUsedSizeCallback);
+
+this._overviewCanvas.width = width * window.devicePixelRatio;
+this._overviewCanvas.height = height * window.devicePixelRatio;
+this._overviewCanvas.style.width = width + "px";
+this._overviewCanvas.style.height = height + "px";
+var yScaleFactor = height / (maxUsedSize * 1.1);
+var startTime = timestamps[0];
+
+var context = this._overviewCanvas.getContext("2d");
+context.scale(window.devicePixelRatio, window.devicePixelRatio);
+
+
+function drawBarCallback(x, size)
+{
+context.moveTo(x, height - 1);
+context.lineTo(x, Math.round(height - size * yScaleFactor - 1));
+}
+
+context.beginPath();
+context.lineWidth = 2;
+context.strokeStyle = "rgba(192, 192, 192, 0.6)";
+aggregateAndCall(usedSizes, drawBarCallback);
+context.stroke();
+context.closePath();
+
+context.beginPath();
+context.lineWidth = 2;
+context.strokeStyle = "rgba(0, 0, 192, 0.8)";
+aggregateAndCall(sizes, drawBarCallback);
+context.stroke();
+context.closePath();
+},
+
+onResize: function()
+{
+this._updateOverviewCanvas = true;
+this._scheduleUpdate();
+},
+
+_onWindowChanged: function()
+{
+if (!this._updateGridTimerId)
+this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10);
+},
+
+_scheduleUpdate: function()
+{
+if (this._updateTimerId)
+return;
+this._updateTimerId = setTimeout(this.update.bind(this), 10);
+},
+
+_updateBoundaries: function()
+{
+this._windowLeft = this._overviewGrid.windowLeft();
+this._windowRight = this._overviewGrid.windowRight();
+this._windowWidth = this._windowRight - this._windowLeft;
+},
+
+
+update: function(updateOverviewCanvas)
+{
+this._updateTimerId = null;
+this._updateBoundaries();
+this._overviewCalculator._updateBoundaries(this);
+this._overviewGrid.updateDividers(this._overviewCalculator);
+if (this._updateOverviewCanvas || updateOverviewCanvas) {
+this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20);
+this._updateOverviewCanvas = false;
+}
+},
+
+_updateGrid: function()
+{
+this._updateGridTimerId = 0;
+this._updateBoundaries();
+var ids = this._profileSamples.ids;
+var timestamps = this._profileSamples.timestamps;
+var sizes = this._profileSamples.sizes;
+var startTime = timestamps[0];
+var finishTime = timestamps[timestamps.length - 1];
+var timeRange = finishTime - startTime;
+var timeLeft = startTime + timeRange * this._windowLeft;
+var timeRight = startTime + timeRange * this._windowRight;
+var minId = 0;
+var maxId = ids[ids.length - 1] + 1;
+var size = 0;
+for (var i = 1; i < timestamps.length; ++i) {
+if (!timestamps[i])
+continue;
+if (timestamps[i] > timeRight)
+break;
+maxId = ids[i];
+if (timestamps[i] <= timeLeft) {
+minId = ids[i];
+continue;
+}
+size += sizes[i];
+}
+
+this.dispatchEventToListeners(WebInspector.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size});
+},
+
+__proto__: WebInspector.View.prototype
+}
+
+
+
+WebInspector.HeapTrackingOverviewGrid.OverviewCalculator = function()
+{
+}
+
+WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype = {
+
+_updateBoundaries: function(chart)
+{
+this._minimumBoundaries = 0;
+this._maximumBoundaries = chart._totalTime;
+this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries;
+},
+
+
+computePosition: function(time)
+{
+return (time - this._minimumBoundaries) * this._xScaleFactor;
+},
+
+formatTime: function(value)
+{
+return Number.secondsToString((value + this._minimumBoundaries) / 1000);
+},
+
+maximumBoundary: function()
+{
+return this._maximumBoundaries;
+},
+
+minimumBoundary: function()
+{
+return this._minimumBoundaries;
+},
+
+zeroTime: function()
+{
+return this._minimumBoundaries;
+},
+
+boundarySpan: function()
+{
+return this._maximumBoundaries - this._minimumBoundaries;
+}
+}
;
@@ -10445,8 +10898,12 @@
_createControlButton: function(parent, className, title, clickCallback)
{
var button = new WebInspector.StatusBarButton(title, className);
-button.element.addEventListener("click", clickCallback, false);
parent.appendChild(button.element);
+
+button.makeLongClickEnabled();
+button.addEventListener("click", clickCallback, this);
+button.addEventListener("longClickDown", clickCallback, this);
+button.addEventListener("longClickPress", clickCallback, this);
},
_onReplayContextChanged: function()
@@ -10482,7 +10939,10 @@
var selectedNode = this._logGrid.selectedNode;
if (!selectedNode)
return;
-var nextNode = forward ? selectedNode.traverseNextNode(false) : selectedNode.traversePreviousNode(false);
+var nextNode = selectedNode;
+do {
+nextNode = forward ? nextNode.traverseNextNode(false) : nextNode.traversePreviousNode(false);
+} while (nextNode && typeof nextNode.index !== "number");
(nextNode || selectedNode).revealAndSelect();
},
@@ -10554,15 +11014,9 @@
{
delete this._pendingReplayTraceLogEvent;
-if (index !== this._selectedCallIndex()) {
-this._replayTraceLog();
-return;
-}
-
this._enableWaitIcon(false);
-if (error)
-return;
+if (!error) {
this._currentResourceStates = {};
this._currentResourceStates["auto"] = resourceState;
this._currentResourceStates[resourceState.id] = resourceState;
@@ -10570,6 +11024,10 @@
this._debugInfoElement.textContent = "Replay time: " + (Date.now() - time) + "ms";
this._onReplayContextChanged();
}
+
+if (index !== this._selectedCallIndex())
+this._replayTraceLog();
+}
this._enableWaitIcon(true);
CanvasAgent.replayTraceLog(this._traceLogId, index, didReplayTraceLog.bind(this));
},
@@ -10797,9 +11255,9 @@
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
this._decorationElement = document.createElement("div");
-this._decorationElement.addStyleClass("profile-canvas-decoration");
-this._decorationElement.addStyleClass("hidden");
-this._decorationElement.textContent = WebInspector.UIString("There is an uninstrumented canvas on the page. Reload the page to instrument it.");
+this._decorationElement.className = "profile-canvas-decoration hidden";
+this._decorationElement.createChild("div", "warning-icon-small");
+this._decorationElement.appendChild(document.createTextNode(WebInspector.UIString("There is an uninstrumented canvas on the page. Reload the page to instrument it.")));
var reloadPageButton = this._decorationElement.createChild("button");
reloadPageButton.type = "button";
reloadPageButton.textContent = WebInspector.UIString("Reload");
« no previous file with comments | « chrome_linux/resources/inspector/NetworkPanel.js ('k') | chrome_linux/resources/inspector/ResourcesPanel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698