| Index: chrome_linux64/resources/inspector/ProfilesPanel.js
|
| ===================================================================
|
| --- chrome_linux64/resources/inspector/ProfilesPanel.js (revision 197568)
|
| +++ chrome_linux64/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");
|
|
|