Web Inspector: Move profiler tools into separate panels
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2013 14:43:48 +0000 (14:43 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2013 14:43:48 +0000 (14:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109832

Patch by Alexei Filippov <alph@chromium.org> on 2013-02-28
Reviewed by Yury Semikhatsky.

This is a first part of the fix that puts each profiler tool into a separate panel.
The fix introduces separate panels for each profiler type.
There are now six panel (including experimental):
  1. JS CPU profiler
  2. CSS Selector profiler
  3. JS Heap profiler
  4. Canvas profier
  5. Native memory snapshots
  6. Native memory distribution
The new functionality is put behind experimental flag.

* inspector/front-end/ProfileLauncherView.js:
(WebInspector.ProfileLauncherView):
(WebInspector.ProfileLauncherView.prototype.addProfileType):
* inspector/front-end/ProfilesPanel.js:
(WebInspector.ProfileHeader.prototype.view):
(WebInspector.ProfileHeader.prototype.createView):
(WebInspector.ProfilesPanel):
(WebInspector.ProfilesPanel.prototype._handleContextMenuEvent):
(WebInspector.ProfilesPanel.prototype._addProfileHeader):
(WebInspector.ProfilesPanel.prototype._removeProfileHeader):
(WebInspector.ProfilesPanel.prototype._showProfile):
(WebInspector.ProfilesPanel.prototype._searchableViews):
(WebInspector.ProfileSidebarTreeElement.prototype.handleContextMenuEvent):
(WebInspector.ProfileGroupSidebarTreeElement):
(WebInspector.ProfileGroupSidebarTreeElement.prototype.onselect):
(WebInspector.CPUProfilerPanel):
(WebInspector.CSSSelectorProfilerPanel):
(WebInspector.HeapProfilerPanel):
(WebInspector.CanvasProfilerPanel):
(WebInspector.MemoryChartProfilerPanel):
(WebInspector.NativeMemoryProfilerPanel):
* inspector/front-end/Settings.js:
(WebInspector.ExperimentsSettings):
* inspector/front-end/inspector.css:
(.toolbar-item.cpu-profiler .toolbar-icon):
(.toolbar-item.css-profiler .toolbar-icon):
(.toolbar-item.heap-profiler .toolbar-icon):
(.toolbar-item.canvas-profiler .toolbar-icon):
(.toolbar-item.memory-chart-profiler .toolbar-icon):
(.toolbar-item.memory-snapshot-profiler .toolbar-icon):
* inspector/front-end/inspector.js:
(WebInspector._panelDescriptors):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@144304 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/inspector/front-end/ProfileLauncherView.js
Source/WebCore/inspector/front-end/ProfilesPanel.js
Source/WebCore/inspector/front-end/Settings.js
Source/WebCore/inspector/front-end/inspector.css
Source/WebCore/inspector/front-end/inspector.js

index 3c98065..394b05e 100644 (file)
@@ -1,3 +1,54 @@
+2013-02-28  Alexei Filippov  <alph@chromium.org>
+
+        Web Inspector: Move profiler tools into separate panels
+        https://bugs.webkit.org/show_bug.cgi?id=109832
+
+        Reviewed by Yury Semikhatsky.
+
+        This is a first part of the fix that puts each profiler tool into a separate panel.
+        The fix introduces separate panels for each profiler type.
+        There are now six panel (including experimental):
+          1. JS CPU profiler
+          2. CSS Selector profiler
+          3. JS Heap profiler
+          4. Canvas profier
+          5. Native memory snapshots
+          6. Native memory distribution
+        The new functionality is put behind experimental flag.
+
+        * inspector/front-end/ProfileLauncherView.js:
+        (WebInspector.ProfileLauncherView):
+        (WebInspector.ProfileLauncherView.prototype.addProfileType):
+        * inspector/front-end/ProfilesPanel.js:
+        (WebInspector.ProfileHeader.prototype.view):
+        (WebInspector.ProfileHeader.prototype.createView):
+        (WebInspector.ProfilesPanel):
+        (WebInspector.ProfilesPanel.prototype._handleContextMenuEvent):
+        (WebInspector.ProfilesPanel.prototype._addProfileHeader):
+        (WebInspector.ProfilesPanel.prototype._removeProfileHeader):
+        (WebInspector.ProfilesPanel.prototype._showProfile):
+        (WebInspector.ProfilesPanel.prototype._searchableViews):
+        (WebInspector.ProfileSidebarTreeElement.prototype.handleContextMenuEvent):
+        (WebInspector.ProfileGroupSidebarTreeElement):
+        (WebInspector.ProfileGroupSidebarTreeElement.prototype.onselect):
+        (WebInspector.CPUProfilerPanel):
+        (WebInspector.CSSSelectorProfilerPanel):
+        (WebInspector.HeapProfilerPanel):
+        (WebInspector.CanvasProfilerPanel):
+        (WebInspector.MemoryChartProfilerPanel):
+        (WebInspector.NativeMemoryProfilerPanel):
+        * inspector/front-end/Settings.js:
+        (WebInspector.ExperimentsSettings):
+        * inspector/front-end/inspector.css:
+        (.toolbar-item.cpu-profiler .toolbar-icon):
+        (.toolbar-item.css-profiler .toolbar-icon):
+        (.toolbar-item.heap-profiler .toolbar-icon):
+        (.toolbar-item.canvas-profiler .toolbar-icon):
+        (.toolbar-item.memory-chart-profiler .toolbar-icon):
+        (.toolbar-item.memory-snapshot-profiler .toolbar-icon):
+        * inspector/front-end/inspector.js:
+        (WebInspector._panelDescriptors):
+
 2013-02-28  Keishi Hattori  <keishi@webkit.org>
 
         Add calendar header for new calendar picker
index c85c0b3..a22dad1 100644 (file)
 /**
  * @constructor
  * @extends {WebInspector.View}
+ * @param {!WebInspector.ProfilesPanel} profilesPanel
+ * @param {boolean} singleProfileMode
  */
-WebInspector.ProfileLauncherView = function(profilesPanel)
+WebInspector.ProfileLauncherView = function(profilesPanel, singleProfileMode)
 {
     WebInspector.View.call(this);
 
     this._panel = profilesPanel;
+    this._singleProfileMode = singleProfileMode;
     this._profileRunning = false;
 
     this.element.addStyleClass("profile-launcher-view");
@@ -44,8 +47,10 @@ WebInspector.ProfileLauncherView = function(profilesPanel)
 
     this._contentElement = this.element.createChild("div", "profile-launcher-view-content");
 
-    var header = this._contentElement.createChild("h1");
-    header.textContent = WebInspector.UIString("Select profiling type");
+    if (!singleProfileMode) {
+        var header = this._contentElement.createChild("h1");
+        header.textContent = WebInspector.UIString("Select profiling type");
+    }
 
     this._profileTypeSelectorForm = this._contentElement.createChild("form");
 
@@ -73,22 +78,30 @@ WebInspector.ProfileLauncherView.prototype = {
     addProfileType: function(profileType)
     {
         var checked = !this._profileTypeSelectorForm.children.length;
-        var labelElement = this._profileTypeSelectorForm.createChild("label");
-        labelElement.textContent = profileType.name;
-        var optionElement = document.createElement("input");
-        labelElement.insertBefore(optionElement, labelElement.firstChild);
-        optionElement.type = "radio";
-        optionElement.name = "profile-type";
-        if (checked) {
-            optionElement.checked = checked;
-            this.dispatchEventToListeners(WebInspector.ProfileLauncherView.EventTypes.ProfileTypeSelected, profileType);
+        var labelElement;
+        if (this._singleProfileMode)
+            labelElement = this._profileTypeSelectorForm.createChild("h1");
+        else {
+            labelElement = this._profileTypeSelectorForm.createChild("label");
+            labelElement.textContent = profileType.name;
+            var optionElement = document.createElement("input");
+            labelElement.insertBefore(optionElement, labelElement.firstChild);
+            optionElement.type = "radio";
+            optionElement.name = "profile-type";
+            optionElement.style.hidden = true;
+            if (checked) {
+                optionElement.checked = checked;
+                this.dispatchEventToListeners(WebInspector.ProfileLauncherView.EventTypes.ProfileTypeSelected, profileType);
+            }
+            optionElement.addEventListener("change", this._profileTypeChanged.bind(this, profileType), false);
         }
-        optionElement.addEventListener("change", this._profileTypeChanged.bind(this, profileType), false);
         var descriptionElement = labelElement.createChild("p");
         descriptionElement.textContent = profileType.description;
         var decorationElement = profileType.decorationElement();
         if (decorationElement)
             labelElement.appendChild(decorationElement);
+        if (this._singleProfileMode)
+            this._profileTypeChanged(profileType);
     },
 
     _controlButtonClicked: function()
index b50a4f2..930062e 100644 (file)
@@ -268,20 +268,21 @@ WebInspector.ProfileHeader.prototype = {
     },
 
     /**
+     * @param {!WebInspector.ProfilesPanel} panel
      * @return {!WebInspector.View}
      */
-    view: function()
+    view: function(panel)
     {
         if (!this._view)
-            this._view = this.createView(WebInspector.ProfilesPanel._instance);
+            this._view = this.createView(panel);
         return this._view;
     },
 
     /**
-     * @param {WebInspector.ProfilesPanel} profilesPanel
+     * @param {!WebInspector.ProfilesPanel} panel
      * @return {!WebInspector.View}
      */
-    createView: function(profilesPanel)
+    createView: function(panel)
     {
         throw new Error("Not implemented.");
     },
@@ -331,11 +332,14 @@ WebInspector.ProfileHeader.prototype = {
  * @constructor
  * @extends {WebInspector.Panel}
  * @implements {WebInspector.ContextMenu.Provider}
+ * @param {string=} name
  */
-WebInspector.ProfilesPanel = function()
+WebInspector.ProfilesPanel = function(name)
 {
-    WebInspector.Panel.call(this, "profiles");
-    WebInspector.ProfilesPanel._instance = this;
+    // If the name is not specified the ProfilesPanel works in multi-profile mode.
+    var singleProfileMode = typeof name !== "undefined";
+    name = name || "profiles";
+    WebInspector.Panel.call(this, name);
     this.registerRequiredCSS("panelEnablerView.css");
     this.registerRequiredCSS("heapProfiler.css");
     this.registerRequiredCSS("profilesPanel.css");
@@ -345,12 +349,13 @@ WebInspector.ProfilesPanel = function()
     this.profilesItemTreeElement = new WebInspector.ProfilesSidebarTreeElement(this);
     this.sidebarTree.appendChild(this.profilesItemTreeElement);
 
+    this._singleProfileMode = singleProfileMode;
     this._profileTypesByIdMap = {};
 
     var panelEnablerHeading = WebInspector.UIString("You need to enable profiling before you can use the Profiles panel.");
     var panelEnablerDisclaimer = WebInspector.UIString("Enabling profiling will make scripts run slower.");
     var panelEnablerButton = WebInspector.UIString("Enable Profiling");
-    this.panelEnablerView = new WebInspector.PanelEnablerView("profiles", panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
+    this.panelEnablerView = new WebInspector.PanelEnablerView(name, panelEnablerHeading, panelEnablerDisclaimer, panelEnablerButton);
     this.panelEnablerView.addEventListener("enable clicked", this.enableProfiler, this);
 
     this.profileViews = document.createElement("div");
@@ -386,21 +391,23 @@ WebInspector.ProfilesPanel = function()
 
     this._profilerEnabled = !Capabilities.profilerCausesRecompilation;
 
-    this._launcherView = new WebInspector.ProfileLauncherView(this);
+    this._launcherView = new WebInspector.ProfileLauncherView(this, singleProfileMode);
     this._launcherView.addEventListener(WebInspector.ProfileLauncherView.EventTypes.ProfileTypeSelected, this._onProfileTypeSelected, this);
     this._reset();
 
-    this._registerProfileType(new WebInspector.CPUProfileType());
-    if (!WebInspector.WorkerManager.isWorkerFrontend())
-        this._registerProfileType(new WebInspector.CSSSelectorProfileType());
-    if (Capabilities.heapProfilerPresent)
-        this._registerProfileType(new WebInspector.HeapSnapshotProfileType());
-    if (WebInspector.experimentsSettings.nativeMemorySnapshots.isEnabled()) {
-        this._registerProfileType(new WebInspector.NativeMemoryProfileType());
-        this._registerProfileType(new WebInspector.NativeSnapshotProfileType());
+    if (!singleProfileMode) {
+        this._registerProfileType(new WebInspector.CPUProfileType());
+        if (!WebInspector.WorkerManager.isWorkerFrontend())
+            this._registerProfileType(new WebInspector.CSSSelectorProfileType());
+        if (Capabilities.heapProfilerPresent)
+            this._registerProfileType(new WebInspector.HeapSnapshotProfileType());
+        if (WebInspector.experimentsSettings.nativeMemorySnapshots.isEnabled()) {
+            this._registerProfileType(new WebInspector.NativeSnapshotProfileType());
+            this._registerProfileType(new WebInspector.NativeMemoryProfileType());
+        }
+        if (WebInspector.experimentsSettings.canvasInspection.isEnabled())
+            this._registerProfileType(new WebInspector.CanvasProfileType());
     }
-    if (WebInspector.experimentsSettings.canvasInspection.isEnabled())
-        this._registerProfileType(new WebInspector.CanvasProfileType());
 
     this._createFileSelectorElement();
     this.element.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
@@ -569,7 +576,7 @@ WebInspector.ProfilesPanel.prototype = {
         this._profileTypesByIdMap[profileType.id] = profileType;
         this._launcherView.addProfileType(profileType);
         profileType.treeElement = new WebInspector.SidebarSectionTreeElement(profileType.treeItemTitle, null, true);
-        profileType.treeElement.hidden = true;
+        profileType.treeElement.hidden = !this._singleProfileMode;
         this.sidebarTree.appendChild(profileType.treeElement);
         profileType.treeElement.childrenListElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), true);
         function onAddProfileHeader(event)
@@ -601,7 +608,7 @@ WebInspector.ProfilesPanel.prototype = {
         if (!element)
             return;
         if (element.treeElement && element.treeElement.handleContextMenuEvent) {
-            element.treeElement.handleContextMenuEvent(event);
+            element.treeElement.handleContextMenuEvent(event, this);
             return;
         }
         if (element !== this.element || event.srcElement === this.sidebarElement) {
@@ -649,7 +656,7 @@ WebInspector.ProfilesPanel.prototype = {
             group.push(profile);
             if (group.length === 2) {
                 // Make a group TreeElement now that there are 2 profiles.
-                group._profilesTreeElement = new WebInspector.ProfileGroupSidebarTreeElement(profile.title);
+                group._profilesTreeElement = new WebInspector.ProfileGroupSidebarTreeElement(this, profile.title);
 
                 // Insert at the same index for the first profile of the group.
                 var index = sidebarParent.children.indexOf(group[0]._profilesTreeElement);
@@ -725,7 +732,7 @@ WebInspector.ProfilesPanel.prototype = {
         if (!sidebarParent.children.length) {
             this.profilesItemTreeElement.select();
             this._showLauncherView();
-            sidebarParent.hidden = true;
+            sidebarParent.hidden = !this._singleProfileMode;
         }
     },
 
@@ -737,7 +744,7 @@ WebInspector.ProfilesPanel.prototype = {
         if (!profile || profile.isTemporary)
             return;
 
-        var view = profile.view();
+        var view = profile.view(this);
         if (view === this.visibleView)
             return;
 
@@ -771,8 +778,9 @@ WebInspector.ProfilesPanel.prototype = {
             // FIXME: allow to choose snapshot if there are several options.
             if (profile.maxJSObjectId >= snapshotObjectId) {
                 this._showProfile(profile);
-                profile.view().changeView(viewName, function() {
-                    profile.view().dataGrid.highlightObjectByHeapSnapshotId(snapshotObjectId);
+                var view = profile.view(this);
+                view.changeView(viewName, function() {
+                    view.dataGrid.highlightObjectByHeapSnapshotId(snapshotObjectId);
                 });
                 break;
             }
@@ -1007,7 +1015,7 @@ WebInspector.ProfilesPanel.prototype = {
         var profiles = this._getAllProfiles();
         var searchableViews = [];
         for (var i = 0; i < profiles.length; ++i) {
-            var view = profiles[i].view();
+            var view = profiles[i].view(this);
             if (view.performSearch)
                 searchableViews.push(view)
         }
@@ -1267,19 +1275,19 @@ WebInspector.ProfileSidebarTreeElement.prototype = {
 
     /**
      * @param {!Event} event
+     * @param {!WebInspector.ProfilesPanel} panel
      */
-    handleContextMenuEvent: function(event)
+    handleContextMenuEvent: function(event, panel)
     {
         var profile = this.profile;
         var contextMenu = new WebInspector.ContextMenu(event);
-        var profilesPanel = WebInspector.ProfilesPanel._instance;
         // FIXME: use context menu provider
         if (profile.canSaveToFile()) {
             contextMenu.appendItem(WebInspector.UIString("Save Heap Snapshot\u2026"), profile.saveToFile.bind(profile));
-            contextMenu.appendItem(WebInspector.UIString("Load Heap Snapshot\u2026"), profilesPanel._fileSelectorElement.click.bind(profilesPanel._fileSelectorElement));
+            contextMenu.appendItem(WebInspector.UIString("Load Heap Snapshot\u2026"), panel._fileSelectorElement.click.bind(panel._fileSelectorElement));
             contextMenu.appendItem(WebInspector.UIString("Delete Heap Snapshot"), this.ondelete.bind(this));
         } else {
-            contextMenu.appendItem(WebInspector.UIString("Load Heap Snapshot\u2026"), profilesPanel._fileSelectorElement.click.bind(profilesPanel._fileSelectorElement));
+            contextMenu.appendItem(WebInspector.UIString("Load Heap Snapshot\u2026"), panel._fileSelectorElement.click.bind(panel._fileSelectorElement));
             contextMenu.appendItem(WebInspector.UIString("Delete profile"), this.ondelete.bind(this));
         }
         contextMenu.show();
@@ -1291,19 +1299,21 @@ WebInspector.ProfileSidebarTreeElement.prototype = {
 /**
  * @constructor
  * @extends {WebInspector.SidebarTreeElement}
+ * @param {WebInspector.ProfilesPanel} panel
  * @param {string} title
  * @param {string=} subtitle
  */
-WebInspector.ProfileGroupSidebarTreeElement = function(title, subtitle)
+WebInspector.ProfileGroupSidebarTreeElement = function(panel, title, subtitle)
 {
     WebInspector.SidebarTreeElement.call(this, "profile-group-sidebar-tree-item", title, subtitle, null, true);
+    this._panel = panel;
 }
 
 WebInspector.ProfileGroupSidebarTreeElement.prototype = {
     onselect: function()
     {
         if (this.children.length > 0)
-            WebInspector.ProfilesPanel._instance._showProfile(this.children[this.children.length - 1].profile);
+            this._panel._showProfile(this.children[this.children.length - 1].profile);
     },
 
     __proto__: WebInspector.SidebarTreeElement.prototype
@@ -1336,6 +1346,85 @@ WebInspector.ProfilesSidebarTreeElement.prototype = {
     __proto__: WebInspector.SidebarTreeElement.prototype
 }
 
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfilesPanel}
+ */
+WebInspector.CPUProfilerPanel = function()
+{
+    WebInspector.ProfilesPanel.call(this, "cpu-profiler");
+    this._registerProfileType(new WebInspector.CPUProfileType());
+}
+
+WebInspector.CPUProfilerPanel.prototype.__proto__ = WebInspector.ProfilesPanel.prototype;
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfilesPanel}
+ */
+WebInspector.CSSSelectorProfilerPanel = function()
+{
+    WebInspector.ProfilesPanel.call(this, "css-profiler");
+    this._registerProfileType(new WebInspector.CSSSelectorProfileType());
+}
+
+WebInspector.CSSSelectorProfilerPanel.prototype.__proto__ = WebInspector.ProfilesPanel.prototype;
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfilesPanel}
+ */
+WebInspector.HeapProfilerPanel = function()
+{
+    WebInspector.ProfilesPanel.call(this, "heap-profiler");
+    this._registerProfileType(new WebInspector.HeapSnapshotProfileType());
+}
+
+WebInspector.HeapProfilerPanel.prototype.__proto__ = WebInspector.ProfilesPanel.prototype;
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfilesPanel}
+ */
+WebInspector.CanvasProfilerPanel = function()
+{
+    WebInspector.ProfilesPanel.call(this, "canvas-profiler");
+    this._registerProfileType(new WebInspector.CanvasProfileType());
+}
+
+WebInspector.CanvasProfilerPanel.prototype.__proto__ = WebInspector.ProfilesPanel.prototype;
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfilesPanel}
+ */
+WebInspector.MemoryChartProfilerPanel = function()
+{
+    WebInspector.ProfilesPanel.call(this, "memory-chart-profiler");
+    this._registerProfileType(new WebInspector.NativeMemoryProfileType());
+}
+
+WebInspector.MemoryChartProfilerPanel.prototype.__proto__ = WebInspector.ProfilesPanel.prototype;
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.ProfilesPanel}
+ */
+WebInspector.NativeMemoryProfilerPanel = function()
+{
+    WebInspector.ProfilesPanel.call(this, "memory-snapshot-profiler");
+    this._registerProfileType(new WebInspector.NativeSnapshotProfileType());
+}
+
+WebInspector.NativeMemoryProfilerPanel.prototype.__proto__ = WebInspector.ProfilesPanel.prototype;
+
+
 importScript("ProfileDataGridTree.js");
 importScript("BottomUpProfileDataGridTree.js");
 importScript("CPUProfileView.js");
index 1e5e287..ad6985d 100644 (file)
@@ -215,6 +215,7 @@ WebInspector.ExperimentsSettings = function()
     this.fileSystemProject = this._createExperiment("fileSystemProject", "File system folders in Sources Panel");
     this.showWhitespaceInEditor = this._createExperiment("showWhitespaceInEditor", "Show whitespace characters in editor");
     this.textEditorSmartBraces = this._createExperiment("textEditorSmartBraces", "Enable smart braces in text editor");
+    this.separateProfilers = this._createExperiment("separateProfilers", "Separate profiler tools");
 
     this._cleanUpSetting();
 }
index 2245364..1f0ac5e 100644 (file)
@@ -475,6 +475,30 @@ body.dock-to-bottom .toolbar-item.timeline .toolbar-icon {
     background-position-x: -160px;
 }
 
+.toolbar-item.cpu-profiler .toolbar-icon {
+    background-position-x: -160px;
+}
+
+.toolbar-item.css-profiler .toolbar-icon {
+    background-position-x: -160px;
+}
+
+.toolbar-item.heap-profiler .toolbar-icon {
+    background-position-x: -160px;
+}
+
+.toolbar-item.canvas-profiler .toolbar-icon {
+    background-position-x: -160px;
+}
+
+.toolbar-item.memory-chart-profiler .toolbar-icon {
+    background-position-x: -160px;
+}
+
+.toolbar-item.memory-snapshot-profiler .toolbar-icon {
+    background-position-x: -160px;
+}
+
 body.dock-to-bottom .toolbar-item.profiles .toolbar-icon {
     background-position-x: -120px;
 }
index 14c8cdb..e2c0cca 100644 (file)
@@ -46,12 +46,28 @@ var WebInspector = {
         var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js");
         var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel");
         var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
+        var allProfilers = [profiles];
+        if (WebInspector.experimentsSettings.separateProfilers.isEnabled()) {
+            allProfilers = [];
+            allProfilers.push(new WebInspector.PanelDescriptor("cpu-profiler", WebInspector.UIString("CPU Profiler"), "CPUProfilerPanel", "ProfilesPanel.js"));
+            if (!WebInspector.WorkerManager.isWorkerFrontend())
+                allProfilers.push(new WebInspector.PanelDescriptor("css-profiler", WebInspector.UIString("CSS Profiler"), "CSSSelectorProfilerPanel", "ProfilesPanel.js"));
+            if (Capabilities.heapProfilerPresent)
+                allProfilers.push(new WebInspector.PanelDescriptor("heap-profiler", WebInspector.UIString("Heap Profiler"), "HeapProfilerPanel", "ProfilesPanel.js"));
+            if (!WebInspector.WorkerManager.isWorkerFrontend() && WebInspector.experimentsSettings.canvasInspection.isEnabled())
+                allProfilers.push(new WebInspector.PanelDescriptor("canvas-profiler", WebInspector.UIString("Canvas Profiler"), "CanvasProfilerPanel", "ProfilesPanel.js"));
+            if (!WebInspector.WorkerManager.isWorkerFrontend() && WebInspector.experimentsSettings.nativeMemorySnapshots.isEnabled()) {
+                allProfilers.push(new WebInspector.PanelDescriptor("memory-chart-profiler", WebInspector.UIString("Memory Distribution"), "MemoryChartProfilerPanel", "ProfilesPanel.js"));
+                allProfilers.push(new WebInspector.PanelDescriptor("memory-snapshot-profiler", WebInspector.UIString("Memory Snapshots"), "NativeMemoryProfilerPanel", "ProfilesPanel.js"));
+            }
+            Array.prototype.splice.bind(allDescriptors, allDescriptors.indexOf(profiles), 1).apply(null, allProfilers);
+        }
 
         var panelDescriptors = [];
         if (WebInspector.WorkerManager.isWorkerFrontend()) {
             panelDescriptors.push(scripts);
             panelDescriptors.push(timeline);
-            panelDescriptors.push(profiles);
+            panelDescriptors = panelDescriptors.concat(allProfilers);
             panelDescriptors.push(console);
             return panelDescriptors;
         }