/**
* @constructor
* @extends {WebInspector.View}
- * @param {!WebInspector.ProfilesPanel} parent
* @param {!WebInspector.HeapProfileHeader} profile
*/
-WebInspector.HeapSnapshotView = function(parent, profile)
+WebInspector.HeapSnapshotView = function(profile)
{
WebInspector.View.call(this);
- this.element.addStyleClass("heap-snapshot-view");
+ this.element.classList.add("heap-snapshot-view");
- this.parent = parent;
- this.parent.addEventListener("profile added", this._onProfileHeaderAdded, this);
+ profile.profileType().addEventListener(WebInspector.HeapSnapshotProfileType.SnapshotReceived, this._onReceivSnapshot, this);
+ profile.profileType().addEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
if (profile._profileType.id === WebInspector.TrackingHeapSnapshotProfileType.TypeId) {
this._trackingOverviewGrid = new WebInspector.HeapTrackingOverviewGrid(profile);
this._trackingOverviewGrid.show(this.element);
}
- this.viewsContainer = document.createElement("div");
- this.viewsContainer.addStyleClass("views-container");
- this.element.appendChild(this.viewsContainer);
+ this.viewsContainer = new WebInspector.SplitView(false, true, "heapSnapshotRetainersViewSize", 200, 200);
+ this.viewsContainer.show(this.element);
+ this.viewsContainer.setMainElementConstraints(50, 50);
+ this.viewsContainer.setSidebarElementConstraints(70, 70);
this.containmentView = new WebInspector.View();
- this.containmentView.element.addStyleClass("view");
this.containmentDataGrid = new WebInspector.HeapSnapshotContainmentDataGrid();
this.containmentDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
this.containmentDataGrid.show(this.containmentView.element);
this.containmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
this.constructorsView = new WebInspector.View();
- this.constructorsView.element.addStyleClass("view");
- this.constructorsView.element.appendChild(this._createToolbarWithClassNameFilter());
this.constructorsDataGrid = new WebInspector.HeapSnapshotConstructorsDataGrid();
- this.constructorsDataGrid.element.addStyleClass("class-view-grid");
this.constructorsDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
this.constructorsDataGrid.show(this.constructorsView.element);
this.constructorsDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
- this.dataGrid = /** @type {WebInspector.HeapSnapshotSortableDataGrid} */ (this.constructorsDataGrid);
+ this.dataGrid = /** @type {!WebInspector.HeapSnapshotSortableDataGrid} */ (this.constructorsDataGrid);
this.currentView = this.constructorsView;
- this.currentView.show(this.viewsContainer);
+ this.currentView.show(this.viewsContainer.mainElement());
this.diffView = new WebInspector.View();
- this.diffView.element.addStyleClass("view");
- this.diffView.element.appendChild(this._createToolbarWithClassNameFilter());
this.diffDataGrid = new WebInspector.HeapSnapshotDiffDataGrid();
- this.diffDataGrid.element.addStyleClass("class-view-grid");
this.diffDataGrid.show(this.diffView.element);
this.diffDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
this.dominatorView = new WebInspector.View();
- this.dominatorView.element.addStyleClass("view");
this.dominatorDataGrid = new WebInspector.HeapSnapshotDominatorsDataGrid();
this.dominatorDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
this.dominatorDataGrid.show(this.dominatorView.element);
this.dominatorDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
- if (WebInspector.HeapSnapshot.enableAllocationProfiler) {
+ if (WebInspector.experimentsSettings.allocationProfiler.isEnabled() && profile.profileType() === WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType) {
this.allocationView = new WebInspector.View();
- this.allocationView.element.addStyleClass("view");
this.allocationDataGrid = new WebInspector.AllocationDataGrid();
this.allocationDataGrid.element.addEventListener("mousedown", this._mouseDownInContentsGrid.bind(this), true);
this.allocationDataGrid.show(this.allocationView.element);
this.allocationDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._selectionChanged, this);
}
- this.retainmentViewHeader = document.createElement("div");
- this.retainmentViewHeader.addStyleClass("retainers-view-header");
- WebInspector.installDragHandle(this.retainmentViewHeader, this._startRetainersHeaderDragging.bind(this), this._retainersHeaderDragging.bind(this), this._endRetainersHeaderDragging.bind(this), "row-resize");
- var retainingPathsTitleDiv = document.createElement("div");
- retainingPathsTitleDiv.className = "title";
- var retainingPathsTitle = document.createElement("span");
+ this.retainmentViewHeader = document.createElementWithClass("div", "retainers-view-header");
+ var retainingPathsTitleDiv = this.retainmentViewHeader.createChild("div", "title");
+ var retainingPathsTitle = retainingPathsTitleDiv.createChild("span");
retainingPathsTitle.textContent = WebInspector.UIString("Object's retaining tree");
- retainingPathsTitleDiv.appendChild(retainingPathsTitle);
- this.retainmentViewHeader.appendChild(retainingPathsTitleDiv);
- this.element.appendChild(this.retainmentViewHeader);
+ this.viewsContainer.hideDefaultResizer();
+ this.viewsContainer.installResizer(this.retainmentViewHeader);
this.retainmentView = new WebInspector.View();
- this.retainmentView.element.addStyleClass("view");
- this.retainmentView.element.addStyleClass("retaining-paths-view");
+ this.retainmentView.element.classList.add("retaining-paths-view");
+ this.retainmentView.element.appendChild(this.retainmentViewHeader);
this.retainmentDataGrid = new WebInspector.HeapSnapshotRetainmentDataGrid();
this.retainmentDataGrid.show(this.retainmentView.element);
this.retainmentDataGrid.addEventListener(WebInspector.DataGrid.Events.SelectedNode, this._inspectedObjectChanged, this);
- this.retainmentView.show(this.element);
+ this.retainmentView.show(this.viewsContainer.sidebarElement());
this.retainmentDataGrid.reset();
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}];
+ this.views = [{title: WebInspector.UIString("Summary"), view: this.constructorsView, grid: this.constructorsDataGrid}];
+
+ if (profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
+ this.views.push({title: WebInspector.UIString("Comparison"), view: this.diffView, grid: this.diffDataGrid});
+ this.views.push({title: WebInspector.UIString("Containment"), view: this.containmentView, grid: this.containmentDataGrid});
if (WebInspector.settings.showAdvancedHeapSnapshotProperties.get())
- this.views.push({title: "Dominators", view: this.dominatorView, grid: this.dominatorDataGrid});
- if (WebInspector.HeapSnapshot.enableAllocationProfiler)
- this.views.push({title: "Allocation", view: this.allocationView, grid: this.allocationDataGrid});
+ this.views.push({title: WebInspector.UIString("Dominators"), view: this.dominatorView, grid: this.dominatorDataGrid});
+ if (this.allocationView)
+ this.views.push({title: WebInspector.UIString("Allocation"), view: this.allocationView, grid: this.allocationDataGrid});
this.views.current = 0;
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._profile = profile;
this.baseSelect = new WebInspector.StatusBarComboBox(this._changeBase.bind(this));
- this.baseSelect.element.addStyleClass("hidden");
this._updateBaseOptions();
- this.filterSelect = new WebInspector.StatusBarComboBox(this._changeFilter.bind(this));
+ this._filterSelect = new WebInspector.StatusBarComboBox(this._changeFilter.bind(this));
this._updateFilterOptions();
+ this._classNameFilter = new WebInspector.StatusBarInput("Class filter");
+ this._classNameFilter.setOnChangeHandler(this._onClassFilterChanged.bind(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));
+ this._updateSelectorsVisibility();
+ this._refreshView();
+}
- function profileCallback(heapSnapshotProxy)
+WebInspector.HeapSnapshotView.prototype = {
+ _refreshView: function()
{
- var list = this._profiles();
- var profileIndex;
- for (var i = 0; i < list.length; ++i) {
- if (list[i].uid === this._profileUid) {
- profileIndex = i;
- break;
- }
- }
+ this._profile.load(profileCallback.bind(this));
- if (profileIndex > 0)
- this.baseSelect.setSelectedIndex(profileIndex - 1);
- else
- this.baseSelect.setSelectedIndex(profileIndex);
- this.dataGrid.setDataSource(heapSnapshotProxy);
- }
-}
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function profileCallback(heapSnapshotProxy)
+ {
+ var list = this._profiles();
+ var profileIndex = list.indexOf(this._profile);
+ this.baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1));
+ this.dataGrid.setDataSource(heapSnapshotProxy);
+ if (this._trackingOverviewGrid)
+ this._trackingOverviewGrid._updateGrid();
+ }
+ },
-WebInspector.HeapSnapshotView.prototype = {
_onIdsRangeChanged: function(event)
{
var minId = event.data.minId;
this.constructorsDataGrid.setSelectionRange(minId, maxId);
},
- dispose: function()
- {
- this.parent.removeEventListener("profile added", this._onProfileHeaderAdded, this);
- this.profile.dispose();
- if (this.baseProfile)
- this.baseProfile.dispose();
- this.containmentDataGrid.dispose();
- this.constructorsDataGrid.dispose();
- this.diffDataGrid.dispose();
- this.dominatorDataGrid.dispose();
- this.retainmentDataGrid.dispose();
- },
-
get statusBarItems()
{
- return [this.viewSelect.element, this.baseSelect.element, this.filterSelect.element, this.selectedSizeText.element];
- },
-
- get profile()
- {
- return this.parent.getProfile(this._profileTypeId, this._profileUid);
- },
-
- get baseProfile()
- {
- return this.parent.getProfile(this._profileTypeId, this._baseProfileUid);
+ var result = [this.viewSelect.element, this._classNameFilter.element];
+ if (this._profile.profileType() !== WebInspector.ProfileTypeRegistry.instance.trackingHeapSnapshotProfileType)
+ result.push(this.baseSelect.element, this._filterSelect.element);
+ result.push(this.selectedSizeText.element);
+ return result;
},
wasShown: function()
{
// FIXME: load base and current snapshots in parallel
- this.profile.load(profileCallback.bind(this));
+ this._profile.load(profileCallback.bind(this));
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
function profileCallback() {
- this.profile._wasShown();
- if (this.baseProfile)
- this.baseProfile.load(function() { });
+ this._profile._wasShown();
+ if (this._baseProfile)
+ this._baseProfile.load(function() { });
}
},
this.helpPopover.hide();
},
- onResize: function()
- {
- var height = this.retainmentView.element.clientHeight;
- this._updateRetainmentViewHeight(height);
- },
-
searchCanceled: function()
{
if (this._searchResults) {
if (this.currentView !== this.constructorsView && this.currentView !== this.diffView)
return;
+ /**
+ * @param {boolean} found
+ * @this {WebInspector.HeapSnapshotView}
+ */
+ function didHighlight(found)
+ {
+ finishedCallback(this, found ? 1 : 0);
+ }
+
+ if (query.charAt(0) === "@") {
+ var snapshotNodeId = parseInt(query.substring(1), 10);
+ if (!isNaN(snapshotNodeId))
+ this.dataGrid.highlightObjectByHeapSnapshotId(String(snapshotNodeId), didHighlight.bind(this));
+ else
+ finishedCallback(this, 0);
+ return;
+ }
+
this._searchFinishedCallback = finishedCallback;
var nameRegExp = createPlainTextSearchRegex(query, "i");
- var snapshotNodeId = null;
function matchesByName(gridNode) {
return ("_name" in gridNode) && nameRegExp.test(gridNode._name);
}
- function matchesById(gridNode) {
- return ("snapshotNodeId" in gridNode) && gridNode.snapshotNodeId === snapshotNodeId;
- }
-
- var matchPredicate;
- if (query.charAt(0) !== "@")
- matchPredicate = matchesByName;
- else {
- snapshotNodeId = parseInt(query.substring(1), 10);
- matchPredicate = matchesById;
- }
-
function matchesQuery(gridNode)
{
delete gridNode._searchMatched;
- if (matchPredicate(gridNode)) {
+ if (matchesByName(gridNode)) {
gridNode._searchMatched = true;
gridNode.refresh();
return true;
this._jumpToSearchResult(this._currentSearchResultIndex);
},
+ /**
+ * @return {boolean}
+ */
showingFirstSearchResult: function()
{
return (this._currentSearchResultIndex === 0);
},
+ /**
+ * @return {boolean}
+ */
showingLastSearchResult: function()
{
return (this._searchResults && this._currentSearchResultIndex === (this._searchResults.length - 1));
},
+ /**
+ * @return {number}
+ */
+ currentSearchResultIndex: function() {
+ return this._currentSearchResultIndex;
+ },
+
_jumpToSearchResult: function(index)
{
var searchResult = this._searchResults[index];
_changeBase: function()
{
- if (this._baseProfileUid === this._profiles()[this.baseSelect.selectedIndex()].uid)
+ if (this._baseProfile=== this._profiles()[this.baseSelect.selectedIndex()])
return;
- this._baseProfileUid = this._profiles()[this.baseSelect.selectedIndex()].uid;
- var dataGrid = /** @type {WebInspector.HeapSnapshotDiffDataGrid} */ (this.dataGrid);
+ this._baseProfile = this._profiles()[this.baseSelect.selectedIndex()];
+ var dataGrid = /** @type {!WebInspector.HeapSnapshotDiffDataGrid} */ (this.dataGrid);
// Change set base data source only if main data source is already set.
if (dataGrid.snapshot)
- this.baseProfile.load(dataGrid.setBaseDataSource.bind(dataGrid));
+ this._baseProfile.load(dataGrid.setBaseDataSource.bind(dataGrid));
if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
return;
_changeFilter: function()
{
- var profileIndex = this.filterSelect.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.filterSelect.selectedOption().label
+ label: this._filterSelect.selectedOption().label
});
if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
this.performSearch(this.currentQuery, this._searchFinishedCallback);
},
- _createToolbarWithClassNameFilter: function()
- {
- var toolbar = document.createElement("div");
- toolbar.addStyleClass("class-view-toolbar");
- var classNameFilter = document.createElement("input");
- classNameFilter.addStyleClass("class-name-filter");
- classNameFilter.setAttribute("placeholder", WebInspector.UIString("Class filter"));
- classNameFilter.addEventListener("keyup", this._changeNameFilter.bind(this, classNameFilter), false);
- toolbar.appendChild(classNameFilter);
- return toolbar;
- },
-
- _changeNameFilter: function(classNameInputElement)
+ /**
+ * @param {string} value
+ */
+ _onClassFilterChanged: function(value)
{
- var filter = classNameInputElement.value;
- this.dataGrid.changeNameFilter(filter);
+ this.dataGrid.changeNameFilter(value);
},
/**
*/
_profiles: function()
{
- return this.parent.getProfileType(this._profileTypeId).getProfiles();
+ return this._profile.profileType().getProfiles();
},
/**
- * @param {WebInspector.ContextMenu} contextMenu
- * @param {Event} event
+ * @param {!WebInspector.ContextMenu} contextMenu
+ * @param {?Event} event
*/
populateContextMenu: function(contextMenu, event)
{
- this.dataGrid.populateContextMenu(this.parent, contextMenu, event);
+ this.dataGrid.populateContextMenu(contextMenu, event);
},
_selectionChanged: function(event)
_inspectedObjectChanged: function(event)
{
var selectedNode = event.target.selectedNode;
- if (!this.profile.fromFile() && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode)
+ if (!this._profile.fromFile() && selectedNode instanceof WebInspector.HeapSnapshotGenericObjectNode)
ConsoleAgent.addInspectedHeapObject(selectedNode.snapshotNodeId);
},
return;
var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
- if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("shallowSize-column") && !cell.hasStyleClass("retainedSize-column")))
+ if (!cell || (!cell.classList.contains("count-column") && !cell.classList.contains("shallowSize-column") && !cell.classList.contains("retainedSize-column")))
return;
event.consume(true);
return;
}
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
function dataGridContentShown(event)
{
var dataGrid = event.data;
if (dataGrid.snapshot)
return;
- this.profile.load(didLoadSnapshot.bind(this));
+ this._profile.load(didLoadSnapshot.bind(this));
+
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
function didLoadSnapshot(snapshotProxy)
{
if (this.dataGrid !== dataGrid)
if (dataGrid.snapshot !== snapshotProxy)
dataGrid.setDataSource(snapshotProxy);
if (dataGrid === this.diffDataGrid) {
- if (!this._baseProfileUid)
- this._baseProfileUid = this._profiles()[this.baseSelect.selectedIndex()].uid;
- this.baseProfile.load(didLoadBaseSnaphot.bind(this));
+ if (!this._baseProfile)
+ this._baseProfile = this._profiles()[this.baseSelect.selectedIndex()];
+ this._baseProfile.load(didLoadBaseSnaphot.bind(this));
}
}
+ /**
+ * @this {WebInspector.HeapSnapshotView}
+ */
function didLoadBaseSnaphot(baseSnapshotProxy)
{
if (this.diffDataGrid.baseSnapshot !== baseSnapshotProxy)
_updateSelectorsVisibility: function()
{
- if (this.currentView === this.diffView)
- this.baseSelect.element.removeStyleClass("hidden");
- else
- this.baseSelect.element.addStyleClass("hidden");
+ this.baseSelect.visible = (this.currentView === this.diffView);
+ this._filterSelect.visible = (this.currentView === this.constructorsView);
+ this._classNameFilter.visible = (this.currentView === this.constructorsView || this.currentView === this.diffView);
- if (this.currentView === this.constructorsView) {
- if (this._trackingOverviewGrid) {
- this._trackingOverviewGrid.element.removeStyleClass("hidden");
+ if (this._trackingOverviewGrid) {
+ this._trackingOverviewGrid.element.classList.toggle("hidden", this.currentView !== this.constructorsView);
+ if (this.currentView === this.constructorsView)
this._trackingOverviewGrid.update();
- 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");
- }
}
},
var view = this.views[this.views.current];
this.currentView = view.view;
this.dataGrid = view.grid;
- this.currentView.show(this.viewsContainer);
+ this.currentView.show(this.viewsContainer.mainElement());
this.refreshVisibleData();
this.dataGrid.updateWidths();
_resolveObjectForPopover: function(element, showCallback, objectGroupName)
{
- if (this.profile.fromFile())
+ if (this._profile.fromFile())
return;
element.node.queryObjectContent(showCallback, objectGroupName);
},
- /**
- * @return {boolean}
- */
- _startRetainersHeaderDragging: function(event)
- {
- if (!this.isShowing())
- return false;
-
- this._previousDragPosition = event.pageY;
- return true;
- },
-
- _retainersHeaderDragging: function(event)
- {
- var height = this.retainmentView.element.clientHeight;
- height += this._previousDragPosition - event.pageY;
- this._previousDragPosition = event.pageY;
- this._updateRetainmentViewHeight(height);
- event.consume(true);
- },
-
- _endRetainersHeaderDragging: function(event)
- {
- delete this._previousDragPosition;
- event.consume();
- },
-
- _updateRetainmentViewHeight: function(height)
- {
- 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();
- },
-
_updateBaseOptions: function()
{
var list = this._profiles();
{
var list = this._profiles();
// We're assuming that snapshots can only be added.
- if (this.filterSelect.size() - 1 === list.length)
+ if (this._filterSelect.size() - 1 === list.length)
return;
- if (!this.filterSelect.size())
- this.filterSelect.createOption(WebInspector.UIString("All objects"));
+ if (!this._filterSelect.size())
+ this._filterSelect.createOption(WebInspector.UIString("All objects"));
- for (var i = this.filterSelect.size() - 1, n = list.length; i < n; ++i) {
+ for (var i = this._filterSelect.size() - 1, n = list.length; i < n; ++i) {
var title = list[i].title;
if (!i)
title = WebInspector.UIString("Objects allocated before %s", title);
else
title = WebInspector.UIString("Objects allocated between %s and %s", list[i - 1].title, title);
- this.filterSelect.createOption(title);
+ this._filterSelect.createOption(title);
}
},
- /**
- * @param {WebInspector.Event} event
- */
- _onProfileHeaderAdded: function(event)
+ _updateControls: function()
{
- if (!event.data || event.data.type !== this._profileTypeId)
- return;
this._updateBaseOptions();
this._updateFilterOptions();
},
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onReceivSnapshot: function(event)
+ {
+ this._updateControls();
+ },
+
+ /**
+ * @param {!WebInspector.Event} event
+ */
+ _onProfileHeaderRemoved: function(event)
+ {
+ var profile = event.data;
+ if (this._profile === profile) {
+ this.detach();
+ this._profile.profileType().removeEventListener(WebInspector.ProfileType.Events.AddProfileHeader, this._onReceivSnapshot, this);
+ this._profile.profileType().removeEventListener(WebInspector.ProfileType.Events.RemoveProfileHeader, this._onProfileHeaderRemoved, this);
+ } else {
+ this._updateControls();
+ }
+ },
+
__proto__: WebInspector.View.prototype
}
WebInspector.HeapProfilerDispatcher.prototype = {
/**
- * @param {HeapProfilerAgent.Dispatcher} dispatcher
+ * @param {!HeapProfilerAgent.Dispatcher} dispatcher
*/
register: function(dispatcher)
{
/**
* @override
- * @param {Array.<number>} samples
+ * @param {!Array.<number>} samples
*/
heapStatsUpdate: function(samples)
{
},
/**
- * @param {HeapProfilerAgent.ProfileHeader} profileHeader
- */
- addProfileHeader: function(profileHeader)
- {
- this._genericCaller("addProfileHeader");
- },
-
- /**
* @override
- * @param {number} uid
* @param {string} chunk
*/
- addHeapSnapshotChunk: function(uid, chunk)
+ addHeapSnapshotChunk: function(chunk)
{
this._genericCaller("addHeapSnapshotChunk");
},
* @override
* @param {number} done
* @param {number} total
+ * @param {boolean=} finished
*/
- reportHeapSnapshotProgress: function(done, total)
+ reportHeapSnapshotProgress: function(done, total, finished)
{
this._genericCaller("reportHeapSnapshotProgress");
},
* @constructor
* @extends {WebInspector.ProfileType}
* @implements {HeapProfilerAgent.Dispatcher}
+ * @param {string=} id
+ * @param {string=} title
*/
-WebInspector.HeapSnapshotProfileType = function()
+WebInspector.HeapSnapshotProfileType = function(id, title)
{
- WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("Take Heap Snapshot"));
+ WebInspector.ProfileType.call(this, id || WebInspector.HeapSnapshotProfileType.TypeId, title || WebInspector.UIString("Take Heap Snapshot"));
WebInspector.HeapProfilerDispatcher._dispatcher.register(this);
}
/**
* @override
- * @param {Array.<number>} samples
+ * @param {!Array.<number>} samples
*/
heapStatsUpdate: function(samples)
{
/**
* @override
- * @param {string=} title
+ * @param {!string} title
* @return {!WebInspector.ProfileHeader}
*/
- createTemporaryProfile: function(title)
+ createProfileLoadedFromFile: function(title)
{
- title = title || WebInspector.UIString("Snapshotting\u2026");
return new WebInspector.HeapProfileHeader(this, title);
},
- /**
- * @override
- * @param {HeapProfilerAgent.ProfileHeader} profile
- * @return {!WebInspector.ProfileHeader}
- */
- createProfile: function(profile)
- {
- return new WebInspector.HeapProfileHeader(this, profile.title, profile.uid, profile.maxJSObjectId || 0);
- },
-
_takeHeapSnapshot: function(callback)
{
- var temporaryProfile = this.findTemporaryProfile();
- if (!temporaryProfile)
- this.addProfile(this.createTemporaryProfile());
- HeapProfilerAgent.takeHeapSnapshot(true, callback);
- },
-
- /**
- * @param {HeapProfilerAgent.ProfileHeader} profileHeader
- */
- addProfileHeader: function(profileHeader)
- {
- if (!this.findTemporaryProfile())
+ if (this.profileBeingRecorded())
return;
- var profile = this.createProfile(profileHeader);
- profile._profileSamples = this._profileSamples;
- this._profileSamples = null;
- this.addProfile(profile);
+ this._profileBeingRecorded = new WebInspector.HeapProfileHeader(this);
+ this.addProfile(this._profileBeingRecorded);
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString("Snapshotting\u2026"));
+
+ /**
+ * @param {?string} error
+ * @this {WebInspector.HeapSnapshotProfileType}
+ */
+ function didTakeHeapSnapshot(error)
+ {
+ var profile = this._profileBeingRecorded;
+ profile.title = WebInspector.UIString("Snapshot %d", profile.uid);
+ profile._finishLoad();
+ this._profileBeingRecorded = null;
+ WebInspector.panels.profiles.showProfile(profile);
+ callback();
+ }
+ HeapProfilerAgent.takeHeapSnapshot(true, didTakeHeapSnapshot.bind(this));
},
/**
* @override
- * @param {number} uid
* @param {string} chunk
*/
- addHeapSnapshotChunk: function(uid, chunk)
+ addHeapSnapshotChunk: function(chunk)
{
- var profile = this._profilesIdMap[this._makeKey(uid)];
- if (profile)
- profile.transferChunk(chunk);
+ if (!this.profileBeingRecorded())
+ return;
+ this.profileBeingRecorded().transferChunk(chunk);
},
/**
* @override
* @param {number} done
* @param {number} total
+ * @param {boolean=} finished
*/
- reportHeapSnapshotProgress: function(done, total)
+ reportHeapSnapshotProgress: function(done, total, finished)
{
- var profile = this.findTemporaryProfile();
- if (profile)
- this.dispatchEventToListeners(WebInspector.ProfileType.Events.ProgressUpdated, {"profile": profile, "done": done, "total": total});
+ var profile = this.profileBeingRecorded();
+ if (!profile)
+ return;
+ profile.updateStatus(WebInspector.UIString("%.0f%", (done / total) * 100), true);
+ if (finished)
+ profile._prepareToLoad();
},
/**
this._reset();
},
- /**
- * @override
- * @param {!WebInspector.ProfileHeader} profile
- */
- removeProfile: function(profile)
- {
- WebInspector.ProfileType.prototype.removeProfile.call(this, profile);
- if (!profile.isTemporary && !profile.fromFile())
- HeapProfilerAgent.removeProfile(profile.uid);
- },
-
_snapshotReceived: function(profile)
{
+ if (this._profileBeingRecorded === profile)
+ this._profileBeingRecorded = null;
this.dispatchEventToListeners(WebInspector.HeapSnapshotProfileType.SnapshotReceived, profile);
},
/**
* @constructor
* @extends {WebInspector.HeapSnapshotProfileType}
- * @param {WebInspector.ProfilesPanel} profilesPanel
*/
-WebInspector.TrackingHeapSnapshotProfileType = function(profilesPanel)
+WebInspector.TrackingHeapSnapshotProfileType = function()
{
- WebInspector.ProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Record Heap Allocations"));
- this._profilesPanel = profilesPanel;
- WebInspector.HeapProfilerDispatcher._dispatcher.register(this);
+ WebInspector.HeapSnapshotProfileType.call(this, WebInspector.TrackingHeapSnapshotProfileType.TypeId, WebInspector.UIString("Record Heap Allocations"));
}
WebInspector.TrackingHeapSnapshotProfileType.TypeId = "HEAP-RECORD";
/**
* @override
- * @param {Array.<number>} samples
+ * @param {!Array.<number>} samples
*/
heapStatsUpdate: function(samples)
{
if (profileSamples.totalTime < timestamp - profileSamples.timestamps[0])
profileSamples.totalTime *= 2;
this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._profileSamples);
- var profile = this.findTemporaryProfile();
- profile.sidebarElement.wait = true;
- if (profile.sidebarElement && !profile.sidebarElement.wait)
- profile.sidebarElement.wait = true;
+ this._profileBeingRecorded.updateStatus(null, true);
},
/**
_startRecordingProfile: function()
{
+ if (this.profileBeingRecorded())
+ return;
+ this._profileBeingRecorded = new WebInspector.HeapProfileHeader(this);
this._lastSeenIndex = -1;
this._profileSamples = {
'sizes': [],
'max': [],
'totalTime': 30000
};
+ this._profileBeingRecorded._profileSamples = this._profileSamples;
this._recording = true;
- HeapProfilerAgent.startTrackingHeapObjects();
+ this.addProfile(this._profileBeingRecorded);
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString("Recording\u2026"));
+ HeapProfilerAgent.startTrackingHeapObjects(WebInspector.experimentsSettings.allocationProfiler.isEnabled());
this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStarted);
},
_stopRecordingProfile: function()
{
- HeapProfilerAgent.stopTrackingHeapObjects();
- HeapProfilerAgent.takeHeapSnapshot(true);
+ this._profileBeingRecorded.updateStatus(WebInspector.UIString("Snapshotting\u2026"));
+ /**
+ * @param {?string} error
+ * @this {WebInspector.HeapSnapshotProfileType}
+ */
+ function didTakeHeapSnapshot(error)
+ {
+ var profile = this._profileBeingRecorded;
+ if (!profile)
+ return;
+ profile._finishLoad();
+ this._profileSamples = null;
+ this._profileBeingRecorded = null;
+ WebInspector.panels.profiles.showProfile(profile);
+ }
+
+ HeapProfilerAgent.stopTrackingHeapObjects(true, didTakeHeapSnapshot.bind(this));
this._recording = false;
this.dispatchEventToListeners(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped);
},
/**
* @override
- * @param {string=} title
- * @return {!WebInspector.ProfileHeader}
*/
- createTemporaryProfile: function(title)
+ profileBeingRecordedRemoved: function()
{
- title = title || WebInspector.UIString("Recording\u2026");
- return new WebInspector.HeapProfileHeader(this, title);
+ this._stopRecordingProfile();
+ this._profileSamples = null;
},
__proto__: WebInspector.HeapSnapshotProfileType.prototype
/**
* @constructor
* @extends {WebInspector.ProfileHeader}
- * @param {!WebInspector.ProfileType} type
- * @param {string} title
- * @param {number=} uid
- * @param {number=} maxJSObjectId
+ * @param {!WebInspector.HeapSnapshotProfileType} type
+ * @param {string=} title
*/
-WebInspector.HeapProfileHeader = function(type, title, uid, maxJSObjectId)
+WebInspector.HeapProfileHeader = function(type, title)
{
- WebInspector.ProfileHeader.call(this, type, title, uid);
- this.maxJSObjectId = maxJSObjectId;
+ WebInspector.ProfileHeader.call(this, type, title || WebInspector.UIString("Snapshot %d", type._nextProfileUid));
+ this.maxJSObjectId = -1;
/**
- * @type {WebInspector.OutputStream}
+ * @type {?WebInspector.HeapSnapshotWorkerProxy}
+ */
+ this._workerProxy = null;
+ /**
+ * @type {?WebInspector.OutputStream}
*/
this._receiver = null;
/**
- * @type {WebInspector.HeapSnapshotProxy}
+ * @type {?WebInspector.HeapSnapshotProxy}
*/
this._snapshotProxy = null;
+ /**
+ * @type {?Array.<function(!WebInspector.HeapSnapshotProxy)>}
+ */
+ this._loadCallbacks = [];
this._totalNumberOfChunks = 0;
- this._transferHandler = null;
+ this._bufferedWriter = null;
}
WebInspector.HeapProfileHeader.prototype = {
/**
* @override
+ * @return {!WebInspector.ProfileSidebarTreeElement}
*/
createSidebarTreeElement: function()
{
- return new WebInspector.ProfileSidebarTreeElement(this, WebInspector.UIString("Snapshot %d"), "heap-snapshot-sidebar-tree-item");
+ return new WebInspector.ProfileSidebarTreeElement(this, "heap-snapshot-sidebar-tree-item");
},
/**
* @override
- * @param {!WebInspector.ProfilesPanel} profilesPanel
+ * @return {!WebInspector.HeapSnapshotView}
*/
- createView: function(profilesPanel)
+ createView: function()
{
- return new WebInspector.HeapSnapshotView(profilesPanel, this);
+ return new WebInspector.HeapSnapshotView(this);
},
/**
* @override
- * @param {function(WebInspector.HeapSnapshotProxy):void} callback
+ * @param {function(!WebInspector.HeapSnapshotProxy):void} callback
*/
load: function(callback)
{
callback(this._snapshotProxy);
return;
}
-
- this._numberOfChunks = 0;
- if (!this._receiver) {
- this._setupWorker();
- this._transferHandler = new WebInspector.BackendSnapshotLoader(this);
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
- this.sidebarElement.wait = true;
- this._transferSnapshot();
- }
- var loaderProxy = /** @type {WebInspector.HeapSnapshotLoaderProxy} */ (this._receiver);
- loaderProxy.addConsumer(callback);
+ this._loadCallbacks.push(callback);
},
- _transferSnapshot: function()
+ _prepareToLoad: function()
{
- function finishTransfer()
- {
- if (this._transferHandler) {
- this._transferHandler.finishTransfer();
- this._totalNumberOfChunks = this._transferHandler._totalNumberOfChunks;
- }
- }
- HeapProfilerAgent.getHeapSnapshot(this.uid, finishTransfer.bind(this));
+ console.assert(!this._receiver, "Already loading");
+ this._setupWorker();
+ this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
},
- snapshotConstructorName: function()
+ _finishLoad: function()
{
- return "JSHeapSnapshot";
+ this._receiver.close(function() {});
+ if (this._bufferedWriter) {
+ this._bufferedWriter.close(this._didWriteToTempFile.bind(this));
+ this._bufferedWriter = null;
+ }
},
- snapshotProxyConstructor: function()
+ _didWriteToTempFile: function(tempFile)
{
- return WebInspector.HeapSnapshotProxy;
+ this._tempFile = tempFile;
+ if (!tempFile)
+ this._failedToCreateTempFile = true;
+ if (this._onTempFileReady) {
+ this._onTempFileReady();
+ this._onTempFileReady = null;
+ }
},
_setupWorker: function()
{
+ /**
+ * @this {WebInspector.HeapProfileHeader}
+ */
function setProfileWait(event)
{
- this.sidebarElement.wait = event.data;
+ this.updateStatus(null, event.data);
}
- var worker = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
- worker.addEventListener("wait", setProfileWait, this);
- var loaderProxy = worker.createLoader(this.snapshotConstructorName(), this.snapshotProxyConstructor());
- loaderProxy.addConsumer(this._snapshotReceived.bind(this));
- this._receiver = loaderProxy;
+ console.assert(!this._workerProxy, "HeapSnapshotWorkerProxy already exists");
+ this._workerProxy = new WebInspector.HeapSnapshotWorkerProxy(this._handleWorkerEvent.bind(this));
+ this._workerProxy.addEventListener("wait", setProfileWait, this);
+ this._receiver = this._workerProxy.createLoader(this.uid, this._snapshotReceived.bind(this));
},
/**
- * @param{string} eventName
- * @param{*} data
+ * @param {string} eventName
+ * @param {*} data
*/
_handleWorkerEvent: function(eventName, data)
{
- if (WebInspector.HeapSnapshotProgress.Event.Update !== eventName)
+ if (WebInspector.HeapSnapshotProgressEvent.Update !== eventName)
return;
- this._updateSubtitle(data);
+ var subtitle = /** @type {string} */ (data);
+ this.updateStatus(subtitle);
},
/**
*/
dispose: function()
{
- if (this._receiver)
- this._receiver.close();
- else if (this._snapshotProxy)
- this._snapshotProxy.dispose();
- if (this._view) {
- var view = this._view;
- this._view = null;
- view.dispose();
- }
- },
-
- _updateSubtitle: function(value)
- {
- this.sidebarElement.subtitle = value;
+ if (this._workerProxy)
+ this._workerProxy.dispose();
+ this.removeTempFile();
+ this._wasDisposed = true;
},
_didCompleteSnapshotTransfer: function()
{
- this.sidebarElement.subtitle = Number.bytesToString(this._snapshotProxy.totalSize);
- this.sidebarElement.wait = false;
+ if (!this._snapshotProxy)
+ return;
+ this.updateStatus(Number.bytesToString(this._snapshotProxy.totalSize), false);
},
/**
*/
transferChunk: function(chunk)
{
- this._transferHandler.transferChunk(chunk);
+ if (!this._bufferedWriter)
+ this._bufferedWriter = new WebInspector.BufferedTempFileWriter("heap-profiler", this.uid);
+ this._bufferedWriter.write(chunk);
+
+ ++this._totalNumberOfChunks;
+ this._receiver.write(chunk, function() {});
},
_snapshotReceived: function(snapshotProxy)
{
+ if (this._wasDisposed)
+ return;
this._receiver = null;
- if (snapshotProxy)
- this._snapshotProxy = snapshotProxy;
+ this._snapshotProxy = snapshotProxy;
+ this.maxJSObjectId = snapshotProxy.maxJSObjectId();
this._didCompleteSnapshotTransfer();
- var worker = /** @type {WebInspector.HeapSnapshotWorkerProxy} */ (this._snapshotProxy.worker);
- this.isTemporary = false;
- worker.startCheckingForLongRunningCalls();
+ this._workerProxy.startCheckingForLongRunningCalls();
this.notifySnapshotReceived();
-
- if (this.fromFile()) {
- function didGetMaxNodeId(id)
- {
- this.maxJSObjectId = id;
- }
- snapshotProxy.maxJsNodeId(didGetMaxNodeId.bind(this));
- }
},
notifySnapshotReceived: function()
{
+ for (var i = 0; i < this._loadCallbacks.length; i++)
+ this._loadCallbacks[i](this._snapshotProxy);
+ this._loadCallbacks = null;
this._profileType._snapshotReceived(this);
+ if (this.canSaveToFile())
+ this.dispatchEventToListeners(WebInspector.ProfileHeader.Events.ProfileReceived);
},
// Hook point for tests.
*/
canSaveToFile: function()
{
- return !this.fromFile() && !!this._snapshotProxy && !this._receiver;
+ return !this.fromFile() && this._snapshotProxy;
},
/**
saveToFile: function()
{
var fileOutputStream = new WebInspector.FileOutputStream();
- function onOpen()
+
+ /**
+ * @param {boolean} accepted
+ * @this {WebInspector.HeapProfileHeader}
+ */
+ function onOpen(accepted)
{
- this._receiver = fileOutputStream;
- this._transferHandler = new WebInspector.SaveSnapshotHandler(this);
- this._transferSnapshot();
+ if (!accepted)
+ return;
+ if (this._failedToCreateTempFile) {
+ WebInspector.log("Failed to open temp file with heap snapshot",
+ WebInspector.ConsoleMessage.MessageLevel.Error);
+ fileOutputStream.close();
+ } else if (this._tempFile) {
+ var delegate = new WebInspector.SaveSnapshotOutputStreamDelegate(this);
+ this._tempFile.writeToOutputSteam(fileOutputStream, delegate);
+ } else {
+ this._onTempFileReady = onOpen.bind(this, accepted);
+ this._updateSaveProgress(0, 1);
+ }
}
this._fileName = this._fileName || "Heap-" + new Date().toISO8601Compact() + this._profileType.fileExtension();
fileOutputStream.open(this._fileName, onOpen.bind(this));
},
+ _updateSaveProgress: function(value, total)
+ {
+ var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0);
+ this.updateStatus(WebInspector.UIString("Saving\u2026 %d\%", percentValue));
+ },
+
/**
* @override
- * @param {File} file
+ * @param {!File} file
*/
loadFromFile: function(file)
{
- this.sidebarElement.subtitle = WebInspector.UIString("Loading\u2026");
- this.sidebarElement.wait = true;
+ this.updateStatus(WebInspector.UIString("Loading\u2026"), true);
this._setupWorker();
-
var delegate = new WebInspector.HeapSnapshotLoadFromFileDelegate(this);
var fileReader = this._createFileReader(file, delegate);
fileReader.start(this._receiver);
__proto__: WebInspector.ProfileHeader.prototype
}
-
/**
* @constructor
- * @param {WebInspector.HeapProfileHeader} header
- * @param {string} title
+ * @implements {WebInspector.OutputStreamDelegate}
*/
-WebInspector.SnapshotTransferHandler = function(header, title)
+WebInspector.HeapSnapshotLoadFromFileDelegate = function(snapshotHeader)
{
- this._numberOfChunks = 0;
- this._savedChunks = 0;
- this._header = header;
- this._totalNumberOfChunks = 0;
- this._title = title;
+ this._snapshotHeader = snapshotHeader;
}
-
-WebInspector.SnapshotTransferHandler.prototype = {
- /**
- * @param {string} chunk
- */
- transferChunk: function(chunk)
+WebInspector.HeapSnapshotLoadFromFileDelegate.prototype = {
+ onTransferStarted: function()
{
- ++this._numberOfChunks;
- this._header._receiver.write(chunk, this._didTransferChunk.bind(this));
},
- finishTransfer: function()
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ */
+ onChunkTransferred: function(reader)
{
},
- _didTransferChunk: function()
+ onTransferFinished: function()
{
- this._updateProgress(++this._savedChunks, this._totalNumberOfChunks);
},
- _updateProgress: function(value, total)
- {
- }
-}
-
-
-/**
- * @constructor
- * @param {WebInspector.HeapProfileHeader} header
- * @extends {WebInspector.SnapshotTransferHandler}
- */
-WebInspector.SaveSnapshotHandler = function(header)
-{
- WebInspector.SnapshotTransferHandler.call(this, header, "Saving\u2026 %d\%");
- this._totalNumberOfChunks = header._totalNumberOfChunks;
- this._updateProgress(0, this._totalNumberOfChunks);
-}
-
-
-WebInspector.SaveSnapshotHandler.prototype = {
- _updateProgress: function(value, total)
+ /**
+ * @param {!WebInspector.ChunkedReader} reader
+ */
+ onError: function (reader, e)
{
- var percentValue = ((total ? (value / total) : 0) * 100).toFixed(0);
- this._header._updateSubtitle(WebInspector.UIString(this._title, percentValue));
- if (value === total) {
- this._header._receiver.close();
- this._header._didCompleteSnapshotTransfer();
+ var subtitle;
+ switch(e.target.error.code) {
+ case e.target.error.NOT_FOUND_ERR:
+ subtitle = WebInspector.UIString("'%s' not found.", reader.fileName());
+ break;
+ case e.target.error.NOT_READABLE_ERR:
+ subtitle = WebInspector.UIString("'%s' is not readable", reader.fileName());
+ break;
+ case e.target.error.ABORT_ERR:
+ return;
+ default:
+ subtitle = WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code);
}
- },
-
- __proto__: WebInspector.SnapshotTransferHandler.prototype
+ this._snapshotHeader.updateStatus(subtitle);
+ }
}
-
/**
* @constructor
- * @param {WebInspector.HeapProfileHeader} header
- * @extends {WebInspector.SnapshotTransferHandler}
+ * @implements {WebInspector.OutputStreamDelegate}
+ * @param {!WebInspector.HeapProfileHeader} profileHeader
*/
-WebInspector.BackendSnapshotLoader = function(header)
+WebInspector.SaveSnapshotOutputStreamDelegate = function(profileHeader)
{
- WebInspector.SnapshotTransferHandler.call(this, header, "Loading\u2026 %d\%");
+ this._profileHeader = profileHeader;
}
-
-WebInspector.BackendSnapshotLoader.prototype = {
- finishTransfer: function()
- {
- this._header._receiver.close(this._didFinishTransfer.bind(this));
- this._totalNumberOfChunks = this._numberOfChunks;
- },
-
- _didFinishTransfer: function()
+WebInspector.SaveSnapshotOutputStreamDelegate.prototype = {
+ onTransferStarted: function()
{
- console.assert(this._totalNumberOfChunks === this._savedChunks, "Not all chunks were transfered.");
+ this._profileHeader._updateSaveProgress(0, 1);
},
- __proto__: WebInspector.SnapshotTransferHandler.prototype
-}
-
-
-/**
- * @constructor
- * @implements {WebInspector.OutputStreamDelegate}
- */
-WebInspector.HeapSnapshotLoadFromFileDelegate = function(snapshotHeader)
-{
- this._snapshotHeader = snapshotHeader;
-}
-
-WebInspector.HeapSnapshotLoadFromFileDelegate.prototype = {
- onTransferStarted: function()
+ onTransferFinished: function()
{
+ this._profileHeader._didCompleteSnapshotTransfer();
},
/**
- * @param {WebInspector.ChunkedReader} reader
+ * @param {!WebInspector.ChunkedReader} reader
*/
onChunkTransferred: function(reader)
{
- },
-
- onTransferFinished: function()
- {
+ this._profileHeader._updateSaveProgress(reader.loadedSize(), reader.fileSize());
},
/**
- * @param {WebInspector.ChunkedReader} reader
+ * @param {!WebInspector.ChunkedReader} reader
*/
- onError: function (reader, e)
+ onError: function(reader, event)
{
- switch(e.target.error.code) {
- case e.target.error.NOT_FOUND_ERR:
- this._snapshotHeader._updateSubtitle(WebInspector.UIString("'%s' not found.", reader.fileName()));
- break;
- case e.target.error.NOT_READABLE_ERR:
- this._snapshotHeader._updateSubtitle(WebInspector.UIString("'%s' is not readable", reader.fileName()));
- break;
- case e.target.error.ABORT_ERR:
- break;
- default:
- this._snapshotHeader._updateSubtitle(WebInspector.UIString("'%s' error %d", reader.fileName(), e.target.error.code));
- }
+ WebInspector.log("Failed to read heap snapshot from temp file: " + event.message,
+ WebInspector.ConsoleMessage.MessageLevel.Error);
+ this.onTransferFinished();
}
}
WebInspector.View.call(this);
this.registerRequiredCSS("flameChart.css");
this.element.id = "heap-recording-view";
+ this.element.classList.add("heap-tracking-overview");
this._overviewContainer = this.element.createChild("div", "overview-container");
this._overviewGrid = new WebInspector.OverviewGrid("heap-recording");
+ this._overviewGrid.element.classList.add("fill");
+
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 || heapProfileHeader._profileType._profileSamples;
- if (heapProfileHeader.isTemporary) {
+ this._profileSamples = heapProfileHeader._profileSamples;
+ if (heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) {
this._profileType = heapProfileHeader._profileType;
this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this);
this._profileType.addEventListener(WebInspector.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this);
var scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime);
var maxSize = 0;
/**
- * @param {Array.<number>} sizes
+ * @param {!Array.<number>} sizes
* @param {function(number, number):void} callback
*/
function aggregateAndCall(sizes, callback)
WebInspector.HeapTrackingOverviewGrid.OverviewCalculator.prototype = {
/**
- * @param {WebInspector.HeapTrackingOverviewGrid} chart
+ * @param {!WebInspector.HeapTrackingOverviewGrid} chart
*/
_updateBoundaries: function(chart)
{
/**
* @param {number} time
+ * @return {number}
*/
computePosition: function(time)
{
return (time - this._minimumBoundaries) * this._xScaleFactor;
},
- formatTime: function(value)
+ /**
+ * @param {number} value
+ * @param {boolean=} hires
+ * @return {string}
+ */
+ formatTime: function(value, hires)
{
- return Number.secondsToString((value + this._minimumBoundaries) / 1000);
+ return Number.secondsToString((value + this._minimumBoundaries) / 1000, hires);
},
+ /**
+ * @return {number}
+ */
maximumBoundary: function()
{
return this._maximumBoundaries;
},
+ /**
+ * @return {number}
+ */
minimumBoundary: function()
{
return this._minimumBoundaries;
},
+ /**
+ * @return {number}
+ */
zeroTime: function()
{
return this._minimumBoundaries;
},
+ /**
+ * @return {number}
+ */
boundarySpan: function()
{
return this._maximumBoundaries - this._minimumBoundaries;