[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
mnaganov at chromium.org
mnaganov at chromium.org
Wed Dec 22 12:39:07 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 06106af7785a108c6d34b3aefde2faae5653cbec
Author: mnaganov at chromium.org <mnaganov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Aug 26 18:27:24 2010 +0000
2010-08-26 Mikhail Naganov <mnaganov at chromium.org>
Reviewed by Pavel Feldman.
Web Inspector: Store heap snapshots in InspectorProfilerAgent.
Change the way heap snapshots are transported to Inspector
to be aligned with CPU profiles. As a result, the Heap snapshots
view of Profiles panel was upstreamed into WebCore.
https://bugs.webkit.org/show_bug.cgi?id=44531
* English.lproj/localizedStrings.js:
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/ScriptHeapSnapshot.h: Added.
(WebCore::ScriptHeapSnapshot::~ScriptHeapSnapshot):
(WebCore::ScriptHeapSnapshot::title):
(WebCore::ScriptHeapSnapshot::uid):
(WebCore::ScriptHeapSnapshot::buildInspectorObjectForHead):
(WebCore::ScriptHeapSnapshot::ScriptHeapSnapshot):
* bindings/js/ScriptProfiler.h:
(WebCore::ScriptProfiler::takeHeapSnapshot):
* bindings/v8/ScriptHeapSnapshot.cpp: Added.
(WebCore::ScriptHeapSnapshot::title):
(WebCore::ScriptHeapSnapshot::uid):
(WebCore::buildInspectorObjectFor):
(WebCore::ScriptHeapSnapshot::buildInspectorObjectForHead):
* bindings/v8/ScriptHeapSnapshot.h: Added.
(WebCore::ScriptHeapSnapshot::create):
(WebCore::ScriptHeapSnapshot::~ScriptHeapSnapshot):
(WebCore::ScriptHeapSnapshot::ScriptHeapSnapshot):
* bindings/v8/ScriptProfile.cpp:
(WebCore::buildInspectorObjectFor):
* bindings/v8/ScriptProfiler.cpp:
(WebCore::ScriptProfiler::takeHeapSnapshot):
* bindings/v8/ScriptProfiler.h:
* inspector/Inspector.idl:
* inspector/InspectorBackend.cpp:
* inspector/InspectorBackend.h:
* inspector/InspectorProfilerAgent.cpp:
(WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
(WebCore::InspectorProfilerAgent::createSnapshotHeader):
(WebCore::InspectorProfilerAgent::getProfileHeaders):
(WebCore::InspectorProfilerAgent::getProfile):
(WebCore::InspectorProfilerAgent::removeProfile):
(WebCore::InspectorProfilerAgent::resetState):
(WebCore::InspectorProfilerAgent::takeHeapSnapshot):
* inspector/InspectorProfilerAgent.h:
* inspector/front-end/HeapSnapshotView.js: Added.
(WebInspector.HeapSnapshotView.profileCallback):
(WebInspector.HeapSnapshotView.resetCompleted):
(WebInspector.HeapSnapshotView):
(WebInspector.HeapSnapshotView.prototype.get statusBarItems):
(WebInspector.HeapSnapshotView.prototype.get profile):
(WebInspector.HeapSnapshotView.prototype.set profile):
(WebInspector.HeapSnapshotView.prototype.show):
(WebInspector.HeapSnapshotView.prototype.hide):
(WebInspector.HeapSnapshotView.prototype.resize):
(WebInspector.HeapSnapshotView.prototype.refresh):
(WebInspector.HeapSnapshotView.prototype.refreshShowAsPercents):
(WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags):
(WebInspector.HeapSnapshotView.prototype.searchCanceled):
(WebInspector.HeapSnapshotView.prototype.performSearch):
(WebInspector.HeapSnapshotView.prototype.jumpToFirstSearchResult.WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult.jumpToLastSearchResult.WebInspector.CPUProfileView.prototype.jumpToLastSearchResult.jumpToNextSearchResult.WebInspector.CPUProfileView.prototype.jumpToNextSearchResult.jumpToPreviousSearchResult.WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult.showingFirstSearchResult.WebInspector.CPUProfileView.prototype.showingFirstSearchResult.showingLastSearchResult.WebInspector.CPUProfileView.prototype.showingLastSearchResult._jumpToSearchResult.WebInspector.CPUProfileView.prototype._jumpToSearchResult.refreshVisibleData):
(WebInspector.HeapSnapshotView.prototype._changeBase.resetCompleted):
(WebInspector.HeapSnapshotView.prototype._changeBase):
(WebInspector.HeapSnapshotView.prototype._createSnapshotDataGridList):
(WebInspector.HeapSnapshotView.prototype._getProfiles):
(WebInspector.HeapSnapshotView.prototype._loadProfile.loadedCallback):
(WebInspector.HeapSnapshotView.prototype._loadProfile):
(WebInspector.HeapSnapshotView.prototype._mouseDownInDataGrid):
(WebInspector.HeapSnapshotView.prototype.get _isShowingAsPercent):
(WebInspector.HeapSnapshotView.prototype._percentClicked):
(WebInspector.HeapSnapshotView.prototype._prepareProfile.mergeRetainers):
(WebInspector.HeapSnapshotView.prototype._prepareProfile):
(WebInspector.HeapSnapshotView.prototype._resetDataGridList.profileLoaded):
(WebInspector.HeapSnapshotView.prototype._resetDataGridList):
(WebInspector.HeapSnapshotView.prototype._sortData):
(WebInspector.HeapSnapshotView.prototype._updateBaseOptions):
(WebInspector.HeapSnapshotView.prototype._updatePercentButton):
(WebInspector.HeapSnapshotView.prototype._updateSummaryGraph):
(WebInspector.HeapSnapshotView.SearchHelper.operations.LESS):
(WebInspector.HeapSnapshotView.SearchHelper.operations.LESS_OR_EQUAL):
(WebInspector.HeapSnapshotView.SearchHelper.operations.EQUAL):
(WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER_OR_EQUAL):
(WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER):
(WebInspector.HeapSnapshotView.SearchHelper.parseOperationAndNumber):
(WebInspector.HeapSummaryCalculator):
(WebInspector.HeapSummaryCalculator.prototype.computeSummaryValues):
(WebInspector.HeapSummaryCalculator.prototype.formatValue):
(WebInspector.HeapSummaryCalculator.prototype.get showAsPercent):
(WebInspector.HeapSummaryCalculator.prototype.set showAsPercent):
(WebInspector.HeapSummaryCountCalculator):
(WebInspector.HeapSummaryCountCalculator.prototype._highFromLow):
(WebInspector.HeapSummaryCountCalculator.prototype._valueToString):
(WebInspector.HeapSummarySizeCalculator):
(WebInspector.HeapSummarySizeCalculator.prototype._highFromLow):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _hasRetainers):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _parent):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype._populate):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.signForDelta):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.showDeltaAsPercent):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countPercent):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizePercent):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countDeltaPercent):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizeDeltaPercent):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get data):
(WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.createCell):
(WebInspector.HeapSnapshotDataGridNode):
(WebInspector.HeapSnapshotDataGridList):
(WebInspector.HeapSnapshotDataGridList.prototype.appendChild):
(WebInspector.HeapSnapshotDataGridList.prototype.insertChild):
(WebInspector.HeapSnapshotDataGridList.prototype.removeChildren):
(WebInspector.HeapSnapshotDataGridList.prototype.populateChildren):
(WebInspector.HeapSnapshotDataGridList.propertyComparator.comparator):
(WebInspector.HeapSnapshotDataGridList.propertyComparator):
(WebInspector.HeapSnapshotDataGridRetainerNode):
(WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizePercent):
(WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizeDeltaPercent):
(WebInspector.HeapSnapshotDataGridRetainerNode.prototype._calculateRetainers):
(WebInspector.HeapSnapshotProfileType):
(WebInspector.HeapSnapshotProfileType.prototype.get buttonTooltip):
(WebInspector.HeapSnapshotProfileType.prototype.get buttonStyle):
(WebInspector.HeapSnapshotProfileType.prototype.buttonClicked):
(WebInspector.HeapSnapshotProfileType.prototype.get welcomeMessage):
(WebInspector.HeapSnapshotProfileType.prototype.createSidebarTreeElementForProfile):
(WebInspector.HeapSnapshotProfileType.prototype.createView):
* inspector/front-end/ProfileView.js:
(WebInspector.CPUProfileView):
(WebInspector.CPUProfileType.prototype.createSidebarTreeElementForProfile):
* inspector/front-end/ProfilesPanel.js:
(WebInspector.ProfilesPanel.prototype.addProfileHeader):
(WebInspector.ProfilesPanel.prototype.removeProfileHeader):
(WebInspector.ProfilesPanel.prototype.getProfiles):
(WebInspector.ProfilesPanel.prototype.updateProfile):
(WebInspector.ProfileSidebarTreeElement):
(WebInspector.ProfileSidebarTreeElement.prototype.get mainTitle):
* inspector/front-end/WebKit.qrc:
* inspector/front-end/inspector.css:
(.heap-snapshot-sidebar-tree-item .icon):
(.heap-snapshot-sidebar-tree-item.small .icon):
(.heap-snapshot-view):
(.heap-snapshot-view.visible):
(.heap-snapshot-view .data-grid):
(.heap-snapshot-view .data-grid th.count-column):
(.heap-snapshot-view .data-grid td.count-column):
(.heap-snapshot-view .data-grid th.size-column):
(.heap-snapshot-view .data-grid td.size-column):
(.heap-snapshot-view .data-grid th.countDelta-column):
(.heap-snapshot-view .data-grid td.countDelta-column):
(.heap-snapshot-view .data-grid th.sizeDelta-column):
(.heap-snapshot-view .data-grid td.sizeDelta-column):
(#heap-snapshot-summary-container):
(.heap-snapshot-summary):
(.heap-snapshot-summary canvas.summary-graph):
(.heap-snapshot-summary-label):
* inspector/front-end/inspector.html:
* inspector/front-end/inspector.js:
(WebInspector._createPanels):
* DEPS:
* WebKit.gypi:
* src/js/DevTools.js:
():
* src/js/HeapProfilerPanel.js: Removed.
* src/js/ProfilerAgent.js: Removed.
* src/js/ProfilerProcessor.js: Removed.
* src/js/devTools.css:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66117 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index be6f489..2c83237 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,172 @@
+2010-08-26 Mikhail Naganov <mnaganov at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: Store heap snapshots in InspectorProfilerAgent.
+
+ Change the way heap snapshots are transported to Inspector
+ to be aligned with CPU profiles. As a result, the Heap snapshots
+ view of Profiles panel was upstreamed into WebCore.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44531
+
+ * English.lproj/localizedStrings.js:
+ * GNUmakefile.am:
+ * WebCore.gypi:
+ * WebCore.pro:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/ScriptHeapSnapshot.h: Added.
+ (WebCore::ScriptHeapSnapshot::~ScriptHeapSnapshot):
+ (WebCore::ScriptHeapSnapshot::title):
+ (WebCore::ScriptHeapSnapshot::uid):
+ (WebCore::ScriptHeapSnapshot::buildInspectorObjectForHead):
+ (WebCore::ScriptHeapSnapshot::ScriptHeapSnapshot):
+ * bindings/js/ScriptProfiler.h:
+ (WebCore::ScriptProfiler::takeHeapSnapshot):
+ * bindings/v8/ScriptHeapSnapshot.cpp: Added.
+ (WebCore::ScriptHeapSnapshot::title):
+ (WebCore::ScriptHeapSnapshot::uid):
+ (WebCore::buildInspectorObjectFor):
+ (WebCore::ScriptHeapSnapshot::buildInspectorObjectForHead):
+ * bindings/v8/ScriptHeapSnapshot.h: Added.
+ (WebCore::ScriptHeapSnapshot::create):
+ (WebCore::ScriptHeapSnapshot::~ScriptHeapSnapshot):
+ (WebCore::ScriptHeapSnapshot::ScriptHeapSnapshot):
+ * bindings/v8/ScriptProfile.cpp:
+ (WebCore::buildInspectorObjectFor):
+ * bindings/v8/ScriptProfiler.cpp:
+ (WebCore::ScriptProfiler::takeHeapSnapshot):
+ * bindings/v8/ScriptProfiler.h:
+ * inspector/Inspector.idl:
+ * inspector/InspectorBackend.cpp:
+ * inspector/InspectorBackend.h:
+ * inspector/InspectorProfilerAgent.cpp:
+ (WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
+ (WebCore::InspectorProfilerAgent::createSnapshotHeader):
+ (WebCore::InspectorProfilerAgent::getProfileHeaders):
+ (WebCore::InspectorProfilerAgent::getProfile):
+ (WebCore::InspectorProfilerAgent::removeProfile):
+ (WebCore::InspectorProfilerAgent::resetState):
+ (WebCore::InspectorProfilerAgent::takeHeapSnapshot):
+ * inspector/InspectorProfilerAgent.h:
+ * inspector/front-end/HeapSnapshotView.js: Added.
+ (WebInspector.HeapSnapshotView.profileCallback):
+ (WebInspector.HeapSnapshotView.resetCompleted):
+ (WebInspector.HeapSnapshotView):
+ (WebInspector.HeapSnapshotView.prototype.get statusBarItems):
+ (WebInspector.HeapSnapshotView.prototype.get profile):
+ (WebInspector.HeapSnapshotView.prototype.set profile):
+ (WebInspector.HeapSnapshotView.prototype.show):
+ (WebInspector.HeapSnapshotView.prototype.hide):
+ (WebInspector.HeapSnapshotView.prototype.resize):
+ (WebInspector.HeapSnapshotView.prototype.refresh):
+ (WebInspector.HeapSnapshotView.prototype.refreshShowAsPercents):
+ (WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags):
+ (WebInspector.HeapSnapshotView.prototype.searchCanceled):
+ (WebInspector.HeapSnapshotView.prototype.performSearch):
+ (WebInspector.HeapSnapshotView.prototype.jumpToFirstSearchResult.WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult.jumpToLastSearchResult.WebInspector.CPUProfileView.prototype.jumpToLastSearchResult.jumpToNextSearchResult.WebInspector.CPUProfileView.prototype.jumpToNextSearchResult.jumpToPreviousSearchResult.WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult.showingFirstSearchResult.WebInspector.CPUProfileView.prototype.showingFirstSearchResult.showingLastSearchResult.WebInspector.CPUProfileView.prototype.showingLastSearchResult._jumpToSearchResult.WebInspector.CPUProfileView.prototype._jumpToSearchResult.refreshVisibleData):
+ (WebInspector.HeapSnapshotView.prototype._changeBase.resetCompleted):
+ (WebInspector.HeapSnapshotView.prototype._changeBase):
+ (WebInspector.HeapSnapshotView.prototype._createSnapshotDataGridList):
+ (WebInspector.HeapSnapshotView.prototype._getProfiles):
+ (WebInspector.HeapSnapshotView.prototype._loadProfile.loadedCallback):
+ (WebInspector.HeapSnapshotView.prototype._loadProfile):
+ (WebInspector.HeapSnapshotView.prototype._mouseDownInDataGrid):
+ (WebInspector.HeapSnapshotView.prototype.get _isShowingAsPercent):
+ (WebInspector.HeapSnapshotView.prototype._percentClicked):
+ (WebInspector.HeapSnapshotView.prototype._prepareProfile.mergeRetainers):
+ (WebInspector.HeapSnapshotView.prototype._prepareProfile):
+ (WebInspector.HeapSnapshotView.prototype._resetDataGridList.profileLoaded):
+ (WebInspector.HeapSnapshotView.prototype._resetDataGridList):
+ (WebInspector.HeapSnapshotView.prototype._sortData):
+ (WebInspector.HeapSnapshotView.prototype._updateBaseOptions):
+ (WebInspector.HeapSnapshotView.prototype._updatePercentButton):
+ (WebInspector.HeapSnapshotView.prototype._updateSummaryGraph):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.LESS):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.LESS_OR_EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER_OR_EQUAL):
+ (WebInspector.HeapSnapshotView.SearchHelper.operations.GREATER):
+ (WebInspector.HeapSnapshotView.SearchHelper.parseOperationAndNumber):
+ (WebInspector.HeapSummaryCalculator):
+ (WebInspector.HeapSummaryCalculator.prototype.computeSummaryValues):
+ (WebInspector.HeapSummaryCalculator.prototype.formatValue):
+ (WebInspector.HeapSummaryCalculator.prototype.get showAsPercent):
+ (WebInspector.HeapSummaryCalculator.prototype.set showAsPercent):
+ (WebInspector.HeapSummaryCountCalculator):
+ (WebInspector.HeapSummaryCountCalculator.prototype._highFromLow):
+ (WebInspector.HeapSummaryCountCalculator.prototype._valueToString):
+ (WebInspector.HeapSummarySizeCalculator):
+ (WebInspector.HeapSummarySizeCalculator.prototype._highFromLow):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _hasRetainers):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get _parent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype._populate):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.signForDelta):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.showDeltaAsPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizePercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get countDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get sizeDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.get data):
+ (WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.createCell):
+ (WebInspector.HeapSnapshotDataGridNode):
+ (WebInspector.HeapSnapshotDataGridList):
+ (WebInspector.HeapSnapshotDataGridList.prototype.appendChild):
+ (WebInspector.HeapSnapshotDataGridList.prototype.insertChild):
+ (WebInspector.HeapSnapshotDataGridList.prototype.removeChildren):
+ (WebInspector.HeapSnapshotDataGridList.prototype.populateChildren):
+ (WebInspector.HeapSnapshotDataGridList.propertyComparator.comparator):
+ (WebInspector.HeapSnapshotDataGridList.propertyComparator):
+ (WebInspector.HeapSnapshotDataGridRetainerNode):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizePercent):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype.get sizeDeltaPercent):
+ (WebInspector.HeapSnapshotDataGridRetainerNode.prototype._calculateRetainers):
+ (WebInspector.HeapSnapshotProfileType):
+ (WebInspector.HeapSnapshotProfileType.prototype.get buttonTooltip):
+ (WebInspector.HeapSnapshotProfileType.prototype.get buttonStyle):
+ (WebInspector.HeapSnapshotProfileType.prototype.buttonClicked):
+ (WebInspector.HeapSnapshotProfileType.prototype.get welcomeMessage):
+ (WebInspector.HeapSnapshotProfileType.prototype.createSidebarTreeElementForProfile):
+ (WebInspector.HeapSnapshotProfileType.prototype.createView):
+ * inspector/front-end/ProfileView.js:
+ (WebInspector.CPUProfileView):
+ (WebInspector.CPUProfileType.prototype.createSidebarTreeElementForProfile):
+ * inspector/front-end/ProfilesPanel.js:
+ (WebInspector.ProfilesPanel.prototype.addProfileHeader):
+ (WebInspector.ProfilesPanel.prototype.removeProfileHeader):
+ (WebInspector.ProfilesPanel.prototype.getProfiles):
+ (WebInspector.ProfilesPanel.prototype.updateProfile):
+ (WebInspector.ProfileSidebarTreeElement):
+ (WebInspector.ProfileSidebarTreeElement.prototype.get mainTitle):
+ * inspector/front-end/WebKit.qrc:
+ * inspector/front-end/inspector.css:
+ (.heap-snapshot-sidebar-tree-item .icon):
+ (.heap-snapshot-sidebar-tree-item.small .icon):
+ (.heap-snapshot-view):
+ (.heap-snapshot-view.visible):
+ (.heap-snapshot-view .data-grid):
+ (.heap-snapshot-view .data-grid th.count-column):
+ (.heap-snapshot-view .data-grid td.count-column):
+ (.heap-snapshot-view .data-grid th.size-column):
+ (.heap-snapshot-view .data-grid td.size-column):
+ (.heap-snapshot-view .data-grid th.countDelta-column):
+ (.heap-snapshot-view .data-grid td.countDelta-column):
+ (.heap-snapshot-view .data-grid th.sizeDelta-column):
+ (.heap-snapshot-view .data-grid td.sizeDelta-column):
+ (#heap-snapshot-summary-container):
+ (.heap-snapshot-summary):
+ (.heap-snapshot-summary canvas.summary-graph):
+ (.heap-snapshot-summary-label):
+ * inspector/front-end/inspector.html:
+ * inspector/front-end/inspector.js:
+ (WebInspector._createPanels):
+
2010-08-25 David Hyatt <hyatt at apple.com>
Reviewed by Simon Fraser.
diff --git a/WebCore/English.lproj/localizedStrings.js b/WebCore/English.lproj/localizedStrings.js
index 38d2557..80d2425 100644
Binary files a/WebCore/English.lproj/localizedStrings.js and b/WebCore/English.lproj/localizedStrings.js differ
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 656697c..2707a1a 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -773,6 +773,7 @@ webcore_sources += \
WebCore/bindings/js/ScriptFunctionCall.h \
WebCore/bindings/js/ScriptGCEvent.cpp \
WebCore/bindings/js/ScriptGCEvent.h \
+ WebCore/bindings/js/ScriptHeapSnapshot.h \
WebCore/bindings/js/ScriptInstance.h \
WebCore/bindings/js/ScriptObject.cpp \
WebCore/bindings/js/ScriptObject.h \
diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi
index 0f15977..3f0c6de 100644
--- a/WebCore/WebCore.gypi
+++ b/WebCore/WebCore.gypi
@@ -854,6 +854,8 @@
'bindings/v8/ScriptFunctionCall.h',
'bindings/v8/ScriptGCEvent.cpp',
'bindings/v8/ScriptGCEvent.h',
+ 'bindings/v8/ScriptHeapSnapshot.cpp',
+ 'bindings/v8/ScriptHeapSnapshot.h',
'bindings/v8/ScriptInstance.cpp',
'bindings/v8/ScriptInstance.h',
'bindings/v8/ScriptObject.cpp',
@@ -4180,6 +4182,7 @@
'inspector/front-end/ExtensionServer.js',
'inspector/front-end/FontView.js',
'inspector/front-end/HAREntry.js',
+ 'inspector/front-end/HeapSnapshotView.js',
'inspector/front-end/HelpScreen.js',
'inspector/front-end/ImageView.js',
'inspector/front-end/InspectorFrontendHostStub.js',
diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro
index d1ff8b2..865cfbc 100644
--- a/WebCore/WebCore.pro
+++ b/WebCore/WebCore.pro
@@ -1156,6 +1156,7 @@ HEADERS += \
bindings/js/ScriptEventListener.h \
bindings/js/ScriptFunctionCall.h \
bindings/js/ScriptGCEvent.h \
+ bindings/js/ScriptHeapSnapshot.h \
bindings/js/ScriptObject.h \
bindings/js/ScriptProfile.h \
bindings/js/ScriptProfileNode.h \
diff --git a/WebCore/WebCore.vcproj/WebCore.vcproj b/WebCore/WebCore.vcproj/WebCore.vcproj
index c2807f2..dd2bbe6 100644
--- a/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -49236,6 +49236,10 @@
>
</File>
<File
+ RelativePath="..\bindings\js\ScriptHeapSnapshot.h"
+ >
+ </File>
+ <File
RelativePath="..\bindings\js\ScriptInstance.h"
>
</File>
@@ -52168,6 +52172,10 @@
>
</File>
<File
+ RelativePath="..\inspector\front-end\HeapSnapshotView.js"
+ >
+ </File>
+ <File
RelativePath="..\inspector\front-end\MetricsSidebarPane.js"
>
</File>
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index d7633e3..be26197 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -2755,6 +2755,7 @@
97EF7DFE107E55B700D7C49C /* ScriptControllerBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */; };
9F0D6B2E121BFEBA006C0288 /* InspectorProfilerAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */; };
9F0D6B2F121BFEBA006C0288 /* InspectorProfilerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */; };
+ 9F3B947E12241758005304E7 /* ScriptHeapSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */; };
9F6FC1961122E82A00E80196 /* ScriptDebugServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9F6FC1941122E82A00E80196 /* ScriptDebugServer.cpp */; };
9F6FC1971122E82A00E80196 /* ScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F6FC1951122E82A00E80196 /* ScriptDebugServer.h */; settings = {ATTRIBUTES = (Private, ); }; };
9F72304F11184B4100AD0126 /* ScriptProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F72304C11184B4100AD0126 /* ScriptProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -8623,6 +8624,7 @@
97EF7DFD107E55B700D7C49C /* ScriptControllerBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptControllerBase.cpp; sourceTree = "<group>"; };
9F0D6B2C121BFEBA006C0288 /* InspectorProfilerAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorProfilerAgent.cpp; sourceTree = "<group>"; };
9F0D6B2D121BFEBA006C0288 /* InspectorProfilerAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorProfilerAgent.h; sourceTree = "<group>"; };
+ 9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptHeapSnapshot.h; sourceTree = "<group>"; };
9F6FC1941122E82A00E80196 /* ScriptDebugServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptDebugServer.cpp; sourceTree = "<group>"; };
9F6FC1951122E82A00E80196 /* ScriptDebugServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptDebugServer.h; sourceTree = "<group>"; };
9F72304C11184B4100AD0126 /* ScriptProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptProfile.h; sourceTree = "<group>"; };
@@ -16123,6 +16125,7 @@
41002CCB0F66EDEF009E660D /* ScriptFunctionCall.h */,
4FD8D0F0119C718B002FA825 /* ScriptGCEvent.cpp */,
4FD8D0F1119C718B002FA825 /* ScriptGCEvent.h */,
+ 9F3B947D12241758005304E7 /* ScriptHeapSnapshot.h */,
934CC1160EDCAC7300A658F2 /* ScriptInstance.h */,
41F066E30F64BCF600A07EAC /* ScriptObject.cpp */,
41F066E20F64BCF600A07EAC /* ScriptObject.h */,
@@ -20372,6 +20375,7 @@
8947A82C12222C4700D95F2D /* JSMetadataCallback.h in Headers */,
8947A83C122234F400D95F2D /* Metadata.h in Headers */,
8947A83D122234F900D95F2D /* MetadataCallback.h in Headers */,
+ 9F3B947E12241758005304E7 /* ScriptHeapSnapshot.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/WebCore/bindings/js/ScriptHeapSnapshot.h b/WebCore/bindings/js/ScriptHeapSnapshot.h
new file mode 100644
index 0000000..c81c782
--- /dev/null
+++ b/WebCore/bindings/js/ScriptHeapSnapshot.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptHeapSnapshot_h
+#define ScriptHeapSnapshot_h
+
+#include "InspectorValues.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class ScriptHeapSnapshot : public RefCounted<ScriptHeapSnapshot> {
+public:
+ virtual ~ScriptHeapSnapshot() {}
+
+ String title() const { return ""; }
+ unsigned int uid() const { return 0; }
+
+ PassRefPtr<InspectorObject> buildInspectorObjectForHead() const { return InspectorObject::create(); }
+
+private:
+ ScriptHeapSnapshot() {}
+};
+
+} // namespace WebCore
+
+#endif // ScriptHeapSnapshot_h
diff --git a/WebCore/bindings/js/ScriptProfiler.h b/WebCore/bindings/js/ScriptProfiler.h
index 180c49f..05e7a25 100644
--- a/WebCore/bindings/js/ScriptProfiler.h
+++ b/WebCore/bindings/js/ScriptProfiler.h
@@ -28,6 +28,7 @@
#define ScriptProfiler_h
#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "ScriptHeapSnapshot.h"
#include "ScriptProfile.h"
#include "ScriptState.h"
@@ -39,8 +40,7 @@ class ScriptProfiler : public Noncopyable {
public:
static void start(ScriptState* state, const String& title);
static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
- static void takeHeapSnapshot() { }
- static long getProfilerLogLines(long, String*) { return 0; }
+ static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String&) { return 0; }
static bool isProfilerAlwaysEnabled();
};
diff --git a/WebCore/bindings/v8/ScriptHeapSnapshot.cpp b/WebCore/bindings/v8/ScriptHeapSnapshot.cpp
new file mode 100644
index 0000000..885d039
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptHeapSnapshot.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScriptHeapSnapshot.h"
+
+#include "InspectorValues.h"
+#include "V8Binding.h"
+#include <v8-profiler.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+String ScriptHeapSnapshot::title() const
+{
+ v8::HandleScope scope;
+ return toWebCoreString(m_snapshot->GetTitle());
+}
+
+unsigned int ScriptHeapSnapshot::uid() const
+{
+ return m_snapshot->GetUid();
+}
+
+static PassRefPtr<InspectorObject> buildInspectorObjectFor(const v8::HeapGraphNode* root)
+{
+ v8::HandleScope scope;
+ RefPtr<InspectorObject> result = InspectorObject::create();
+ RefPtr<InspectorObject> lowLevels = InspectorObject::create();
+ RefPtr<InspectorObject> entries = InspectorObject::create();
+ RefPtr<InspectorObject> children = InspectorObject::create();
+ for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphNode* node = root->GetChild(i)->GetToNode();
+ if (node->GetType() == v8::HeapGraphNode::kInternal) {
+ RefPtr<InspectorObject> lowLevel = InspectorObject::create();
+ lowLevel->setNumber("count", node->GetInstancesCount());
+ lowLevel->setNumber("size", node->GetSelfSize());
+ lowLevel->setString("type", toWebCoreString(node->GetName()));
+ lowLevels->setObject(toWebCoreString(node->GetName()), lowLevel);
+ } else if (node->GetInstancesCount()) {
+ RefPtr<InspectorObject> entry = InspectorObject::create();
+ entry->setString("constructorName", toWebCoreString(node->GetName()));
+ entry->setNumber("count", node->GetInstancesCount());
+ entry->setNumber("size", node->GetSelfSize());
+ entries->setObject(toWebCoreString(node->GetName()), entry);
+ } else {
+ RefPtr<InspectorObject> entry = InspectorObject::create();
+ entry->setString("constructorName", toWebCoreString(node->GetName()));
+ for (int j = 0, count = node->GetChildrenCount(); j < count; ++j) {
+ const v8::HeapGraphEdge* v8Edge = node->GetChild(j);
+ const v8::HeapGraphNode* v8Child = v8Edge->GetToNode();
+ RefPtr<InspectorObject> child = InspectorObject::create();
+ child->setString("constructorName", toWebCoreString(v8Child->GetName()));
+ child->setNumber("count", v8Edge->GetName()->ToInteger()->Value());
+ entry->setObject(String::number(reinterpret_cast<unsigned long long>(v8Child)), child);
+ }
+ children->setObject(String::number(reinterpret_cast<unsigned long long>(node)), entry);
+ }
+ }
+ result->setObject("lowlevels", lowLevels);
+ result->setObject("entries", entries);
+ result->setObject("children", children);
+ return result.release();
+}
+
+PassRefPtr<InspectorObject> ScriptHeapSnapshot::buildInspectorObjectForHead() const
+{
+ return buildInspectorObjectFor(m_snapshot->GetRoot());
+}
+
+} // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptHeapSnapshot.h b/WebCore/bindings/v8/ScriptHeapSnapshot.h
new file mode 100644
index 0000000..794a5a9
--- /dev/null
+++ b/WebCore/bindings/v8/ScriptHeapSnapshot.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ScriptHeapSnapshot_h
+#define ScriptHeapSnapshot_h
+
+#include "PlatformString.h"
+
+namespace v8 {
+class HeapSnapshot;
+}
+
+namespace WebCore {
+
+class InspectorObject;
+
+class ScriptHeapSnapshot : public RefCounted<ScriptHeapSnapshot> {
+public:
+ static PassRefPtr<ScriptHeapSnapshot> create(const v8::HeapSnapshot* snapshot)
+ {
+ return adoptRef(new ScriptHeapSnapshot(snapshot));
+ }
+ virtual ~ScriptHeapSnapshot() {}
+
+ String title() const;
+ unsigned int uid() const;
+
+ PassRefPtr<InspectorObject> buildInspectorObjectForHead() const;
+
+private:
+ ScriptHeapSnapshot(const v8::HeapSnapshot* snapshot)
+ : m_snapshot(snapshot)
+ {}
+
+ const v8::HeapSnapshot* m_snapshot;
+};
+
+} // namespace WebCore
+
+#endif // ScriptHeapSnapshot_h
diff --git a/WebCore/bindings/v8/ScriptProfile.cpp b/WebCore/bindings/v8/ScriptProfile.cpp
index 85dbadb..c5a6dbf 100644
--- a/WebCore/bindings/v8/ScriptProfile.cpp
+++ b/WebCore/bindings/v8/ScriptProfile.cpp
@@ -75,7 +75,7 @@ static PassRefPtr<InspectorObject> buildInspectorObjectFor(const v8::CpuProfileN
children->pushObject(buildInspectorObjectFor(child));
}
result->setArray("children", children);
- return result;
+ return result.release();
}
PassRefPtr<InspectorObject> ScriptProfile::buildInspectorObjectForHead() const
diff --git a/WebCore/bindings/v8/ScriptProfiler.cpp b/WebCore/bindings/v8/ScriptProfiler.cpp
index 0de4a24..ab7cfa7 100644
--- a/WebCore/bindings/v8/ScriptProfiler.cpp
+++ b/WebCore/bindings/v8/ScriptProfiler.cpp
@@ -29,8 +29,9 @@
*/
#include "config.h"
-
#include "ScriptProfiler.h"
+
+#include "InspectorValues.h"
#include "ScriptString.h"
#include <v8-profiler.h>
@@ -52,21 +53,11 @@ PassRefPtr<ScriptProfile> ScriptProfiler::stop(ScriptState* state, const String&
return profile ? ScriptProfile::create(profile) : 0;
}
-void ScriptProfiler::takeHeapSnapshot()
-{
- v8::V8::ResumeProfilerEx(v8::PROFILER_MODULE_HEAP_SNAPSHOT
- | v8::PROFILER_MODULE_HEAP_STATS
- | v8::PROFILER_MODULE_JS_CONSTRUCTORS);
-}
-
-long ScriptProfiler::getProfilerLogLines(long position, String* data)
+PassRefPtr<ScriptHeapSnapshot> ScriptProfiler::takeHeapSnapshot(const String& title)
{
- static char buffer[65536];
- const int readSize = v8::V8::GetLogLines(position, buffer, sizeof(buffer) - 1);
- buffer[readSize] = '\0';
- position += readSize;
- *data = buffer;
- return position;
+ v8::HandleScope hs;
+ const v8::HeapSnapshot* snapshot = v8::HeapProfiler::TakeSnapshot(v8String(title), v8::HeapSnapshot::kAggregated);
+ return snapshot ? ScriptHeapSnapshot::create(snapshot) : 0;
}
bool ScriptProfiler::isProfilerAlwaysEnabled()
diff --git a/WebCore/bindings/v8/ScriptProfiler.h b/WebCore/bindings/v8/ScriptProfiler.h
index b1ab3b1..b75a054 100644
--- a/WebCore/bindings/v8/ScriptProfiler.h
+++ b/WebCore/bindings/v8/ScriptProfiler.h
@@ -32,6 +32,7 @@
#define ScriptProfiler_h
#include "PlatformString.h"
+#include "ScriptHeapSnapshot.h"
#include "ScriptProfile.h"
#include "ScriptState.h"
@@ -39,12 +40,13 @@
namespace WebCore {
+class InspectorObject;
+
class ScriptProfiler : public Noncopyable {
public:
static void start(ScriptState* state, const String& title);
static PassRefPtr<ScriptProfile> stop(ScriptState* state, const String& title);
- static void takeHeapSnapshot();
- static long getProfilerLogLines(long position, String* data);
+ static PassRefPtr<ScriptHeapSnapshot> takeHeapSnapshot(const String& title);
static bool isProfilerAlwaysEnabled();
};
diff --git a/WebCore/inspector/Inspector.idl b/WebCore/inspector/Inspector.idl
index 7f39f8d..ff1c2af 100644
--- a/WebCore/inspector/Inspector.idl
+++ b/WebCore/inspector/Inspector.idl
@@ -150,13 +150,12 @@ module core {
[handler=Profiler] void stopProfiling();
[handler=Profiler] void getProfileHeaders(out Array headers);
- [handler=Profiler] void getProfile(in unsigned long uid, out Object profile);
+ [handler=Profiler] void getProfile(in String type, in unsigned long uid, out Object profile);
- [handler=Profiler] void removeProfile(in unsigned long uid);
+ [handler=Profiler] void removeProfile(in String type, in unsigned long uid);
[handler=Profiler] void clearProfiles();
- [handler=Backend] void takeHeapSnapshot();
- [handler=Backend] void getProfilerLogLines(in long inPosition, out long outPosition, out String log);
+ [handler=Profiler] void takeHeapSnapshot();
#endif
[handler=Backend] void setInjectedScriptSource(in String scriptSource);
[handler=Backend] void dispatchOnInjectedScript(in long injectedScriptId, in String methodName, in String arguments, out Value result, out boolean isException);
diff --git a/WebCore/inspector/InspectorBackend.cpp b/WebCore/inspector/InspectorBackend.cpp
index 99f40a9..791e3a6 100644
--- a/WebCore/inspector/InspectorBackend.cpp
+++ b/WebCore/inspector/InspectorBackend.cpp
@@ -68,17 +68,6 @@ void InspectorBackend::enableDebugger(bool always)
m_inspectorController->enableDebuggerFromFrontend(always);
}
-void InspectorBackend::takeHeapSnapshot()
-{
- ScriptProfiler::takeHeapSnapshot();
-}
-
-void InspectorBackend::getProfilerLogLines(long position, long* outPosition, String* data)
-{
- // FIXME: we should make inspector dispatcher pluggable, so that embedders could contribute APIs instead of polluting the core one
- // https://bugs.webkit.org/show_bug.cgi?id=43357
- *outPosition = ScriptProfiler::getProfilerLogLines(position, data);
-}
#endif
void InspectorBackend::setInjectedScriptSource(const String& source)
diff --git a/WebCore/inspector/InspectorBackend.h b/WebCore/inspector/InspectorBackend.h
index 23b31a3..1fcec96 100644
--- a/WebCore/inspector/InspectorBackend.h
+++ b/WebCore/inspector/InspectorBackend.h
@@ -60,8 +60,6 @@ public:
#if ENABLE(JAVASCRIPT_DEBUGGER)
void enableDebugger(bool always);
- void takeHeapSnapshot();
- void getProfilerLogLines(long position, long* outPosition, String* data);
#endif
void setInjectedScriptSource(const String& source);
diff --git a/WebCore/inspector/InspectorProfilerAgent.cpp b/WebCore/inspector/InspectorProfilerAgent.cpp
index a73469a..9161c3b 100644
--- a/WebCore/inspector/InspectorProfilerAgent.cpp
+++ b/WebCore/inspector/InspectorProfilerAgent.cpp
@@ -39,6 +39,7 @@
#include "KURL.h"
#include "Page.h"
#include "ScriptDebugServer.h"
+#include "ScriptHeapSnapshot.h"
#include "ScriptProfile.h"
#include "ScriptProfiler.h"
#include <wtf/OwnPtr.h>
@@ -51,6 +52,7 @@ namespace WebCore {
static const char* const UserInitiatedProfileName = "org.webkit.profiles.user-initiated";
static const char* const CPUProfileType = "CPU";
+static const char* const HeapProfileType = "HEAP";
PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InspectorController* inspectorController)
{
@@ -65,6 +67,7 @@ InspectorProfilerAgent::InspectorProfilerAgent(InspectorController* inspectorCon
, m_recordingUserInitiatedProfile(false)
, m_currentUserInitiatedProfileNumber(-1)
, m_nextUserInitiatedProfileNumber(1)
+ , m_nextUserInitiatedHeapSnapshotNumber(1)
{
}
@@ -104,6 +107,15 @@ PassRefPtr<InspectorObject> InspectorProfilerAgent::createProfileHeader(const Sc
return header;
}
+PassRefPtr<InspectorObject> InspectorProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot)
+{
+ RefPtr<InspectorObject> header = InspectorObject::create();
+ header->setString("title", snapshot.title());
+ header->setNumber("uid", snapshot.uid());
+ header->setString("typeId", String(HeapProfileType));
+ return header;
+}
+
void InspectorProfilerAgent::disable()
{
if (!m_enabled)
@@ -138,28 +150,46 @@ void InspectorProfilerAgent::getProfileHeaders(RefPtr<InspectorArray>* headers)
ProfilesMap::iterator profilesEnd = m_profiles.end();
for (ProfilesMap::iterator it = m_profiles.begin(); it != profilesEnd; ++it)
(*headers)->pushObject(createProfileHeader(*it->second));
-}
-
-void InspectorProfilerAgent::getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject)
-{
- ProfilesMap::iterator it = m_profiles.find(uid);
- if (it != m_profiles.end()) {
- *profileObject = createProfileHeader(*it->second);
- (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead());
+ HeapSnapshotsMap::iterator snapshotsEnd = m_snapshots.end();
+ for (HeapSnapshotsMap::iterator it = m_snapshots.begin(); it != snapshotsEnd; ++it)
+ (*headers)->pushObject(createSnapshotHeader(*it->second));
+}
+
+void InspectorProfilerAgent::getProfile(const String& type, unsigned uid, RefPtr<InspectorObject>* profileObject)
+{
+ if (type == CPUProfileType) {
+ ProfilesMap::iterator it = m_profiles.find(uid);
+ if (it != m_profiles.end()) {
+ *profileObject = createProfileHeader(*it->second);
+ (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead());
+ }
+ } else if (type == HeapProfileType) {
+ HeapSnapshotsMap::iterator it = m_snapshots.find(uid);
+ if (it != m_snapshots.end()) {
+ *profileObject = createSnapshotHeader(*it->second);
+ (*profileObject)->setObject("head", it->second->buildInspectorObjectForHead());
+ }
}
}
-void InspectorProfilerAgent::removeProfile(unsigned uid)
+void InspectorProfilerAgent::removeProfile(const String& type, unsigned uid)
{
- if (m_profiles.contains(uid))
- m_profiles.remove(uid);
+ if (type == CPUProfileType) {
+ if (m_profiles.contains(uid))
+ m_profiles.remove(uid);
+ } else if (type == HeapProfileType) {
+ if (m_snapshots.contains(uid))
+ m_snapshots.remove(uid);
+ }
}
void InspectorProfilerAgent::resetState()
{
m_profiles.clear();
+ m_snapshots.clear();
m_currentUserInitiatedProfileNumber = 1;
m_nextUserInitiatedProfileNumber = 1;
+ m_nextUserInitiatedHeapSnapshotNumber = 1;
if (m_frontend)
m_frontend->resetProfilesPanel();
}
@@ -199,6 +229,17 @@ void InspectorProfilerAgent::stopUserInitiatedProfiling()
toggleRecordButton(false);
}
+void InspectorProfilerAgent::takeHeapSnapshot()
+{
+ String title = String::format("%s.%d", UserInitiatedProfileName, m_nextUserInitiatedHeapSnapshotNumber++);
+ RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title);
+ if (snapshot) {
+ m_snapshots.add(snapshot->uid(), snapshot);
+ if (m_frontend)
+ m_frontend->addProfileHeader(createSnapshotHeader(*snapshot));
+ }
+}
+
void InspectorProfilerAgent::toggleRecordButton(bool isProfiling)
{
if (m_frontend)
diff --git a/WebCore/inspector/InspectorProfilerAgent.h b/WebCore/inspector/InspectorProfilerAgent.h
index 9593eba..421efb0 100644
--- a/WebCore/inspector/InspectorProfilerAgent.h
+++ b/WebCore/inspector/InspectorProfilerAgent.h
@@ -44,6 +44,7 @@ class InspectorArray;
class InspectorController;
class InspectorFrontend;
class InspectorObject;
+class ScriptHeapSnapshot;
class ScriptProfile;
class InspectorProfilerAgent : public Noncopyable {
@@ -60,22 +61,25 @@ public:
bool enabled() { return m_enabled; }
String getCurrentUserInitiatedProfileName(bool incrementProfileNumber = false);
void getProfileHeaders(RefPtr<InspectorArray>* headers);
- void getProfile(unsigned uid, RefPtr<InspectorObject>* profileObject);
+ void getProfile(const String& type, unsigned uid, RefPtr<InspectorObject>* profileObject);
bool isRecordingUserInitiatedProfile() { return m_recordingUserInitiatedProfile; }
- void removeProfile(unsigned uid);
+ void removeProfile(const String& type, unsigned uid);
void resetState();
void setFrontend(InspectorFrontend* frontend) { m_frontend = frontend; }
void startProfiling() { startUserInitiatedProfiling(); }
void startUserInitiatedProfiling();
void stopProfiling() { stopUserInitiatedProfiling(); }
void stopUserInitiatedProfiling();
+ void takeHeapSnapshot();
void toggleRecordButton(bool isProfiling);
private:
typedef HashMap<unsigned int, RefPtr<ScriptProfile> > ProfilesMap;
+ typedef HashMap<unsigned int, RefPtr<ScriptHeapSnapshot> > HeapSnapshotsMap;
InspectorProfilerAgent(InspectorController*);
PassRefPtr<InspectorObject> createProfileHeader(const ScriptProfile& profile);
+ PassRefPtr<InspectorObject> createSnapshotHeader(const ScriptHeapSnapshot& snapshot);
InspectorController* m_inspectorController;
InspectorFrontend* m_frontend;
@@ -83,7 +87,9 @@ private:
bool m_recordingUserInitiatedProfile;
int m_currentUserInitiatedProfileNumber;
unsigned m_nextUserInitiatedProfileNumber;
+ unsigned m_nextUserInitiatedHeapSnapshotNumber;
ProfilesMap m_profiles;
+ HeapSnapshotsMap m_snapshots;
};
} // namespace WebCore
diff --git a/WebCore/inspector/front-end/HeapSnapshotView.js b/WebCore/inspector/front-end/HeapSnapshotView.js
new file mode 100644
index 0000000..6bcc0ff
--- /dev/null
+++ b/WebCore/inspector/front-end/HeapSnapshotView.js
@@ -0,0 +1,1008 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.HeapSnapshotView = function(parent, profile)
+{
+ WebInspector.View.call(this);
+
+ this.element.addStyleClass("heap-snapshot-view");
+
+ this.parent = parent;
+ this.parent.addEventListener("profile added", this._updateBaseOptions, this);
+
+ this.showCountAsPercent = false;
+ this.showSizeAsPercent = false;
+ this.showCountDeltaAsPercent = false;
+ this.showSizeDeltaAsPercent = false;
+
+ this.categories = {
+ code: new WebInspector.ResourceCategory("code", WebInspector.UIString("Code"), "rgb(255,121,0)"),
+ data: new WebInspector.ResourceCategory("data", WebInspector.UIString("Objects"), "rgb(47,102,236)")
+ };
+
+ var summaryContainer = document.createElement("div");
+ summaryContainer.id = "heap-snapshot-summary-container";
+
+ this.countsSummaryBar = new WebInspector.SummaryBar(this.categories);
+ this.countsSummaryBar.element.className = "heap-snapshot-summary";
+ this.countsSummaryBar.calculator = new WebInspector.HeapSummaryCountCalculator();
+ var countsLabel = document.createElement("div");
+ countsLabel.className = "heap-snapshot-summary-label";
+ countsLabel.textContent = WebInspector.UIString("Count");
+ this.countsSummaryBar.element.appendChild(countsLabel);
+ summaryContainer.appendChild(this.countsSummaryBar.element);
+
+ this.sizesSummaryBar = new WebInspector.SummaryBar(this.categories);
+ this.sizesSummaryBar.element.className = "heap-snapshot-summary";
+ this.sizesSummaryBar.calculator = new WebInspector.HeapSummarySizeCalculator();
+ var sizesLabel = document.createElement("label");
+ sizesLabel.className = "heap-snapshot-summary-label";
+ sizesLabel.textContent = WebInspector.UIString("Size");
+ this.sizesSummaryBar.element.appendChild(sizesLabel);
+ summaryContainer.appendChild(this.sizesSummaryBar.element);
+
+ this.element.appendChild(summaryContainer);
+
+ var columns = {
+ cons: { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true },
+ count: { title: WebInspector.UIString("Count"), width: "54px", sortable: true },
+ size: { title: WebInspector.UIString("Size"), width: "72px", sort: "descending", sortable: true },
+ // \xb1 is a "plus-minus" sign.
+ countDelta: { title: WebInspector.UIString("\xb1 Count"), width: "72px", sortable: true },
+ sizeDelta: { title: WebInspector.UIString("\xb1 Size"), width: "72px", sortable: true }
+ };
+
+ this.dataGrid = new WebInspector.DataGrid(columns);
+ this.dataGrid.addEventListener("sorting changed", this._sortData, this);
+ this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
+ this.element.appendChild(this.dataGrid.element);
+
+ this.profile = profile;
+
+ this.baseSelectElement = document.createElement("select");
+ this.baseSelectElement.className = "status-bar-item";
+ this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false);
+ this._updateBaseOptions();
+
+ this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item");
+ this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);
+
+ this._loadProfile(this.profile, profileCallback.bind(this));
+
+ function profileCallback(profile)
+ {
+ var list = this._getProfiles();
+ var profileIndex;
+ for (var i = 0; i < list.length; ++i)
+ if (list[i].uid === profile.uid) {
+ profileIndex = i;
+ break;
+ }
+ if (profileIndex > 0)
+ this.baseSelectElement.selectedIndex = profileIndex - 1;
+ else
+ this.baseSelectElement.selectedIndex = profileIndex;
+ this._resetDataGridList(resetCompleted.bind(this));
+ }
+
+ function resetCompleted()
+ {
+ this.refresh();
+ this._updatePercentButton();
+ }
+}
+
+WebInspector.HeapSnapshotView.prototype = {
+ get statusBarItems()
+ {
+ return [this.baseSelectElement, this.percentButton.element];
+ },
+
+ get profile()
+ {
+ return this._profile;
+ },
+
+ set profile(profile)
+ {
+ this._profile = profile;
+ },
+
+ show: function(parentElement)
+ {
+ WebInspector.View.prototype.show.call(this, parentElement);
+ this.dataGrid.updateWidths();
+ },
+
+ hide: function()
+ {
+ WebInspector.View.prototype.hide.call(this);
+ this._currentSearchResultIndex = -1;
+ },
+
+ resize: function()
+ {
+ if (this.dataGrid)
+ this.dataGrid.updateWidths();
+ },
+
+ refresh: function()
+ {
+ this.dataGrid.removeChildren();
+
+ var children = this.snapshotDataGridList.children;
+ var count = children.length;
+ for (var index = 0; index < count; ++index)
+ this.dataGrid.appendChild(children[index]);
+
+ this._updateSummaryGraph();
+ },
+
+ refreshShowAsPercents: function()
+ {
+ this._updatePercentButton();
+ this.refreshVisibleData();
+ },
+
+ _deleteSearchMatchedFlags: function(node)
+ {
+ delete node._searchMatchedConsColumn;
+ delete node._searchMatchedCountColumn;
+ delete node._searchMatchedSizeColumn;
+ delete node._searchMatchedCountDeltaColumn;
+ delete node._searchMatchedSizeDeltaColumn;
+ },
+
+ searchCanceled: function()
+ {
+ if (this._searchResults) {
+ for (var i = 0; i < this._searchResults.length; ++i) {
+ var profileNode = this._searchResults[i].profileNode;
+ this._deleteSearchMatchedFlags(profileNode);
+ profileNode.refresh();
+ }
+ }
+
+ delete this._searchFinishedCallback;
+ this._currentSearchResultIndex = -1;
+ this._searchResults = [];
+ },
+
+ performSearch: function(query, finishedCallback)
+ {
+ // Call searchCanceled since it will reset everything we need before doing a new search.
+ this.searchCanceled();
+
+ query = query.trim();
+
+ if (!query.length)
+ return;
+
+ this._searchFinishedCallback = finishedCallback;
+
+ var helper = WebInspector.HeapSnapshotView.SearchHelper;
+
+ var operationAndNumber = helper.parseOperationAndNumber(query);
+ var operation = operationAndNumber[0];
+ var queryNumber = operationAndNumber[1];
+
+ var percentUnits = helper.percents.test(query);
+ var megaBytesUnits = helper.megaBytes.test(query);
+ var kiloBytesUnits = helper.kiloBytes.test(query);
+ var bytesUnits = helper.bytes.test(query);
+
+ var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber));
+
+ function matchesQuery(heapSnapshotDataGridNode)
+ {
+ WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode);
+
+ if (percentUnits) {
+ heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber);
+ } else if (megaBytesUnits || kiloBytesUnits || bytesUnits) {
+ heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes);
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes);
+ } else {
+ heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber);
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber);
+ }
+
+ if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true))
+ heapSnapshotDataGridNode._searchMatchedConsColumn = true;
+
+ if (heapSnapshotDataGridNode._searchMatchedConsColumn ||
+ heapSnapshotDataGridNode._searchMatchedCountColumn ||
+ heapSnapshotDataGridNode._searchMatchedSizeColumn ||
+ heapSnapshotDataGridNode._searchMatchedCountDeltaColumn ||
+ heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) {
+ heapSnapshotDataGridNode.refresh();
+ return true;
+ }
+
+ return false;
+ }
+
+ var current = this.snapshotDataGridList.children[0];
+ var depth = 0;
+ var info = {};
+
+ // The second and subsequent levels of heap snapshot nodes represent retainers,
+ // so recursive expansion will be infinite, since a graph is being traversed.
+ // So default to a recursion cap of 2 levels.
+ const maxDepth = 2;
+
+ while (current) {
+ if (matchesQuery(current))
+ this._searchResults.push({ profileNode: current });
+ current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
+ depth += info.depthChange;
+ }
+
+ finishedCallback(this, this._searchResults.length);
+ },
+
+ // FIXME: move these methods to a superclass, inherit both views from it.
+ jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult,
+ jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult,
+ jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult,
+ jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult,
+ showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult,
+ showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult,
+ _jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult,
+
+ refreshVisibleData: function()
+ {
+ var child = this.dataGrid.children[0];
+ while (child) {
+ child.refresh();
+ child = child.traverseNextNode(false, null, true);
+ }
+ this._updateSummaryGraph();
+ },
+
+ _changeBase: function()
+ {
+ if (this.baseSnapshot.uid === this._getProfiles()[this.baseSelectElement.selectedIndex].uid)
+ return;
+
+ this._resetDataGridList(resetCompleted.bind(this));
+
+ function resetCompleted() {
+ this.refresh();
+
+ if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
+ return;
+
+ // The current search needs to be performed again. First negate out previous match
+ // count by calling the search finished callback with a negative number of matches.
+ // Then perform the search again with the same query and callback.
+ this._searchFinishedCallback(this, -this._searchResults.length);
+ this.performSearch(this.currentQuery, this._searchFinishedCallback);
+ }
+ },
+
+ _createSnapshotDataGridList: function()
+ {
+ if (this._snapshotDataGridList)
+ delete this._snapshotDataGridList;
+
+ this._snapshotDataGridList = new WebInspector.HeapSnapshotDataGridList(this, this.baseSnapshot.entries, this.profile.entries);
+ return this._snapshotDataGridList;
+ },
+
+ _getProfiles: function()
+ {
+ return WebInspector.panels.profiles.getProfiles(WebInspector.HeapSnapshotProfileType.TypeId);
+ },
+
+ _loadProfile: function(profile, callback)
+ {
+ if (profile._loaded) {
+ callback(profile);
+ return;
+ }
+
+ InspectorBackend.getProfile(profile.typeId, profile.uid, loadedCallback.bind(this));
+
+ function loadedCallback(loadedSnapshot) {
+ profile.children = loadedSnapshot.head.children;
+ profile.entries = loadedSnapshot.head.entries;
+ profile.lowlevels = loadedSnapshot.head.lowlevels;
+ this._prepareProfile(profile);
+ profile._loaded = true;
+ this.parent.updateProfile(profile);
+ callback(profile);
+ }
+ },
+
+ _mouseDownInDataGrid: function(event)
+ {
+ if (event.detail < 2)
+ return;
+
+ var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
+ if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("size-column") && !cell.hasStyleClass("countDelta-column") && !cell.hasStyleClass("sizeDelta-column")))
+ return;
+
+ if (cell.hasStyleClass("count-column"))
+ this.showCountAsPercent = !this.showCountAsPercent;
+ else if (cell.hasStyleClass("size-column"))
+ this.showSizeAsPercent = !this.showSizeAsPercent;
+ else if (cell.hasStyleClass("countDelta-column"))
+ this.showCountDeltaAsPercent = !this.showCountDeltaAsPercent;
+ else if (cell.hasStyleClass("sizeDelta-column"))
+ this.showSizeDeltaAsPercent = !this.showSizeDeltaAsPercent;
+
+ this.refreshShowAsPercents();
+
+ event.preventDefault();
+ event.stopPropagation();
+ },
+
+ get _isShowingAsPercent()
+ {
+ return this.showCountAsPercent && this.showSizeAsPercent && this.showCountDeltaAsPercent && this.showSizeDeltaAsPercent;
+ },
+
+ _percentClicked: function(event)
+ {
+ var currentState = this._isShowingAsPercent;
+ this.showCountAsPercent = !currentState;
+ this.showSizeAsPercent = !currentState;
+ this.showCountDeltaAsPercent = !currentState;
+ this.showSizeDeltaAsPercent = !currentState;
+ this.refreshShowAsPercents();
+ },
+
+ _prepareProfile: function(profile)
+ {
+ for (var profileEntry in profile.entries)
+ profile.entries[profileEntry].retainers = {};
+ profile.clusters = {};
+
+ for (var addr in profile.children) {
+ var retainer = profile.children[addr];
+ var retainerId = retainer.constructorName + ':' + addr;
+ for (var childAddr in retainer) {
+ if (childAddr === 'constructorName') continue;
+ var item = retainer[childAddr];
+ var itemId = item.constructorName + ':' + childAddr;
+ if ((item.constructorName === 'Object' || item.constructorName === 'Array')) {
+ if (!(itemId in profile.clusters))
+ profile.clusters[itemId] = { constructorName: itemId, retainers: {} };
+ mergeRetainers(profile.clusters[itemId], item);
+ }
+ mergeRetainers(profile.entries[item.constructorName], item);
+ }
+ }
+
+ function mergeRetainers(entry, item)
+ {
+ if (!(retainer.constructorName in entry.retainers))
+ entry.retainers[retainer.constructorName] = { constructorName: retainer.constructorName, count: 0, clusters: {} };
+ var retainerEntry = entry.retainers[retainer.constructorName];
+ retainerEntry.count += item.count;
+ if (retainer.constructorName === 'Object' || retainer.constructorName === 'Array')
+ retainerEntry.clusters[retainerId] = true;
+ }
+ },
+
+ _resetDataGridList: function(callback)
+ {
+ this._loadProfile(this._getProfiles()[this.baseSelectElement.selectedIndex], profileLoaded.bind(this));
+
+ function profileLoaded(profile)
+ {
+ this.baseSnapshot = profile;
+ var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false);
+ if (this.snapshotDataGridList)
+ lastComparator = this.snapshotDataGridList.lastComparator;
+ this.snapshotDataGridList = this._createSnapshotDataGridList();
+ this.snapshotDataGridList.sort(lastComparator, true);
+ callback();
+ }
+ },
+
+ _sortData: function()
+ {
+ var sortAscending = this.dataGrid.sortOrder === "ascending";
+ var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
+ var sortProperty = {
+ cons: ["cons", null],
+ count: ["count", null],
+ size: ["size", "count"],
+ countDelta: this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
+ sizeDelta: this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"]
+ }[sortColumnIdentifier];
+
+ this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending));
+
+ this.refresh();
+ },
+
+ _updateBaseOptions: function()
+ {
+ var list = this._getProfiles();
+ // We're assuming that snapshots can only be added.
+ if (this.baseSelectElement.length === list.length)
+ return;
+
+ for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) {
+ var baseOption = document.createElement("option");
+ var title = list[i].title;
+ if (!title.indexOf(UserInitiatedProfileName))
+ title = WebInspector.UIString("Snapshot %d", title.substring(UserInitiatedProfileName.length + 1));
+ baseOption.label = WebInspector.UIString("Compared to %s", title);
+ this.baseSelectElement.appendChild(baseOption);
+ }
+ },
+
+ _updatePercentButton: function()
+ {
+ if (this._isShowingAsPercent) {
+ this.percentButton.title = WebInspector.UIString("Show absolute counts and sizes.");
+ this.percentButton.toggled = true;
+ } else {
+ this.percentButton.title = WebInspector.UIString("Show counts and sizes as percentages.");
+ this.percentButton.toggled = false;
+ }
+ },
+
+ _updateSummaryGraph: function()
+ {
+ this.countsSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
+ this.countsSummaryBar.update(this.profile.lowlevels);
+
+ this.sizesSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
+ this.sizesSummaryBar.update(this.profile.lowlevels);
+ }
+};
+
+WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype;
+
+WebInspector.HeapSnapshotView.SearchHelper = {
+ // In comparators, we assume that a value from a node is passed as the first parameter.
+ operations: {
+ LESS: function (a, b) { return a !== null && a < b; },
+ LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; },
+ EQUAL: function (a, b) { return a !== null && a === b; },
+ GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; },
+ GREATER: function (a, b) { return a !== null && a > b; }
+ },
+
+ operationParsers: {
+ LESS: /^<(\d+)/,
+ LESS_OR_EQUAL: /^<=(\d+)/,
+ GREATER_OR_EQUAL: /^>=(\d+)/,
+ GREATER: /^>(\d+)/
+ },
+
+ parseOperationAndNumber: function(query)
+ {
+ var operations = WebInspector.HeapSnapshotView.SearchHelper.operations;
+ var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers;
+ for (var operation in parsers) {
+ var match = query.match(parsers[operation]);
+ if (match !== null)
+ return [operations[operation], parseFloat(match[1])];
+ }
+ return [operations.EQUAL, parseFloat(query)];
+ },
+
+ percents: /%$/,
+
+ megaBytes: /MB$/i,
+
+ kiloBytes: /KB$/i,
+
+ bytes: /B$/i
+}
+
+WebInspector.HeapSummaryCalculator = function(lowLevelField)
+{
+ this.total = 1;
+ this.lowLevelField = lowLevelField;
+}
+
+WebInspector.HeapSummaryCalculator.prototype = {
+ computeSummaryValues: function(lowLevels)
+ {
+ var highLevels = { data: 0, code: 0 };
+ this.total = 0;
+ for (var item in lowLevels) {
+ var highItem = this._highFromLow(item);
+ if (highItem) {
+ var value = lowLevels[item][this.lowLevelField];
+ highLevels[highItem] += value;
+ this.total += value;
+ }
+ }
+ var result = { categoryValues: highLevels };
+ if (!this.showAsPercent)
+ result.total = this.total;
+ return result;
+ },
+
+ formatValue: function(value)
+ {
+ if (this.showAsPercent)
+ return WebInspector.UIString("%.2f%%", value / this.total * 100.0);
+ else
+ return this._valueToString(value);
+ },
+
+ get showAsPercent()
+ {
+ return this._showAsPercent;
+ },
+
+ set showAsPercent(x)
+ {
+ this._showAsPercent = x;
+ }
+}
+
+WebInspector.HeapSummaryCountCalculator = function()
+{
+ WebInspector.HeapSummaryCalculator.call(this, "count");
+}
+
+WebInspector.HeapSummaryCountCalculator.prototype = {
+ _highFromLow: function(type)
+ {
+ if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
+ if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data";
+ return null;
+ },
+
+ _valueToString: function(value)
+ {
+ return value.toString();
+ }
+}
+
+WebInspector.HeapSummaryCountCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;
+
+WebInspector.HeapSummarySizeCalculator = function()
+{
+ WebInspector.HeapSummaryCalculator.call(this, "size");
+}
+
+WebInspector.HeapSummarySizeCalculator.prototype = {
+ _highFromLow: function(type)
+ {
+ if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE")
+ return "code";
+ if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/))
+ return "data";
+ return null;
+ },
+
+ _valueToString: Number.bytesToString
+}
+
+WebInspector.HeapSummarySizeCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;
+
+WebInspector.HeapSnapshotDataGridNodeWithRetainers = function(owningTree)
+{
+ this.tree = owningTree;
+
+ WebInspector.DataGridNode.call(this, null, this._hasRetainers);
+
+ this.addEventListener("populate", this._populate, this);
+};
+
+WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
+ isEmptySet: function(set)
+ {
+ for (var x in set)
+ return false;
+ return true;
+ },
+
+ get _hasRetainers()
+ {
+ return !this.isEmptySet(this.retainers);
+ },
+
+ get _parent()
+ {
+ // For top-level nodes, return owning tree as a parent, not data grid.
+ return this.parent !== this.dataGrid ? this.parent : this.tree;
+ },
+
+ _populate: function(event)
+ {
+ function appendDiffEntry(baseItem, snapshotItem)
+ {
+ this.appendChild(new WebInspector.HeapSnapshotDataGridRetainerNode(this.snapshotView, baseItem, snapshotItem, this.tree));
+ }
+
+ this.produceDiff(this.baseRetainers, this.retainers, appendDiffEntry.bind(this));
+
+ if (this._parent) {
+ var currentComparator = this._parent.lastComparator;
+ if (currentComparator)
+ this.sort(currentComparator, true);
+ }
+
+ this.removeEventListener("populate", this._populate, this);
+ },
+
+ produceDiff: function(baseEntries, currentEntries, callback)
+ {
+ for (var item in currentEntries)
+ callback(baseEntries[item], currentEntries[item]);
+
+ for (item in baseEntries) {
+ if (!(item in currentEntries))
+ callback(baseEntries[item], null);
+ }
+ },
+
+ sort: function(comparator, force) {
+ if (!force && this.lastComparator === comparator)
+ return;
+
+ this.children.sort(comparator);
+ var childCount = this.children.length;
+ for (var childIndex = 0; childIndex < childCount; ++childIndex)
+ this.children[childIndex]._recalculateSiblings(childIndex);
+ for (var i = 0; i < this.children.length; ++i) {
+ var child = this.children[i];
+ if (!force && (!child.expanded || child.lastComparator === comparator))
+ continue;
+ child.sort(comparator, force);
+ }
+ this.lastComparator = comparator;
+ },
+
+ signForDelta: function(delta) {
+ if (delta === 0)
+ return "";
+ if (delta > 0)
+ return "+";
+ else
+ return "\u2212"; // Math minus sign, same width as plus.
+ },
+
+ showDeltaAsPercent: function(value)
+ {
+ if (value === Number.POSITIVE_INFINITY)
+ return WebInspector.UIString("new");
+ else if (value === Number.NEGATIVE_INFINITY)
+ return WebInspector.UIString("deleted");
+ if (value > 1000.0)
+ return WebInspector.UIString("%s >1000%%", this.signForDelta(value));
+ return WebInspector.UIString("%s%.2f%%", this.signForDelta(value), Math.abs(value));
+ },
+
+ getTotalCount: function()
+ {
+ if (!this._count) {
+ this._count = 0;
+ for (var i = 0, n = this.children.length; i < n; ++i)
+ this._count += this.children[i].count;
+ }
+ return this._count;
+ },
+
+ getTotalSize: function()
+ {
+ if (!this._size) {
+ this._size = 0;
+ for (var i = 0, n = this.children.length; i < n; ++i)
+ this._size += this.children[i].size;
+ }
+ return this._size;
+ },
+
+ get countPercent()
+ {
+ return this.count / this._parent.getTotalCount() * 100.0;
+ },
+
+ get sizePercent()
+ {
+ return this.size / this._parent.getTotalSize() * 100.0;
+ },
+
+ get countDeltaPercent()
+ {
+ if (this.baseCount > 0) {
+ if (this.count > 0)
+ return this.countDelta / this.baseCount * 100.0;
+ else
+ return Number.NEGATIVE_INFINITY;
+ } else
+ return Number.POSITIVE_INFINITY;
+ },
+
+ get sizeDeltaPercent()
+ {
+ if (this.baseSize > 0) {
+ if (this.size > 0)
+ return this.sizeDelta / this.baseSize * 100.0;
+ else
+ return Number.NEGATIVE_INFINITY;
+ } else
+ return Number.POSITIVE_INFINITY;
+ },
+
+ get data()
+ {
+ var data = {};
+
+ data["cons"] = this.constructorName;
+
+ if (this.snapshotView.showCountAsPercent)
+ data["count"] = WebInspector.UIString("%.2f%%", this.countPercent);
+ else
+ data["count"] = this.count;
+
+ if (this.size !== null) {
+ if (this.snapshotView.showSizeAsPercent)
+ data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent);
+ else
+ data["size"] = Number.bytesToString(this.size);
+ } else
+ data["size"] = "";
+
+ if (this.snapshotView.showCountDeltaAsPercent)
+ data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent);
+ else
+ data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta));
+
+ if (this.sizeDelta !== null) {
+ if (this.snapshotView.showSizeDeltaAsPercent)
+ data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent);
+ else
+ data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta)));
+ } else
+ data["sizeDelta"] = "";
+
+ return data;
+ },
+
+ createCell: function(columnIdentifier)
+ {
+ var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
+
+ if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) ||
+ (columnIdentifier === "count" && this._searchMatchedCountColumn) ||
+ (columnIdentifier === "size" && this._searchMatchedSizeColumn) ||
+ (columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) ||
+ (columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn))
+ cell.addStyleClass("highlight");
+
+ return cell;
+ }
+};
+
+WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.__proto__ = WebInspector.DataGridNode.prototype;
+
+WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
+{
+ this.snapshotView = snapshotView;
+
+ if (!snapshotEntry)
+ snapshotEntry = { constructorName: baseEntry.constructorName, count: 0, size: 0, retainers: {} };
+ this.constructorName = snapshotEntry.constructorName;
+ this.count = snapshotEntry.count;
+ this.size = snapshotEntry.size;
+ this.retainers = snapshotEntry.retainers;
+
+ if (!baseEntry)
+ baseEntry = { count: 0, size: 0, retainers: {} };
+ this.baseCount = baseEntry.count;
+ this.countDelta = this.count - this.baseCount;
+ this.baseSize = baseEntry.size;
+ this.sizeDelta = this.size - this.baseSize;
+ this.baseRetainers = baseEntry.retainers;
+
+ WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
+};
+
+WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
+
+WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries)
+{
+ this.tree = this;
+ this.snapshotView = snapshotView;
+ this.children = [];
+ this.lastComparator = null;
+ this.populateChildren(baseEntries, snapshotEntries);
+};
+
+WebInspector.HeapSnapshotDataGridList.prototype = {
+ appendChild: function(child)
+ {
+ this.insertChild(child, this.children.length);
+ },
+
+ insertChild: function(child, index)
+ {
+ this.children.splice(index, 0, child);
+ },
+
+ removeChildren: function()
+ {
+ this.children = [];
+ },
+
+ populateChildren: function(baseEntries, snapshotEntries)
+ {
+ function appendListEntry(baseItem, snapshotItem)
+ {
+ this.appendChild(new WebInspector.HeapSnapshotDataGridNode(this.snapshotView, baseItem, snapshotItem, this));
+ }
+ this.produceDiff(baseEntries, snapshotEntries, appendListEntry.bind(this));
+ },
+
+ produceDiff: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff,
+ sort: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort,
+ getTotalCount: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount,
+ getTotalSize: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize
+};
+
+WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}];
+
+WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending)
+{
+ var propertyHash = property + "#" + property2;
+ var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash];
+ if (!comparator) {
+ comparator = function(lhs, rhs) {
+ var l = lhs[property], r = rhs[property];
+ if ((l === null || r === null) && property2 !== null)
+ l = lhs[property2], r = rhs[property2];
+ var result = l < r ? -1 : (l > r ? 1 : 0);
+ return isAscending ? result : -result;
+ };
+ this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator;
+ }
+ return comparator;
+};
+
+WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
+{
+ this.snapshotView = snapshotView;
+
+ if (!snapshotEntry)
+ snapshotEntry = { constructorName: baseEntry.constructorName, count: 0, clusters: {} };
+ this.constructorName = snapshotEntry.constructorName;
+ this.count = snapshotEntry.count;
+ this.retainers = this._calculateRetainers(this.snapshotView.profile, snapshotEntry.clusters);
+
+ if (!baseEntry)
+ baseEntry = { count: 0, clusters: {} };
+ this.baseCount = baseEntry.count;
+ this.countDelta = this.count - this.baseCount;
+ this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters);
+
+ this.size = null;
+ this.sizeDelta = null;
+
+ WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
+}
+
+WebInspector.HeapSnapshotDataGridRetainerNode.prototype = {
+ get sizePercent()
+ {
+ return null;
+ },
+
+ get sizeDeltaPercent()
+ {
+ return null;
+ },
+
+ _calculateRetainers: function(snapshot, clusters)
+ {
+ var retainers = {};
+ if (this.isEmptySet(clusters)) {
+ if (this.constructorName in snapshot.entries)
+ return snapshot.entries[this.constructorName].retainers;
+ } else {
+ // In case when an entry is retained by clusters, we need to gather up the list
+ // of retainers by merging retainers of every cluster.
+ // E.g. having such a tree:
+ // A
+ // Object:1 10
+ // X 3
+ // Y 4
+ // Object:2 5
+ // X 6
+ //
+ // will result in a following retainers list: X 9, Y 4.
+ for (var clusterName in clusters) {
+ if (clusterName in snapshot.clusters) {
+ var clusterRetainers = snapshot.clusters[clusterName].retainers;
+ for (var clusterRetainer in clusterRetainers) {
+ var clusterRetainerEntry = clusterRetainers[clusterRetainer];
+ if (!(clusterRetainer in retainers))
+ retainers[clusterRetainer] = { constructorName: clusterRetainerEntry.constructorName, count: 0, clusters: {} };
+ retainers[clusterRetainer].count += clusterRetainerEntry.count;
+ for (var clusterRetainerCluster in clusterRetainerEntry.clusters)
+ retainers[clusterRetainer].clusters[clusterRetainerCluster] = true;
+ }
+ }
+ }
+ }
+ return retainers;
+ }
+};
+
+WebInspector.HeapSnapshotDataGridRetainerNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
+
+
+WebInspector.HeapSnapshotProfileType = function()
+{
+ WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS"));
+}
+
+WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
+
+WebInspector.HeapSnapshotProfileType.prototype = {
+ get buttonTooltip()
+ {
+ return WebInspector.UIString("Take heap snapshot.");
+ },
+
+ get buttonStyle()
+ {
+ return "heap-snapshot-status-bar-item status-bar-item";
+ },
+
+ buttonClicked: function()
+ {
+ InspectorBackend.takeHeapSnapshot();
+ },
+
+ get welcomeMessage()
+ {
+ return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar.");
+ },
+
+ createSidebarTreeElementForProfile: function(profile)
+ {
+ return new WebInspector.ProfileSidebarTreeElement(profile, WebInspector.UIString("Snapshot %d"), "heap-snapshot-sidebar-tree-item");
+ },
+
+ createView: function(profile)
+ {
+ return new WebInspector.HeapSnapshotView(WebInspector.panels.profiles, profile);
+ }
+}
+
+WebInspector.HeapSnapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype;
diff --git a/WebCore/inspector/front-end/ProfileView.js b/WebCore/inspector/front-end/ProfileView.js
index ca271d0..c325bf7 100644
--- a/WebCore/inspector/front-end/ProfileView.js
+++ b/WebCore/inspector/front-end/ProfileView.js
@@ -94,7 +94,7 @@ WebInspector.CPUProfileView = function(profile)
self._updatePercentButton();
}
- InspectorBackend.getProfile(this.profile.uid, profileCallback);
+ InspectorBackend.getProfile(this.profile.typeId, this.profile.uid, profileCallback);
}
WebInspector.CPUProfileView.prototype = {
@@ -610,7 +610,7 @@ WebInspector.CPUProfileType.prototype = {
createSidebarTreeElementForProfile: function(profile)
{
- return new WebInspector.ProfileSidebarTreeElement(profile);
+ return new WebInspector.ProfileSidebarTreeElement(profile, WebInspector.UIString("Profile %d"), "profile-sidebar-tree-item");
},
createView: function(profile)
diff --git a/WebCore/inspector/front-end/ProfilesPanel.js b/WebCore/inspector/front-end/ProfilesPanel.js
index f2aab76..2bd76f9 100644
--- a/WebCore/inspector/front-end/ProfilesPanel.js
+++ b/WebCore/inspector/front-end/ProfilesPanel.js
@@ -320,6 +320,7 @@ WebInspector.ProfilesPanel.prototype = {
this.welcomeView.hide();
if (!this.visibleView)
this.showProfile(profile);
+ this.dispatchEventToListeners("profile added");
}
},
@@ -344,7 +345,7 @@ WebInspector.ProfilesPanel.prototype = {
sidebarParent.removeChild(profile._profilesTreeElement);
if (!profile.isTemporary)
- InspectorBackend.removeProfile(profile.uid);
+ InspectorBackend.removeProfile(profile.typeId, profile.uid);
// No other item will be selected if there aren't any other profiles, so
// make sure that view gets cleared when the last profile is removed.
@@ -375,6 +376,27 @@ WebInspector.ProfilesPanel.prototype = {
this.profileViewStatusBarItemsContainer.appendChild(statusBarItems[i]);
},
+ getProfiles: function(typeId)
+ {
+ var result = [];
+ var profilesCount = this._profiles.length;
+ for (var i = 0; i < profilesCount; ++i)
+ if (this._profiles[i].typeId === typeId)
+ result.push(this._profiles[i]);
+ return result;
+ },
+
+ updateProfile: function(profile)
+ {
+ var profilesCount = this._profiles.length;
+ for (var i = 0; i < profilesCount; ++i)
+ if (this._profiles[i].typeId === profile.typeId
+ && this._profiles[i].uid === profile.uid) {
+ this._profiles[i] = profile;
+ break;
+ }
+ },
+
showView: function(view)
{
this.showProfile(view.profile);
@@ -535,14 +557,15 @@ WebInspector.ProfilesPanel.prototype = {
WebInspector.ProfilesPanel.prototype.__proto__ = WebInspector.Panel.prototype;
-WebInspector.ProfileSidebarTreeElement = function(profile)
+WebInspector.ProfileSidebarTreeElement = function(profile, titleFormat, className)
{
this.profile = profile;
+ this._titleFormat = titleFormat;
if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
this._profileNumber = this.profile.title.substring(UserInitiatedProfileName.length + 1);
- WebInspector.SidebarTreeElement.call(this, "profile-sidebar-tree-item", "", "", profile, false);
+ WebInspector.SidebarTreeElement.call(this, className, "", "", profile, false);
this.refreshTitles();
}
@@ -564,7 +587,7 @@ WebInspector.ProfileSidebarTreeElement.prototype = {
if (this._mainTitle)
return this._mainTitle;
if (this.profile.title.indexOf(UserInitiatedProfileName) === 0)
- return WebInspector.UIString("Profile %d", this._profileNumber);
+ return WebInspector.UIString(this._titleFormat, this._profileNumber);
return this.profile.title;
},
diff --git a/WebCore/inspector/front-end/WebKit.qrc b/WebCore/inspector/front-end/WebKit.qrc
index 4901857..1f15db3 100644
--- a/WebCore/inspector/front-end/WebKit.qrc
+++ b/WebCore/inspector/front-end/WebKit.qrc
@@ -40,6 +40,7 @@
<file>ExtensionServer.js</file>
<file>FontView.js</file>
<file>HAREntry.js</file>
+ <file>HeapSnapshotView.js</file>
<file>HelpScreen.js</file>
<file>ImageView.js</file>
<file>InjectedFakeWorker.js</file>
diff --git a/WebCore/inspector/front-end/inspector.css b/WebCore/inspector/front-end/inspector.css
index 4319816..a3ffa44 100644
--- a/WebCore/inspector/front-end/inspector.css
+++ b/WebCore/inspector/front-end/inspector.css
@@ -3910,6 +3910,115 @@ button.enable-toggle-status-bar-item .glyph {
-webkit-mask-image: url(Images/reloadButtonGlyph.png);
}
+/* Heap Snapshot View Styles */
+
+/* FIXME: move to a separate css file */
+.heap-snapshot-sidebar-tree-item .icon {
+ content: url(Images/profileIcon.png);
+}
+
+.heap-snapshot-sidebar-tree-item.small .icon {
+ content: url(Images/profileSmallIcon.png);
+}
+
+.heap-snapshot-view {
+ display: none;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+}
+
+.heap-snapshot-view.visible {
+ display: block;
+}
+
+.heap-snapshot-view .data-grid {
+ border: none;
+ max-height: 100%;
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 93px;
+}
+
+.heap-snapshot-view .data-grid th.count-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.count-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.size-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.size-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.countDelta-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.countDelta-column {
+ text-align: right;
+}
+
+.heap-snapshot-view .data-grid th.sizeDelta-column {
+ text-align: center;
+}
+
+.heap-snapshot-view .data-grid td.sizeDelta-column {
+ text-align: right;
+}
+
+#heap-snapshot-summary-container {
+ position: absolute;
+ padding-top: 20px;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 93px;
+ margin-left: -1px;
+ border-left: 1px solid rgb(102, 102, 102);
+ background-color: rgb(101, 111, 130);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
+ background-repeat: repeat-x;
+ background-position: top;
+ text-align: center;
+ text-shadow: black 0 1px 1px;
+ white-space: nowrap;
+ color: white;
+ -webkit-background-size: 1px 6px;
+ -webkit-background-origin: padding;
+ -webkit-background-clip: padding;
+}
+
+.heap-snapshot-summary {
+ display: inline-block;
+ width: 50%;
+ min-width: 300px;
+ position: relative;
+}
+
+.heap-snapshot-summary canvas.summary-graph {
+ width: 225px;
+}
+
+.heap-snapshot-summary-label {
+ font-size: 12px;
+ font-weight: bold;
+ position: absolute;
+ top: 1px;
+ width: 50%;
+ left: 25%;
+}
+
.delete-storage-status-bar-item .glyph {
-webkit-mask-image: url(Images/excludeButtonGlyph.png);
}
diff --git a/WebCore/inspector/front-end/inspector.html b/WebCore/inspector/front-end/inspector.html
index 14e2cdc..4968685 100644
--- a/WebCore/inspector/front-end/inspector.html
+++ b/WebCore/inspector/front-end/inspector.html
@@ -125,6 +125,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<script type="text/javascript" src="BottomUpProfileDataGridTree.js"></script>
<script type="text/javascript" src="TopDownProfileDataGridTree.js"></script>
<script type="text/javascript" src="ProfileView.js"></script>
+ <script type="text/javascript" src="HeapSnapshotView.js"></script>
<script type="text/javascript" src="DOMAgent.js"></script>
<script type="text/javascript" src="InjectedScript.js"></script>
<script type="text/javascript" src="InjectedScriptAccess.js"></script>
diff --git a/WebCore/inspector/front-end/inspector.js b/WebCore/inspector/front-end/inspector.js
index 2e2c54f..cf47dc6 100644
--- a/WebCore/inspector/front-end/inspector.js
+++ b/WebCore/inspector/front-end/inspector.js
@@ -233,6 +233,8 @@ var WebInspector = {
if (hiddenPanels.indexOf("profiles") === -1) {
this.panels.profiles = new WebInspector.ProfilesPanel();
this.panels.profiles.registerProfileType(new WebInspector.CPUProfileType());
+ if (Preferences.heapProfilerPresent)
+ this.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType());
}
if (hiddenPanels.indexOf("storage") === -1 && hiddenPanels.indexOf("databases") === -1)
this.panels.storage = new WebInspector.StoragePanel();
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 806bc09..06358c3 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,24 @@
+2010-08-26 Mikhail Naganov <mnaganov at chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Web Inspector: Store heap snapshots in InspectorProfilerAgent.
+
+ Change the way heap snapshots are transported to Inspector
+ to be aligned with CPU profiles. As a result, the Heap snapshots
+ view of Profiles panel was upstreamed into WebCore.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44531
+
+ * DEPS:
+ * WebKit.gypi:
+ * src/js/DevTools.js:
+ ():
+ * src/js/HeapProfilerPanel.js: Removed.
+ * src/js/ProfilerAgent.js: Removed.
+ * src/js/ProfilerProcessor.js: Removed.
+ * src/js/devTools.css:
+
2010-08-26 Yury Semikhatsky <yurys at chromium.org>
Unreviewed. Revert r66103 since Qt tests are failing.
diff --git a/WebKit/chromium/DEPS b/WebKit/chromium/DEPS
index c189f59..759f7e9 100644
--- a/WebKit/chromium/DEPS
+++ b/WebKit/chromium/DEPS
@@ -32,7 +32,7 @@
vars = {
'chromium_svn': 'http://src.chromium.org/svn/trunk/src',
- 'chromium_rev': '57298',
+ 'chromium_rev': '57489',
}
deps = {
diff --git a/WebKit/chromium/WebKit.gypi b/WebKit/chromium/WebKit.gypi
index b45e3e7..4c6ac37 100644
--- a/WebKit/chromium/WebKit.gypi
+++ b/WebKit/chromium/WebKit.gypi
@@ -33,9 +33,6 @@
# List of DevTools source files, ordered by dependencies. It is used both
# for copying them to resource dir, and for generating 'devtools.html' file.
'devtools_js_files': [
- 'src/js/ProfilerAgent.js',
- 'src/js/ProfilerProcessor.js',
- 'src/js/HeapProfilerPanel.js',
'src/js/DevTools.js',
'src/js/DevToolsHostStub.js',
'src/js/Tests.js',
diff --git a/WebKit/chromium/src/js/DevTools.js b/WebKit/chromium/src/js/DevTools.js
index e3e0204..5184559 100644
--- a/WebKit/chromium/src/js/DevTools.js
+++ b/WebKit/chromium/src/js/DevTools.js
@@ -34,39 +34,10 @@
* DevTools frontend together. It is also responsible for overriding existing
* WebInspector functionality while it is getting upstreamed into WebCore.
*/
-devtools.ToolsAgent = function()
-{
- this.profilerAgent_ = new devtools.ProfilerAgent();
-};
-
-
-/**
- * @return {devtools.ProfilerAgent} Profiler agent instance.
- */
-devtools.ToolsAgent.prototype.getProfilerAgent = function()
-{
- return this.profilerAgent_;
-};
-
-
-
-/**
- * Global instance of the tools agent.
- * @type {devtools.ToolsAgent}
- */
-devtools.tools = null;
-
var context = {}; // Used by WebCore's inspector routines.
-///////////////////////////////////////////////////////////////////////////////
-// Here and below are overrides to existing WebInspector methods only.
-// TODO(pfeldman): Patch WebCore and upstream changes.
-var oldLoaded = WebInspector.loaded;
-WebInspector.loaded = function()
-{
- devtools.tools = new devtools.ToolsAgent();
-
+(function () {
Preferences.ignoreWhitespace = false;
Preferences.samplingCPUProfiler = true;
Preferences.heapProfilerPresent = true;
@@ -75,9 +46,7 @@ WebInspector.loaded = function()
Preferences.canEditScriptSource = true;
Preferences.onlineDetectionEnabled = false;
Preferences.domBreakpointsEnabled = true;
-
- oldLoaded.call(WebInspector);
-}
+})();
devtools.domContentLoaded = function()
{
@@ -88,12 +57,12 @@ devtools.domContentLoaded = function()
document.addEventListener("DOMContentLoaded", devtools.domContentLoaded, false);
+// FIXME: This needs to be upstreamed.
(function InterceptProfilesPanelEvents()
{
var oldShow = WebInspector.ProfilesPanel.prototype.show;
WebInspector.ProfilesPanel.prototype.show = function()
{
- devtools.tools.getProfilerAgent().initializeProfiling();
this.enableToggleButton.visible = false;
oldShow.call(this);
// Show is called on every show event of a panel, so
diff --git a/WebKit/chromium/src/js/HeapProfilerPanel.js b/WebKit/chromium/src/js/HeapProfilerPanel.js
deleted file mode 100644
index bcb008f..0000000
--- a/WebKit/chromium/src/js/HeapProfilerPanel.js
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @fileoverview Heap profiler panel implementation.
- */
-
-WebInspector.ProfilesPanel.prototype.addSnapshot = function(snapshot) {
- snapshot.title = WebInspector.UIString("Snapshot %d", snapshot.number);
- snapshot.typeId = WebInspector.HeapSnapshotProfileType.TypeId;
-
- var snapshots = WebInspector.HeapSnapshotProfileType.snapshots;
- snapshots.push(snapshot);
-
- snapshot.listIndex = snapshots.length - 1;
-
- if (WebInspector.CPUProfile)
- this.addProfileHeader(WebInspector.HeapSnapshotProfileType.TypeId, snapshot);
- else
- this.addProfileHeader(snapshot);
-
- this.dispatchEventToListeners("snapshot added");
-}
-
-
-WebInspector.HeapSnapshotView = function(parent, profile)
-{
- WebInspector.View.call(this);
-
- this.element.addStyleClass("heap-snapshot-view");
-
- this.parent = parent;
- this.parent.addEventListener("snapshot added", this._updateBaseOptions, this);
-
- this.showCountAsPercent = false;
- this.showSizeAsPercent = false;
- this.showCountDeltaAsPercent = false;
- this.showSizeDeltaAsPercent = false;
-
- this.categories = {
- code: new WebInspector.ResourceCategory("code", WebInspector.UIString("Code"), "rgb(255,121,0)"),
- data: new WebInspector.ResourceCategory("data", WebInspector.UIString("Objects"), "rgb(47,102,236)")
- };
-
- var summaryContainer = document.createElement("div");
- summaryContainer.id = "heap-snapshot-summary-container";
-
- this.countsSummaryBar = new WebInspector.SummaryBar(this.categories);
- this.countsSummaryBar.element.className = "heap-snapshot-summary";
- this.countsSummaryBar.calculator = new WebInspector.HeapSummaryCountCalculator();
- var countsLabel = document.createElement("div");
- countsLabel.className = "heap-snapshot-summary-label";
- countsLabel.textContent = WebInspector.UIString("Count");
- this.countsSummaryBar.element.appendChild(countsLabel);
- summaryContainer.appendChild(this.countsSummaryBar.element);
-
- this.sizesSummaryBar = new WebInspector.SummaryBar(this.categories);
- this.sizesSummaryBar.element.className = "heap-snapshot-summary";
- this.sizesSummaryBar.calculator = new WebInspector.HeapSummarySizeCalculator();
- var sizesLabel = document.createElement("label");
- sizesLabel.className = "heap-snapshot-summary-label";
- sizesLabel.textContent = WebInspector.UIString("Size");
- this.sizesSummaryBar.element.appendChild(sizesLabel);
- summaryContainer.appendChild(this.sizesSummaryBar.element);
-
- this.element.appendChild(summaryContainer);
-
- var columns = { "cons": { title: WebInspector.UIString("Constructor"), disclosure: true, sortable: true },
- "count": { title: WebInspector.UIString("Count"), width: "54px", sortable: true },
- "size": { title: WebInspector.UIString("Size"), width: "72px", sort: "descending", sortable: true },
- "countDelta": { title: WebInspector.UIString("\xb1 Count"), width: "72px", sortable: true },
- "sizeDelta": { title: WebInspector.UIString("\xb1 Size"), width: "72px", sortable: true } };
-
- this.dataGrid = new WebInspector.DataGrid(columns);
- this.dataGrid.addEventListener("sorting changed", this._sortData, this);
- this.dataGrid.element.addEventListener("mousedown", this._mouseDownInDataGrid.bind(this), true);
- this.element.appendChild(this.dataGrid.element);
-
- this.profile = profile;
-
- this.baseSelectElement = document.createElement("select");
- this.baseSelectElement.className = "status-bar-item";
- this.baseSelectElement.addEventListener("change", this._changeBase.bind(this), false);
- this._updateBaseOptions();
- if (this.profile.listIndex > 0)
- this.baseSelectElement.selectedIndex = this.profile.listIndex - 1;
- else
- this.baseSelectElement.selectedIndex = this.profile.listIndex;
- this._resetDataGridList();
-
- this.percentButton = new WebInspector.StatusBarButton("", "percent-time-status-bar-item status-bar-item");
- this.percentButton.addEventListener("click", this._percentClicked.bind(this), false);
-
- this.refresh();
-
- this._updatePercentButton();
-};
-
-WebInspector.HeapSnapshotView.prototype = {
-
- get statusBarItems()
- {
- return [this.baseSelectElement, this.percentButton.element];
- },
-
- get profile()
- {
- return this._profile;
- },
-
- set profile(profile)
- {
- this._profile = profile;
- },
-
- show: function(parentElement)
- {
- WebInspector.View.prototype.show.call(this, parentElement);
- this.dataGrid.updateWidths();
- },
-
- hide: function()
- {
- WebInspector.View.prototype.hide.call(this);
- this._currentSearchResultIndex = -1;
- },
-
- resize: function()
- {
- if (this.dataGrid)
- this.dataGrid.updateWidths();
- },
-
- refresh: function()
- {
- this.dataGrid.removeChildren();
-
- var children = this.snapshotDataGridList.children;
- var count = children.length;
- for (var index = 0; index < count; ++index)
- this.dataGrid.appendChild(children[index]);
-
- this._updateSummaryGraph();
- },
-
- refreshShowAsPercents: function()
- {
- this._updatePercentButton();
- this.refreshVisibleData();
- },
-
- _deleteSearchMatchedFlags: function(node)
- {
- delete node._searchMatchedConsColumn;
- delete node._searchMatchedCountColumn;
- delete node._searchMatchedSizeColumn;
- delete node._searchMatchedCountDeltaColumn;
- delete node._searchMatchedSizeDeltaColumn;
- },
-
- searchCanceled: function()
- {
- if (this._searchResults) {
- for (var i = 0; i < this._searchResults.length; ++i) {
- var profileNode = this._searchResults[i].profileNode;
- this._deleteSearchMatchedFlags(profileNode);
- profileNode.refresh();
- }
- }
-
- delete this._searchFinishedCallback;
- this._currentSearchResultIndex = -1;
- this._searchResults = [];
- },
-
- performSearch: function(query, finishedCallback)
- {
- // Call searchCanceled since it will reset everything we need before doing a new search.
- this.searchCanceled();
-
- query = query.trim();
-
- if (!query.length)
- return;
-
- this._searchFinishedCallback = finishedCallback;
-
- var helper = WebInspector.HeapSnapshotView.SearchHelper;
-
- var operationAndNumber = helper.parseOperationAndNumber(query);
- var operation = operationAndNumber[0];
- var queryNumber = operationAndNumber[1];
-
- var percentUnits = helper.percents.test(query);
- var megaBytesUnits = helper.megaBytes.test(query);
- var kiloBytesUnits = helper.kiloBytes.test(query);
- var bytesUnits = helper.bytes.test(query);
-
- var queryNumberBytes = (megaBytesUnits ? (queryNumber * 1024 * 1024) : (kiloBytesUnits ? (queryNumber * 1024) : queryNumber));
-
- function matchesQuery(heapSnapshotDataGridNode)
- {
- WebInspector.HeapSnapshotView.prototype._deleteSearchMatchedFlags(heapSnapshotDataGridNode);
-
- if (percentUnits) {
- heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.countPercent, queryNumber);
- heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.sizePercent, queryNumber);
- heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDeltaPercent, queryNumber);
- heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDeltaPercent, queryNumber);
- } else if (megaBytesUnits || kiloBytesUnits || bytesUnits) {
- heapSnapshotDataGridNode._searchMatchedSizeColumn = operation(heapSnapshotDataGridNode.size, queryNumberBytes);
- heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn = operation(heapSnapshotDataGridNode.sizeDelta, queryNumberBytes);
- } else {
- heapSnapshotDataGridNode._searchMatchedCountColumn = operation(heapSnapshotDataGridNode.count, queryNumber);
- heapSnapshotDataGridNode._searchMatchedCountDeltaColumn = operation(heapSnapshotDataGridNode.countDelta, queryNumber);
- }
-
- if (heapSnapshotDataGridNode.constructorName.hasSubstring(query, true))
- heapSnapshotDataGridNode._searchMatchedConsColumn = true;
-
- if (heapSnapshotDataGridNode._searchMatchedConsColumn ||
- heapSnapshotDataGridNode._searchMatchedCountColumn ||
- heapSnapshotDataGridNode._searchMatchedSizeColumn ||
- heapSnapshotDataGridNode._searchMatchedCountDeltaColumn ||
- heapSnapshotDataGridNode._searchMatchedSizeDeltaColumn) {
- heapSnapshotDataGridNode.refresh();
- return true;
- }
-
- return false;
- }
-
- var current = this.snapshotDataGridList.children[0];
- var depth = 0;
- var info = {};
-
- // The second and subsequent levels of heap snapshot nodes represent retainers,
- // so recursive expansion will be infinite, since a graph is being traversed.
- // So default to a recursion cap of 2 levels.
- var maxDepth = 2;
-
- while (current) {
- if (matchesQuery(current))
- this._searchResults.push({ profileNode: current });
- current = current.traverseNextNode(false, null, (depth >= maxDepth), info);
- depth += info.depthChange;
- }
-
- finishedCallback(this, this._searchResults.length);
- },
-
- jumpToFirstSearchResult: WebInspector.CPUProfileView.prototype.jumpToFirstSearchResult,
- jumpToLastSearchResult: WebInspector.CPUProfileView.prototype.jumpToLastSearchResult,
- jumpToNextSearchResult: WebInspector.CPUProfileView.prototype.jumpToNextSearchResult,
- jumpToPreviousSearchResult: WebInspector.CPUProfileView.prototype.jumpToPreviousSearchResult,
- showingFirstSearchResult: WebInspector.CPUProfileView.prototype.showingFirstSearchResult,
- showingLastSearchResult: WebInspector.CPUProfileView.prototype.showingLastSearchResult,
- _jumpToSearchResult: WebInspector.CPUProfileView.prototype._jumpToSearchResult,
-
- refreshVisibleData: function()
- {
- var child = this.dataGrid.children[0];
- while (child) {
- child.refresh();
- child = child.traverseNextNode(false, null, true);
- }
- this._updateSummaryGraph();
- },
-
- _changeBase: function() {
- if (this.baseSnapshot === WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex])
- return;
-
- this._resetDataGridList();
- this.refresh();
-
- if (!this.currentQuery || !this._searchFinishedCallback || !this._searchResults)
- return;
-
- // The current search needs to be performed again. First negate out previous match
- // count by calling the search finished callback with a negative number of matches.
- // Then perform the search again with the same query and callback.
- this._searchFinishedCallback(this, -this._searchResults.length);
- this.performSearch(this.currentQuery, this._searchFinishedCallback);
- },
-
- _createSnapshotDataGridList: function()
- {
- if (this._snapshotDataGridList)
- delete this._snapshotDataGridList;
-
- this._snapshotDataGridList = new WebInspector.HeapSnapshotDataGridList(this, this.baseSnapshot.entries, this.profile.entries);
- return this._snapshotDataGridList;
- },
-
- _mouseDownInDataGrid: function(event)
- {
- if (event.detail < 2)
- return;
-
- var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
- if (!cell || (!cell.hasStyleClass("count-column") && !cell.hasStyleClass("size-column") && !cell.hasStyleClass("countDelta-column") && !cell.hasStyleClass("sizeDelta-column")))
- return;
-
- if (cell.hasStyleClass("count-column"))
- this.showCountAsPercent = !this.showCountAsPercent;
- else if (cell.hasStyleClass("size-column"))
- this.showSizeAsPercent = !this.showSizeAsPercent;
- else if (cell.hasStyleClass("countDelta-column"))
- this.showCountDeltaAsPercent = !this.showCountDeltaAsPercent;
- else if (cell.hasStyleClass("sizeDelta-column"))
- this.showSizeDeltaAsPercent = !this.showSizeDeltaAsPercent;
-
- this.refreshShowAsPercents();
-
- event.preventDefault();
- event.stopPropagation();
- },
-
- get _isShowingAsPercent()
- {
- return this.showCountAsPercent && this.showSizeAsPercent && this.showCountDeltaAsPercent && this.showSizeDeltaAsPercent;
- },
-
- _percentClicked: function(event)
- {
- var currentState = this._isShowingAsPercent;
- this.showCountAsPercent = !currentState;
- this.showSizeAsPercent = !currentState;
- this.showCountDeltaAsPercent = !currentState;
- this.showSizeDeltaAsPercent = !currentState;
- this.refreshShowAsPercents();
- },
-
- _resetDataGridList: function()
- {
- this.baseSnapshot = WebInspector.HeapSnapshotProfileType.snapshots[this.baseSelectElement.selectedIndex];
- var lastComparator = WebInspector.HeapSnapshotDataGridList.propertyComparator("size", false);
- if (this.snapshotDataGridList)
- lastComparator = this.snapshotDataGridList.lastComparator;
- this.snapshotDataGridList = this._createSnapshotDataGridList();
- this.snapshotDataGridList.sort(lastComparator, true);
- },
-
- _sortData: function()
- {
- var sortAscending = this.dataGrid.sortOrder === "ascending";
- var sortColumnIdentifier = this.dataGrid.sortColumnIdentifier;
- var sortProperty = {
- "cons": ["constructorName", null],
- "count": ["count", null],
- "size": ["size", "count"],
- "countDelta": this.showCountDeltaAsPercent ? ["countDeltaPercent", null] : ["countDelta", null],
- "sizeDelta": this.showSizeDeltaAsPercent ? ["sizeDeltaPercent", "countDeltaPercent"] : ["sizeDelta", "sizeDeltaPercent"]
- }[sortColumnIdentifier];
-
- this.snapshotDataGridList.sort(WebInspector.HeapSnapshotDataGridList.propertyComparator(sortProperty[0], sortProperty[1], sortAscending));
-
- this.refresh();
- },
-
- _updateBaseOptions: function()
- {
- var list = WebInspector.HeapSnapshotProfileType.snapshots;
- // We're assuming that snapshots can only be added.
- if (this.baseSelectElement.length === list.length)
- return;
-
- for (var i = this.baseSelectElement.length, n = list.length; i < n; ++i) {
- var baseOption = document.createElement("option");
- baseOption.label = WebInspector.UIString("Compared to %s", list[i].title);
- this.baseSelectElement.appendChild(baseOption);
- }
- },
-
- _updatePercentButton: function()
- {
- if (this._isShowingAsPercent) {
- this.percentButton.title = WebInspector.UIString("Show absolute counts and sizes.");
- this.percentButton.toggled = true;
- } else {
- this.percentButton.title = WebInspector.UIString("Show counts and sizes as percentages.");
- this.percentButton.toggled = false;
- }
- },
-
- _updateSummaryGraph: function()
- {
- this.countsSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
- this.countsSummaryBar.update(this.profile.lowlevels);
-
- this.sizesSummaryBar.calculator.showAsPercent = this._isShowingAsPercent;
- this.sizesSummaryBar.update(this.profile.lowlevels);
- }
-};
-
-WebInspector.HeapSnapshotView.prototype.__proto__ = WebInspector.View.prototype;
-
-WebInspector.HeapSnapshotView.SearchHelper = {
- // In comparators, we assume that a value from a node is passed as the first parameter.
- operations: { LESS: function (a, b) { return a !== null && a < b; },
- LESS_OR_EQUAL: function (a, b) { return a !== null && a <= b; },
- EQUAL: function (a, b) { return a !== null && a === b; },
- GREATER_OR_EQUAL: function (a, b) { return a !== null && a >= b; },
- GREATER: function (a, b) { return a !== null && a > b; } },
-
- operationParsers: { LESS: /^<(\d+)/,
- LESS_OR_EQUAL: /^<=(\d+)/,
- GREATER_OR_EQUAL: /^>=(\d+)/,
- GREATER: /^>(\d+)/ },
-
- parseOperationAndNumber: function(query)
- {
- var operations = WebInspector.HeapSnapshotView.SearchHelper.operations;
- var parsers = WebInspector.HeapSnapshotView.SearchHelper.operationParsers;
- for (var operation in parsers) {
- var match = query.match(parsers[operation]);
- if (match !== null)
- return [operations[operation], parseFloat(match[1])];
- }
- return [operations.EQUAL, parseFloat(query)];
- },
-
- percents: /%$/,
-
- megaBytes: /MB$/i,
-
- kiloBytes: /KB$/i,
-
- bytes: /B$/i
-}
-
-WebInspector.HeapSummaryCalculator = function(lowLevelField)
-{
- this.total = 1;
- this.lowLevelField = lowLevelField;
-}
-
-WebInspector.HeapSummaryCalculator.prototype = {
- computeSummaryValues: function(lowLevels)
- {
- var highLevels = {data: 0, code: 0};
- this.total = 0;
- for (var item in lowLevels) {
- var highItem = this._highFromLow(item);
- if (highItem) {
- var value = lowLevels[item][this.lowLevelField];
- highLevels[highItem] += value;
- this.total += value;
- }
- }
- var result = {categoryValues: highLevels};
- if (!this.showAsPercent)
- result.total = this.total;
- return result;
- },
-
- formatValue: function(value)
- {
- if (this.showAsPercent)
- return WebInspector.UIString("%.2f%%", value / this.total * 100.0);
- else
- return this._valueToString(value);
- },
-
- get showAsPercent()
- {
- return this._showAsPercent;
- },
-
- set showAsPercent(x)
- {
- this._showAsPercent = x;
- }
-}
-
-WebInspector.HeapSummaryCountCalculator = function()
-{
- WebInspector.HeapSummaryCalculator.call(this, "count");
-}
-
-WebInspector.HeapSummaryCountCalculator.prototype = {
- _highFromLow: function(type) {
- if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
- if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/)) return "data";
- return null;
- },
-
- _valueToString: function(value) {
- return value.toString();
- }
-}
-
-WebInspector.HeapSummaryCountCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;
-
-WebInspector.HeapSummarySizeCalculator = function()
-{
- WebInspector.HeapSummaryCalculator.call(this, "size");
-}
-
-WebInspector.HeapSummarySizeCalculator.prototype = {
- _highFromLow: function(type) {
- if (type === "CODE_TYPE" || type === "SHARED_FUNCTION_INFO_TYPE" || type === "SCRIPT_TYPE") return "code";
- if (type === "STRING_TYPE" || type === "HEAP_NUMBER_TYPE" || type.match(/^JS_/) || type.match(/_ARRAY_TYPE$/)) return "data";
- return null;
- },
-
- _valueToString: Number.bytesToString
-}
-
-WebInspector.HeapSummarySizeCalculator.prototype.__proto__ = WebInspector.HeapSummaryCalculator.prototype;
-
-WebInspector.HeapSnapshotSidebarTreeElement = function(snapshot)
-{
- this.profile = snapshot;
-
- WebInspector.SidebarTreeElement.call(this, "heap-snapshot-sidebar-tree-item", "", "", snapshot, false);
-
- this.refreshTitles();
-};
-
-WebInspector.HeapSnapshotSidebarTreeElement.prototype = {
- get mainTitle()
- {
- if (this._mainTitle)
- return this._mainTitle;
- return this.profile.title;
- },
-
- set mainTitle(x)
- {
- this._mainTitle = x;
- this.refreshTitles();
- }
-};
-
-WebInspector.HeapSnapshotSidebarTreeElement.prototype.__proto__ = WebInspector.ProfileSidebarTreeElement.prototype;
-
-WebInspector.HeapSnapshotDataGridNodeWithRetainers = function(owningTree)
-{
- this.tree = owningTree;
-
- WebInspector.DataGridNode.call(this, null, this._hasRetainers);
-
- this.addEventListener("populate", this._populate, this);
-};
-
-WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype = {
- isEmptySet: function(set)
- {
- for (var x in set)
- return false;
- return true;
- },
-
- get _hasRetainers()
- {
- return !this.isEmptySet(this.retainers);
- },
-
- get _parent()
- {
- // For top-level nodes, return owning tree as a parent, not data grid.
- return this.parent !== this.dataGrid ? this.parent : this.tree;
- },
-
- _populate: function(event)
- {
- var self = this;
- this.produceDiff(this.baseRetainers, this.retainers, function(baseItem, snapshotItem) {
- self.appendChild(new WebInspector.HeapSnapshotDataGridRetainerNode(self.snapshotView, baseItem, snapshotItem, self.tree));
- });
-
- if (this._parent) {
- var currentComparator = this._parent.lastComparator;
- if (currentComparator)
- this.sort(currentComparator, true);
- }
-
- this.removeEventListener("populate", this._populate, this);
- },
-
- produceDiff: function(baseEntries, currentEntries, callback)
- {
- for (var item in currentEntries)
- callback(baseEntries[item], currentEntries[item]);
-
- for (item in baseEntries) {
- if (!(item in currentEntries))
- callback(baseEntries[item], null);
- }
- },
-
- sort: function(comparator, force) {
- if (!force && this.lastComparator === comparator)
- return;
-
- this.children.sort(comparator);
- var childCount = this.children.length;
- for (var childIndex = 0; childIndex < childCount; ++childIndex)
- this.children[childIndex]._recalculateSiblings(childIndex);
- for (var i = 0; i < this.children.length; ++i) {
- var child = this.children[i];
- if (!force && (!child.expanded || child.lastComparator === comparator))
- continue;
- child.sort(comparator, force);
- }
- this.lastComparator = comparator;
- },
-
- signForDelta: function(delta) {
- if (delta === 0)
- return "";
- if (delta > 0)
- return "+";
- else
- // Math minus sign, same width as plus.
- return "\u2212";
- },
-
- showDeltaAsPercent: function(value) {
- if (value === Number.POSITIVE_INFINITY)
- return WebInspector.UIString("new");
- else if (value === Number.NEGATIVE_INFINITY)
- return WebInspector.UIString("deleted");
- if (value > 1000.0)
- return WebInspector.UIString("%s >1000%%", this.signForDelta(value));
- return WebInspector.UIString("%s%.2f%%", this.signForDelta(value), Math.abs(value));
- },
-
- getTotalCount: function() {
- if (!this._count) {
- this._count = 0;
- for (var i = 0, n = this.children.length; i < n; ++i)
- this._count += this.children[i].count;
- }
- return this._count;
- },
-
- getTotalSize: function() {
- if (!this._size) {
- this._size = 0;
- for (var i = 0, n = this.children.length; i < n; ++i)
- this._size += this.children[i].size;
- }
- return this._size;
- },
-
- get countPercent()
- {
- return this.count / this._parent.getTotalCount() * 100.0;
- },
-
- get sizePercent()
- {
- return this.size / this._parent.getTotalSize() * 100.0;
- },
-
- get countDeltaPercent()
- {
- if (this.baseCount > 0) {
- if (this.count > 0)
- return this.countDelta / this.baseCount * 100.0;
- else
- return Number.NEGATIVE_INFINITY;
- } else
- return Number.POSITIVE_INFINITY;
- },
-
- get sizeDeltaPercent()
- {
- if (this.baseSize > 0) {
- if (this.size > 0)
- return this.sizeDelta / this.baseSize * 100.0;
- else
- return Number.NEGATIVE_INFINITY;
- } else
- return Number.POSITIVE_INFINITY;
- },
-
- get data()
- {
- var data = {};
-
- data["cons"] = this.constructorName;
-
- if (this.snapshotView.showCountAsPercent)
- data["count"] = WebInspector.UIString("%.2f%%", this.countPercent);
- else
- data["count"] = this.count;
-
- if (this.size !== null) {
- if (this.snapshotView.showSizeAsPercent)
- data["size"] = WebInspector.UIString("%.2f%%", this.sizePercent);
- else
- data["size"] = Number.bytesToString(this.size);
- } else
- data["size"] = "";
-
- if (this.snapshotView.showCountDeltaAsPercent)
- data["countDelta"] = this.showDeltaAsPercent(this.countDeltaPercent);
- else
- data["countDelta"] = WebInspector.UIString("%s%d", this.signForDelta(this.countDelta), Math.abs(this.countDelta));
-
- if (this.sizeDelta !== null) {
- if (this.snapshotView.showSizeDeltaAsPercent)
- data["sizeDelta"] = this.showDeltaAsPercent(this.sizeDeltaPercent);
- else
- data["sizeDelta"] = WebInspector.UIString("%s%s", this.signForDelta(this.sizeDelta), Number.bytesToString(Math.abs(this.sizeDelta)));
- } else
- data["sizeDelta"] = "";
-
- return data;
- },
-
- createCell: function(columnIdentifier)
- {
- var cell = WebInspector.DataGridNode.prototype.createCell.call(this, columnIdentifier);
-
- if ((columnIdentifier === "cons" && this._searchMatchedConsColumn) ||
- (columnIdentifier === "count" && this._searchMatchedCountColumn) ||
- (columnIdentifier === "size" && this._searchMatchedSizeColumn) ||
- (columnIdentifier === "countDelta" && this._searchMatchedCountDeltaColumn) ||
- (columnIdentifier === "sizeDelta" && this._searchMatchedSizeDeltaColumn))
- cell.addStyleClass("highlight");
-
- return cell;
- }
-};
-
-WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.__proto__ = WebInspector.DataGridNode.prototype;
-
-WebInspector.HeapSnapshotDataGridNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
-{
- this.snapshotView = snapshotView;
-
- if (!snapshotEntry)
- snapshotEntry = { cons: baseEntry.cons, count: 0, size: 0, retainers: {} };
- this.constructorName = snapshotEntry.cons;
- this.count = snapshotEntry.count;
- this.size = snapshotEntry.size;
- this.retainers = snapshotEntry.retainers;
-
- if (!baseEntry)
- baseEntry = { count: 0, size: 0, retainers: {} };
- this.baseCount = baseEntry.count;
- this.countDelta = this.count - this.baseCount;
- this.baseSize = baseEntry.size;
- this.sizeDelta = this.size - this.baseSize;
- this.baseRetainers = baseEntry.retainers;
-
- WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
-};
-
-WebInspector.HeapSnapshotDataGridNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
-
-WebInspector.HeapSnapshotDataGridList = function(snapshotView, baseEntries, snapshotEntries)
-{
- this.tree = this;
- this.snapshotView = snapshotView;
- this.children = [];
- this.lastComparator = null;
- this.populateChildren(baseEntries, snapshotEntries);
-};
-
-WebInspector.HeapSnapshotDataGridList.prototype = {
- appendChild: function(child)
- {
- this.insertChild(child, this.children.length);
- },
-
- insertChild: function(child, index)
- {
- this.children.splice(index, 0, child);
- },
-
- removeChildren: function()
- {
- this.children = [];
- },
-
- populateChildren: function(baseEntries, snapshotEntries)
- {
- var self = this;
- this.produceDiff(baseEntries, snapshotEntries, function(baseItem, snapshotItem) {
- self.appendChild(new WebInspector.HeapSnapshotDataGridNode(self.snapshotView, baseItem, snapshotItem, self));
- });
- },
-
- produceDiff: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.produceDiff,
- sort: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.sort,
- getTotalCount: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalCount,
- getTotalSize: WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype.getTotalSize
-};
-
-WebInspector.HeapSnapshotDataGridList.propertyComparators = [{}, {}];
-
-WebInspector.HeapSnapshotDataGridList.propertyComparator = function(property, property2, isAscending)
-{
- var propertyHash = property + "#" + property2;
- var comparator = this.propertyComparators[(isAscending ? 1 : 0)][propertyHash];
- if (!comparator) {
- comparator = function(lhs, rhs) {
- var l = lhs[property], r = rhs[property];
- if ((l === null || r === null) && property2 !== null)
- l = lhs[property2], r = rhs[property2];
- var result = l < r ? -1 : (l > r ? 1 : 0);
- return isAscending ? result : -result;
- };
- this.propertyComparators[(isAscending ? 1 : 0)][propertyHash] = comparator;
- }
- return comparator;
-};
-
-WebInspector.HeapSnapshotDataGridRetainerNode = function(snapshotView, baseEntry, snapshotEntry, owningTree)
-{
- this.snapshotView = snapshotView;
-
- if (!snapshotEntry)
- snapshotEntry = { cons: baseEntry.cons, count: 0, clusters: {} };
- this.constructorName = snapshotEntry.cons;
- this.count = snapshotEntry.count;
- this.retainers = this._calculateRetainers(this.snapshotView.profile, snapshotEntry.clusters);
-
- if (!baseEntry)
- baseEntry = { count: 0, clusters: {} };
- this.baseCount = baseEntry.count;
- this.countDelta = this.count - this.baseCount;
- this.baseRetainers = this._calculateRetainers(this.snapshotView.baseSnapshot, baseEntry.clusters);
-
- this.size = null;
- this.sizeDelta = null;
-
- WebInspector.HeapSnapshotDataGridNodeWithRetainers.call(this, owningTree);
-}
-
-WebInspector.HeapSnapshotDataGridRetainerNode.prototype = {
- get sizePercent()
- {
- return null;
- },
-
- get sizeDeltaPercent()
- {
- return null;
- },
-
- _calculateRetainers: function(snapshot, clusters) {
- var retainers = {};
- if (this.isEmptySet(clusters)) {
- if (this.constructorName in snapshot.entries)
- return snapshot.entries[this.constructorName].retainers;
- } else {
- // In case when an entry is retained by clusters, we need to gather up the list
- // of retainers by merging retainers of every cluster.
- // E.g. having such a tree:
- // A
- // Object:1 10
- // X 3
- // Y 4
- // Object:2 5
- // X 6
- //
- // will result in a following retainers list: X 9, Y 4.
- for (var clusterName in clusters) {
- if (clusterName in snapshot.clusters) {
- var clusterRetainers = snapshot.clusters[clusterName].retainers;
- for (var clusterRetainer in clusterRetainers) {
- var clusterRetainerEntry = clusterRetainers[clusterRetainer];
- if (!(clusterRetainer in retainers))
- retainers[clusterRetainer] = { cons: clusterRetainerEntry.cons, count: 0, clusters: {} };
- retainers[clusterRetainer].count += clusterRetainerEntry.count;
- for (var clusterRetainerCluster in clusterRetainerEntry.clusters)
- retainers[clusterRetainer].clusters[clusterRetainerCluster] = true;
- }
- }
- }
- }
- return retainers;
- }
-};
-
-WebInspector.HeapSnapshotDataGridRetainerNode.prototype.__proto__ = WebInspector.HeapSnapshotDataGridNodeWithRetainers.prototype;
-
-
-WebInspector.HeapSnapshotProfileType = function()
-{
- WebInspector.ProfileType.call(this, WebInspector.HeapSnapshotProfileType.TypeId, WebInspector.UIString("HEAP SNAPSHOTS"));
-}
-
-WebInspector.HeapSnapshotProfileType.TypeId = "HEAP";
-
-WebInspector.HeapSnapshotProfileType.snapshots = [];
-
-WebInspector.HeapSnapshotProfileType.prototype = {
- get buttonTooltip()
- {
- return WebInspector.UIString("Take heap snapshot.");
- },
-
- get buttonStyle()
- {
- return "heap-snapshot-status-bar-item status-bar-item";
- },
-
- buttonClicked: function()
- {
- devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT);
- },
-
- get welcomeMessage()
- {
- return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar.");
- },
-
- createSidebarTreeElementForProfile: function(profile)
- {
- var element = new WebInspector.HeapSnapshotSidebarTreeElement(profile);
- element.small = false;
- return element;
- },
-
- createView: function(profile)
- {
- return new WebInspector.HeapSnapshotView(WebInspector.panels.profiles, profile);
- }
-}
-
-WebInspector.HeapSnapshotProfileType.prototype.__proto__ = WebInspector.ProfileType.prototype;
-
-
-(function() {
- var originalCreatePanels = WebInspector._createPanels;
- WebInspector._createPanels = function() {
- originalCreatePanels.apply(this, arguments);
- if (WebInspector.panels.profiles)
- WebInspector.panels.profiles.registerProfileType(new WebInspector.HeapSnapshotProfileType());
- }
-})();
diff --git a/WebKit/chromium/src/js/ProfilerAgent.js b/WebKit/chromium/src/js/ProfilerAgent.js
deleted file mode 100644
index c993e62..0000000
--- a/WebKit/chromium/src/js/ProfilerAgent.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @fileoverview Provides communication interface to remote v8 profiler.
- */
-
-/**
- * @constructor
- */
-devtools.ProfilerAgent = function()
-{
-
- /**
- * Profiler log position.
- * @type {number}
- */
- this._logPosition = 0;
-
- /**
- * Last requested log position.
- * @type {number}
- */
- this._lastRequestedLogPosition = -1;
-
- /**
- * Profiler processor instance.
- * @type {devtools.profiler.Processor}
- */
- this._profilerProcessor = new devtools.profiler.Processor();
-};
-
-
-/**
- * A copy of enum from include/v8.h
- * @enum {number}
- */
-devtools.ProfilerAgent.ProfilerModules = {
- PROFILER_MODULE_NONE: 0,
- PROFILER_MODULE_CPU: 1,
- PROFILER_MODULE_HEAP_STATS: 1 << 1,
- PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2,
- PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16
-};
-
-
-/**
- * Initializes profiling state.
- */
-devtools.ProfilerAgent.prototype.initializeProfiling = function()
-{
- this._getNextLogLines(false);
-};
-
-
-/**
- * Requests the next chunk of log lines.
- * @param {boolean} immediately Do not postpone the request.
- * @private
- */
-devtools.ProfilerAgent.prototype._getNextLogLines = function(immediately)
-{
- if (this._lastRequestedLogPosition == this._logPosition)
- return;
- var pos = this._lastRequestedLogPosition = this._logPosition;
-
- if (immediately)
- InspectorBackend.getProfilerLogLines(pos, this._didGetProfilerLogLines.bind(this));
- else {
- function delayedRequest()
- {
- InspectorBackend.getProfilerLogLines(pos, this._didGetProfilerLogLines.bind(this));
- }
- setTimeout(delayedRequest, 500);
- }
-};
-
-
-/**
- * Starts profiling.
- * @param {number} modules List of modules to enable.
- */
-devtools.ProfilerAgent.prototype.startProfiling = function(modules)
-{
- if (modules & devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) {
- InspectorBackend.takeHeapSnapshot();
- // Active modules will not change, instead, a snapshot will be logged.
- this._getNextLogLines();
- }
-};
-
-
-/**
- * Handles a portion of a profiler log retrieved by getLogLines call.
- * @param {number} pos Current position in log.
- * @param {string} log A portion of profiler log.
- */
-devtools.ProfilerAgent.prototype._didGetProfilerLogLines = function(pos, log)
-{
- this._logPosition = pos;
- if (log.length > 0) {
- this._profilerProcessor.processLogChunk(log);
- this._getNextLogLines();
- } else {
- // Allow re-reading from the last position.
- this._lastRequestedLogPosition = this._logPosition - 1;
- }
-};
-
-WebInspector.didGetProfilerLogLines = WebInspector.Callback.processCallback;
diff --git a/WebKit/chromium/src/js/ProfilerProcessor.js b/WebKit/chromium/src/js/ProfilerProcessor.js
deleted file mode 100644
index 61714e8..0000000
--- a/WebKit/chromium/src/js/ProfilerProcessor.js
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @fileoverview Profiler processor is used to process log file produced
- * by V8 and produce an internal profile representation which is used
- * for building profile views in "Profiles" tab.
- */
-
-
-/**
- * Creates a Profile View builder object compatible with WebKit Profiler UI.
- *
- * @param {number} samplingRate Number of ms between profiler ticks.
- * @constructor
- */
-devtools.profiler.WebKitViewBuilder = function(samplingRate)
-{
- devtools.profiler.ViewBuilder.call(this, samplingRate);
-};
-devtools.profiler.WebKitViewBuilder.prototype.__proto__ = devtools.profiler.ViewBuilder.prototype;
-
-
-/**
- * @override
- */
-devtools.profiler.WebKitViewBuilder.prototype.createViewNode = function(funcName, totalTime, selfTime, head)
-{
- return new devtools.profiler.WebKitViewNode(funcName, totalTime, selfTime, head);
-};
-
-
-/**
- * Constructs a Profile View node object for displaying in WebKit Profiler UI.
- *
- * @param {string} internalFuncName A fully qualified function name.
- * @param {number} totalTime Amount of time that application spent in the
- * corresponding function and its descendants (not that depending on
- * profile they can be either callees or callers.)
- * @param {number} selfTime Amount of time that application spent in the
- * corresponding function only.
- * @param {devtools.profiler.ProfileView.Node} head Profile view head.
- * @constructor
- */
-devtools.profiler.WebKitViewNode = function(internalFuncName, totalTime, selfTime, head)
-{
- devtools.profiler.ProfileView.Node.call(this, internalFuncName, totalTime, selfTime, head);
- this.initFuncInfo_();
- this.callUID = internalFuncName;
-};
-devtools.profiler.WebKitViewNode.prototype.__proto__ = devtools.profiler.ProfileView.Node.prototype;
-
-
-/**
- * RegEx for stripping V8's prefixes of compiled functions.
- */
-devtools.profiler.WebKitViewNode.FUNC_NAME_STRIP_RE = /^(?:LazyCompile|Function|Callback): (.*)$/;
-
-
-/**
- * RegEx for extracting script source URL and line number.
- */
-devtools.profiler.WebKitViewNode.FUNC_NAME_PARSE_RE = /^((?:get | set )?[^ ]+) (.*):(\d+)( \{\d+\})?$/;
-
-
-/**
- * Inits "functionName", "url", and "lineNumber" fields using "internalFuncName"
- * field.
- * @private
- */
-devtools.profiler.WebKitViewNode.prototype.initFuncInfo_ = function()
-{
- var nodeAlias = devtools.profiler.WebKitViewNode;
- this.functionName = this.internalFuncName;
-
- var strippedName = nodeAlias.FUNC_NAME_STRIP_RE.exec(this.functionName);
- if (strippedName)
- this.functionName = strippedName[1];
-
- var parsedName = nodeAlias.FUNC_NAME_PARSE_RE.exec(this.functionName);
- if (parsedName) {
- this.functionName = parsedName[1];
- if (parsedName[4])
- this.functionName += parsedName[4];
- this.url = parsedName[2];
- this.lineNumber = parsedName[3];
- } else {
- this.url = '';
- this.lineNumber = 0;
- }
-};
-
-
-/**
- * Ancestor of a profile object that leaves out only JS-related functions.
- * @constructor
- */
-devtools.profiler.JsProfile = function()
-{
- devtools.profiler.Profile.call(this);
-};
-devtools.profiler.JsProfile.prototype.__proto__ = devtools.profiler.Profile.prototype;
-
-
-/**
- * RegExp that leaves only non-native JS functions.
- * @type {RegExp}
- */
-devtools.profiler.JsProfile.JS_NON_NATIVE_RE = new RegExp(
- "^" +
- "(?:Callback:)|" +
- "(?:Script: (?!native))|" +
- "(?:(?:LazyCompile|Function): [^ ]*(?: (?!native )[^ ]+:\\d+)?$)");
-
-
-/**
- * @override
- */
-devtools.profiler.JsProfile.prototype.skipThisFunction = function(name)
-{
- return !devtools.profiler.JsProfile.JS_NON_NATIVE_RE.test(name);
-};
-
-
-/**
- * Profiler processor. Consumes profiler log and builds profile views.
- * FIXME: change field naming style to use trailing underscore.
- *
- * @param {function(devtools.profiler.ProfileView)} newProfileCallback Callback
- * that receives a new processed profile.
- * @constructor
- */
-devtools.profiler.Processor = function()
-{
- var dispatches = {
- "code-creation": {
- parsers: [null, this.createAddressParser("code"), parseInt, null],
- processor: this.processCodeCreation_, backrefs: true,
- needsProfile: true },
- "code-move": { parsers: [this.createAddressParser("code"),
- this.createAddressParser("code-move-to")],
- processor: this.processCodeMove_, backrefs: true,
- needsProfile: true },
- "code-delete": { parsers: [this.createAddressParser("code")],
- processor: this.processCodeDelete_, backrefs: true,
- needsProfile: true },
- "function-creation": { parsers: [this.createAddressParser("code"),
- this.createAddressParser("function-obj")],
- processor: this.processFunctionCreation_, backrefs: true },
- "function-move": { parsers: [this.createAddressParser("code"),
- this.createAddressParser("code-move-to")],
- processor: this.processFunctionMove_, backrefs: true },
- "function-delete": { parsers: [this.createAddressParser("code")],
- processor: this.processFunctionDelete_, backrefs: true },
- "tick": { parsers: [this.createAddressParser("code"),
- this.createAddressParser("stack"), parseInt, "var-args"],
- processor: this.processTick_, backrefs: true, needProfile: true },
- "profiler": { parsers: [null, "var-args"],
- processor: this.processProfiler_, needsProfile: false },
- "heap-sample-begin": { parsers: [null, null, parseInt],
- processor: this.processHeapSampleBegin_ },
- "heap-sample-stats": { parsers: [null, null, parseInt, parseInt],
- processor: this.processHeapSampleStats_ },
- "heap-sample-item": { parsers: [null, parseInt, parseInt],
- processor: this.processHeapSampleItem_ },
- "heap-js-cons-item": { parsers: [null, parseInt, parseInt],
- processor: this.processHeapJsConsItem_ },
- "heap-js-ret-item": { parsers: [null, "var-args"],
- processor: this.processHeapJsRetItem_ },
- "heap-sample-end": { parsers: [null, null],
- processor: this.processHeapSampleEnd_ },
- // Not used in DevTools Profiler.
- "shared-library": null,
- // Obsolete row types.
- "code-allocate": null,
- "begin-code-region": null,
- "end-code-region": null};
-
- if (devtools.profiler.Profile.VERSION === 2) {
- dispatches["tick"] = { parsers: [this.createAddressParser("code"),
- this.createAddressParser("stack"),
- this.createAddressParser("func"), parseInt, "var-args"],
- processor: this.processTickV2_, backrefs: true };
- }
-
- devtools.profiler.LogReader.call(this, dispatches);
-
- /**
- * Callback that is called when a new profile is encountered in the log.
- * @type {function()}
- */
- this.startedProfileProcessing_ = null;
-
- /**
- * Callback that is called periodically to display processing status.
- * @type {function()}
- */
- this.profileProcessingStatus_ = null;
-
- /**
- * Callback that is called when a profile has been processed and is ready
- * to be shown.
- * @type {function(devtools.profiler.ProfileView)}
- */
- this.finishedProfileProcessing_ = null;
-
- /**
- * The current profile.
- * @type {devtools.profiler.JsProfile}
- */
- this.currentProfile_ = null;
-
- /**
- * Builder of profile views. Created during "profiler,begin" event processing.
- * @type {devtools.profiler.WebKitViewBuilder}
- */
- this.viewBuilder_ = null;
-
- /**
- * Next profile id.
- * @type {number}
- */
- this.profileId_ = 1;
-
- /**
- * Counter for processed ticks.
- * @type {number}
- */
- this.ticksCount_ = 0;
-
- /**
- * Interval id for updating processing status.
- * @type {number}
- */
- this.processingInterval_ = null;
-
- /**
- * The current heap snapshot.
- * @type {string}
- */
- this.currentHeapSnapshot_ = null;
-
- /**
- * Next heap snapshot id.
- * @type {number}
- */
- this.heapSnapshotId_ = 1;
-};
-devtools.profiler.Processor.prototype.__proto__ = devtools.profiler.LogReader.prototype;
-
-
-/**
- * @override
- */
-devtools.profiler.Processor.prototype.printError = function(str)
-{
- WebInspector.log(str);
-};
-
-
-/**
- * @override
- */
-devtools.profiler.Processor.prototype.skipDispatch = function(dispatch)
-{
- return dispatch.needsProfile && this.currentProfile_ === null;
-};
-
-
-/**
- * Sets profile processing callbacks.
- *
- * @param {function()} started Started processing callback.
- * @param {function(devtools.profiler.ProfileView)} finished Finished
- * processing callback.
- */
-devtools.profiler.Processor.prototype.setCallbacks = function(started, processing, finished)
-{
- this.startedProfileProcessing_ = started;
- this.profileProcessingStatus_ = processing;
- this.finishedProfileProcessing_ = finished;
-};
-
-
-/**
- * An address for the fake "(program)" entry. WebKit's visualisation
- * has assumptions on how the top of the call tree should look like,
- * and we need to add a fake entry as the topmost function. This
- * address is chosen because it's the end address of the first memory
- * page, which is never used for code or data, but only as a guard
- * page for catching AV errors.
- *
- * @type {number}
- */
-devtools.profiler.Processor.PROGRAM_ENTRY = 0xffff;
-/**
- * @type {string}
- */
-devtools.profiler.Processor.PROGRAM_ENTRY_STR = "0xffff";
-
-
-/**
- * Sets new profile callback.
- * @param {function(devtools.profiler.ProfileView)} callback Callback function.
- */
-devtools.profiler.Processor.prototype.setNewProfileCallback = function(callback)
-{
- this.newProfileCallback_ = callback;
-};
-
-
-devtools.profiler.Processor.prototype.processProfiler_ = function(state, params)
-{
- switch (state) {
- case "resume":
- if (this.currentProfile_ === null) {
- this.currentProfile_ = new devtools.profiler.JsProfile();
- // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY
- this.currentProfile_.addCode("Function", "(program)", devtools.profiler.Processor.PROGRAM_ENTRY, 1);
- if (this.startedProfileProcessing_)
- this.startedProfileProcessing_();
- this.ticksCount_ = 0;
- var self = this;
- if (this.profileProcessingStatus_) {
- this.processingInterval_ = window.setInterval(
- function() { self.profileProcessingStatus_(self.ticksCount_); },
- 1000);
- }
- }
- break;
- case "pause":
- if (this.currentProfile_ !== null) {
- window.clearInterval(this.processingInterval_);
- this.processingInterval_ = null;
- if (this.finishedProfileProcessing_)
- this.finishedProfileProcessing_(this.createProfileForView());
- this.currentProfile_ = null;
- }
- break;
- case "begin":
- var samplingRate = NaN;
- if (params.length > 0)
- samplingRate = parseInt(params[0]);
- if (isNaN(samplingRate))
- samplingRate = 1;
- this.viewBuilder_ = new devtools.profiler.WebKitViewBuilder(samplingRate);
- break;
- // These events are valid but aren't used.
- case "compression":
- case "end": break;
- default:
- throw new Error("unknown profiler state: " + state);
- }
-};
-
-
-devtools.profiler.Processor.prototype.processCodeCreation_ = function(type, start, size, name)
-{
- this.currentProfile_.addCode(this.expandAlias(type), name, start, size);
-};
-
-
-devtools.profiler.Processor.prototype.processCodeMove_ = function(from, to)
-{
- this.currentProfile_.moveCode(from, to);
-};
-
-
-devtools.profiler.Processor.prototype.processCodeDelete_ = function(start)
-{
- this.currentProfile_.deleteCode(start);
-};
-
-
-devtools.profiler.Processor.prototype.processFunctionCreation_ = function(functionAddr, codeAddr)
-{
- this.currentProfile_.addCodeAlias(functionAddr, codeAddr);
-};
-
-
-devtools.profiler.Processor.prototype.processFunctionMove_ = function(from, to)
-{
- this.currentProfile_.safeMoveDynamicCode(from, to);
-};
-
-
-devtools.profiler.Processor.prototype.processFunctionDelete_ = function(start)
-{
- this.currentProfile_.safeDeleteDynamicCode(start);
-};
-
-
-// TODO(mnaganov): Remove after next V8 roll.
-devtools.profiler.Processor.prototype.processTick_ = function(pc, sp, vmState, stack)
-{
- // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY
- stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR);
- this.currentProfile_.recordTick(this.processStack(pc, stack));
- this.ticksCount_++;
-};
-
-
-devtools.profiler.Processor.prototype.processTickV2_ = function(pc, sp, func, vmState, stack)
-{
- // see the comment for devtools.profiler.Processor.PROGRAM_ENTRY
- stack.push(devtools.profiler.Processor.PROGRAM_ENTRY_STR);
-
-
- if (func) {
- var funcEntry = this.currentProfile_.findEntry(func);
- if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction())
- func = 0;
- else {
- var currEntry = this.currentProfile_.findEntry(pc);
- if (!currEntry || !currEntry.isJSFunction || currEntry.isJSFunction()) {
- func = 0;
- }
- }
- }
-
- this.currentProfile_.recordTick(this.processStack(pc, func, stack));
- this.ticksCount_++;
-};
-
-
-devtools.profiler.Processor.prototype.processHeapSampleBegin_ = function(space, state, ticks)
-{
- if (space !== "Heap") return;
- this.currentHeapSnapshot_ = {
- number: this.heapSnapshotId_++,
- entries: {},
- clusters: {},
- lowlevels: {},
- ticks: ticks
- };
-};
-
-
-devtools.profiler.Processor.prototype.processHeapSampleStats_ = function(space, state, capacity, used)
-{
- if (space !== "Heap") return;
-};
-
-
-devtools.profiler.Processor.prototype.processHeapSampleItem_ = function(item, number, size)
-{
- if (!this.currentHeapSnapshot_) return;
- this.currentHeapSnapshot_.lowlevels[item] = {
- type: item, count: number, size: size
- };
-};
-
-
-devtools.profiler.Processor.prototype.processHeapJsConsItem_ = function(item, number, size)
-{
- if (!this.currentHeapSnapshot_) return;
- this.currentHeapSnapshot_.entries[item] = {
- cons: item, count: number, size: size, retainers: {}
- };
-};
-
-
-devtools.profiler.Processor.prototype.processHeapJsRetItem_ = function(item, retainersArray)
-{
- if (!this.currentHeapSnapshot_) return;
- var rawRetainers = {};
- for (var i = 0, n = retainersArray.length; i < n; ++i) {
- var entry = retainersArray[i].split(";");
- rawRetainers[entry[0]] = parseInt(entry[1], 10);
- }
-
- function mergeRetainers(entry) {
- for (var rawRetainer in rawRetainers) {
- var consName = rawRetainer.indexOf(":") !== -1 ? rawRetainer.split(":")[0] : rawRetainer;
- if (!(consName in entry.retainers))
- entry.retainers[consName] = { cons: consName, count: 0, clusters: {} };
- var retainer = entry.retainers[consName];
- retainer.count += rawRetainers[rawRetainer];
- if (consName !== rawRetainer)
- retainer.clusters[rawRetainer] = true;
- }
- }
-
- if (item.indexOf(":") !== -1) {
- // Array, Function, or Object instances cluster case.
- if (!(item in this.currentHeapSnapshot_.clusters)) {
- this.currentHeapSnapshot_.clusters[item] = {
- cons: item, retainers: {}
- };
- }
- mergeRetainers(this.currentHeapSnapshot_.clusters[item]);
- item = item.split(":")[0];
- }
- mergeRetainers(this.currentHeapSnapshot_.entries[item]);
-};
-
-
-devtools.profiler.Processor.prototype.processHeapSampleEnd_ = function(space, state)
-{
- if (space !== "Heap") return;
- var snapshot = this.currentHeapSnapshot_;
- this.currentHeapSnapshot_ = null;
- WebInspector.panels.profiles.addSnapshot(snapshot);
-};
-
-
-/**
- * Creates a profile for further displaying in ProfileView.
- */
-devtools.profiler.Processor.prototype.createProfileForView = function()
-{
- var profile = this.viewBuilder_.buildView(this.currentProfile_.getTopDownProfile());
- profile.uid = this.profileId_++;
- profile.title = UserInitiatedProfileName + "." + profile.uid;
- return profile;
-};
diff --git a/WebKit/chromium/src/js/devTools.css b/WebKit/chromium/src/js/devTools.css
index dfcaadf..9495fb8 100755
--- a/WebKit/chromium/src/js/devTools.css
+++ b/WebKit/chromium/src/js/devTools.css
@@ -37,118 +37,6 @@ body.platform-linux #scripts-files {
line-height: 12px;
}
-/* Heap Profiler Styles */
-
-.heap-snapshot-status-bar-item .glyph {
- -webkit-mask-image: url(Images/focusButtonGlyph.png);
-}
-
-.heap-snapshot-sidebar-tree-item .icon {
- content: url(Images/profileIcon.png);
-}
-
-.heap-snapshot-sidebar-tree-item.small .icon {
- content: url(Images/profileSmallIcon.png);
-}
-
-.heap-snapshot-view {
- display: none;
- overflow: hidden;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
-}
-
-.heap-snapshot-view.visible {
- display: block;
-}
-
-.heap-snapshot-view .data-grid {
- border: none;
- max-height: 100%;
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 93px;
-}
-
-.heap-snapshot-view .data-grid th.count-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.count-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid th.size-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.size-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid th.countDelta-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.countDelta-column {
- text-align: right;
-}
-
-.heap-snapshot-view .data-grid th.sizeDelta-column {
- text-align: center;
-}
-
-.heap-snapshot-view .data-grid td.sizeDelta-column {
- text-align: right;
-}
-
-#heap-snapshot-summary-container {
- position: absolute;
- padding-top: 20px;
- bottom: 0;
- left: 0;
- right: 0;
- height: 93px;
- margin-left: -1px;
- border-left: 1px solid rgb(102, 102, 102);
- background-color: rgb(101, 111, 130);
- background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0)));
- background-repeat: repeat-x;
- background-position: top;
- text-align: center;
- text-shadow: black 0 1px 1px;
- white-space: nowrap;
- color: white;
- -webkit-background-size: 1px 6px;
- -webkit-background-origin: padding;
- -webkit-background-clip: padding;
-}
-
-.heap-snapshot-summary {
- display: inline-block;
- width: 50%;
- min-width: 300px;
- position: relative;
-}
-
-.heap-snapshot-summary canvas.summary-graph {
- width: 225px;
-}
-
-.heap-snapshot-summary-label {
- font-size: 12px;
- font-weight: bold;
- position: absolute;
- top: 1px;
- width: 50%;
- left: 25%;
-}
-
.section > .header {
border: 1px solid rgb(92, 116, 157);
background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(105, 133, 180)), to(rgb(92, 116, 157)));
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list