OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * @fileoverview Provides communication interface to remote v8 profiler. |
| 7 */ |
| 8 goog.provide('devtools.ProfilerAgent'); |
| 9 |
| 10 /** |
| 11 * @constructor |
| 12 */ |
| 13 devtools.ProfilerAgent = function() { |
| 14 RemoteProfilerAgent.DidGetActiveProfilerModules = |
| 15 goog.bind(this.didGetActiveProfilerModules_, this); |
| 16 RemoteProfilerAgent.DidGetLogLines = |
| 17 goog.bind(this.didGetLogLines_, this); |
| 18 |
| 19 /** |
| 20 * Active profiler modules flags. |
| 21 * @type {number} |
| 22 */ |
| 23 this.activeProfilerModules_ = |
| 24 devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; |
| 25 |
| 26 /** |
| 27 * Interval for polling profiler state. |
| 28 * @type {number} |
| 29 */ |
| 30 this.getActiveProfilerModulesInterval_ = null; |
| 31 |
| 32 /** |
| 33 * Profiler log position. |
| 34 * @type {number} |
| 35 */ |
| 36 this.logPosition_ = 0; |
| 37 |
| 38 /** |
| 39 * Whether log contents retrieval must be forced next time. |
| 40 * @type {boolean} |
| 41 */ |
| 42 this.forceGetLogLines_ = false; |
| 43 |
| 44 /** |
| 45 * Profiler processor instance. |
| 46 * @type {devtools.profiler.Processor} |
| 47 */ |
| 48 this.profilerProcessor_ = new devtools.profiler.Processor(); |
| 49 }; |
| 50 |
| 51 |
| 52 /** |
| 53 * A copy of enum from include/v8.h |
| 54 * @enum {number} |
| 55 */ |
| 56 devtools.ProfilerAgent.ProfilerModules = { |
| 57 PROFILER_MODULE_NONE: 0, |
| 58 PROFILER_MODULE_CPU: 1, |
| 59 PROFILER_MODULE_HEAP_STATS: 1 << 1, |
| 60 PROFILER_MODULE_JS_CONSTRUCTORS: 1 << 2, |
| 61 PROFILER_MODULE_HEAP_SNAPSHOT: 1 << 16 |
| 62 }; |
| 63 |
| 64 |
| 65 /** |
| 66 * Resets profiler agent to its initial state. |
| 67 */ |
| 68 devtools.ProfilerAgent.prototype.reset = function() { |
| 69 this.logPosition_ = 0; |
| 70 this.activeProfilerModules_ = |
| 71 devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; |
| 72 }; |
| 73 |
| 74 |
| 75 /** |
| 76 * Sets up callbacks that deal with profiles processing. |
| 77 */ |
| 78 devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function() { |
| 79 // A temporary icon indicating that the profile is being processed. |
| 80 var processingIcon = new WebInspector.SidebarTreeElement( |
| 81 'profile-sidebar-tree-item', |
| 82 WebInspector.UIString('Processing...'), |
| 83 '', null, false); |
| 84 var profilesSidebar = WebInspector.panels.profiles.getProfileType( |
| 85 WebInspector.CPUProfileType.TypeId).treeElement; |
| 86 |
| 87 this.profilerProcessor_.setCallbacks( |
| 88 function onProfileProcessingStarted() { |
| 89 // Set visually empty string. Subtitle hiding is done via styles |
| 90 // manipulation which doesn't play well with dynamic append / removal. |
| 91 processingIcon.subtitle = ' '; |
| 92 profilesSidebar.appendChild(processingIcon); |
| 93 }, |
| 94 function onProfileProcessingStatus(ticksCount) { |
| 95 processingIcon.subtitle = |
| 96 WebInspector.UIString('%d ticks processed', ticksCount); |
| 97 }, |
| 98 function onProfileProcessingFinished(profile) { |
| 99 profilesSidebar.removeChild(processingIcon); |
| 100 profile.typeId = WebInspector.CPUProfileType.TypeId; |
| 101 InspectorBackend.addFullProfile(profile); |
| 102 WebInspector.addProfileHeader(profile); |
| 103 // If no profile is currently shown, show the new one. |
| 104 var profilesPanel = WebInspector.panels.profiles; |
| 105 if (!profilesPanel.visibleView) { |
| 106 profilesPanel.showProfile(profile); |
| 107 } |
| 108 } |
| 109 ); |
| 110 }; |
| 111 |
| 112 |
| 113 /** |
| 114 * Initializes profiling state. |
| 115 */ |
| 116 devtools.ProfilerAgent.prototype.initializeProfiling = function() { |
| 117 this.setupProfilerProcessorCallbacks(); |
| 118 this.forceGetLogLines_ = true; |
| 119 this.getActiveProfilerModulesInterval_ = setInterval( |
| 120 function() { RemoteProfilerAgent.GetActiveProfilerModules(); }, 1000); |
| 121 }; |
| 122 |
| 123 |
| 124 /** |
| 125 * Starts profiling. |
| 126 * @param {number} modules List of modules to enable. |
| 127 */ |
| 128 devtools.ProfilerAgent.prototype.startProfiling = function(modules) { |
| 129 var cmd = new devtools.DebugCommand('profile', { |
| 130 'modules': modules, |
| 131 'command': 'resume'}); |
| 132 devtools.DebuggerAgent.sendCommand_(cmd); |
| 133 RemoteToolsAgent.ExecuteVoidJavaScript(); |
| 134 if (modules & |
| 135 devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) { |
| 136 var pos = this.logPosition_; |
| 137 // Active modules will not change, instead, a snapshot will be logged. |
| 138 setTimeout(function() { RemoteProfilerAgent.GetLogLines(pos); }, 500); |
| 139 } |
| 140 }; |
| 141 |
| 142 |
| 143 /** |
| 144 * Stops profiling. |
| 145 */ |
| 146 devtools.ProfilerAgent.prototype.stopProfiling = function(modules) { |
| 147 var cmd = new devtools.DebugCommand('profile', { |
| 148 'modules': modules, |
| 149 'command': 'pause'}); |
| 150 devtools.DebuggerAgent.sendCommand_(cmd); |
| 151 RemoteToolsAgent.ExecuteVoidJavaScript(); |
| 152 }; |
| 153 |
| 154 |
| 155 /** |
| 156 * Handles current profiler status. |
| 157 * @param {number} modules List of active (started) modules. |
| 158 */ |
| 159 devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_ = function( |
| 160 modules) { |
| 161 var profModules = devtools.ProfilerAgent.ProfilerModules; |
| 162 var profModuleNone = profModules.PROFILER_MODULE_NONE; |
| 163 if (this.forceGetLogLines_ || |
| 164 (modules != profModuleNone && |
| 165 this.activeProfilerModules_ == profModuleNone)) { |
| 166 this.forceGetLogLines_ = false; |
| 167 // Start to query log data. |
| 168 RemoteProfilerAgent.GetLogLines(this.logPosition_); |
| 169 } |
| 170 this.activeProfilerModules_ = modules; |
| 171 // Update buttons. |
| 172 WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); |
| 173 }; |
| 174 |
| 175 |
| 176 /** |
| 177 * Handles a portion of a profiler log retrieved by GetLogLines call. |
| 178 * @param {number} pos Current position in log. |
| 179 * @param {string} log A portion of profiler log. |
| 180 */ |
| 181 devtools.ProfilerAgent.prototype.didGetLogLines_ = function(pos, log) { |
| 182 this.logPosition_ = pos; |
| 183 if (log.length > 0) { |
| 184 this.profilerProcessor_.processLogChunk(log); |
| 185 } else if (this.activeProfilerModules_ == |
| 186 devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE) { |
| 187 // No new data and profiling is stopped---suspend log reading. |
| 188 return; |
| 189 } |
| 190 setTimeout(function() { RemoteProfilerAgent.GetLogLines(pos); }, 500); |
| 191 }; |
OLD | NEW |