| Index: webkit/glue/devtools/js/profiler_agent.js
|
| diff --git a/webkit/glue/devtools/js/profiler_agent.js b/webkit/glue/devtools/js/profiler_agent.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c41bbcbee2c67603513e889d96412b9297eccc90
|
| --- /dev/null
|
| +++ b/webkit/glue/devtools/js/profiler_agent.js
|
| @@ -0,0 +1,191 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +/**
|
| + * @fileoverview Provides communication interface to remote v8 profiler.
|
| + */
|
| +goog.provide('devtools.ProfilerAgent');
|
| +
|
| +/**
|
| + * @constructor
|
| + */
|
| +devtools.ProfilerAgent = function() {
|
| + RemoteProfilerAgent.DidGetActiveProfilerModules =
|
| + goog.bind(this.didGetActiveProfilerModules_, this);
|
| + RemoteProfilerAgent.DidGetLogLines =
|
| + goog.bind(this.didGetLogLines_, this);
|
| +
|
| + /**
|
| + * Active profiler modules flags.
|
| + * @type {number}
|
| + */
|
| + this.activeProfilerModules_ =
|
| + devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE;
|
| +
|
| + /**
|
| + * Interval for polling profiler state.
|
| + * @type {number}
|
| + */
|
| + this.getActiveProfilerModulesInterval_ = null;
|
| +
|
| + /**
|
| + * Profiler log position.
|
| + * @type {number}
|
| + */
|
| + this.logPosition_ = 0;
|
| +
|
| + /**
|
| + * Whether log contents retrieval must be forced next time.
|
| + * @type {boolean}
|
| + */
|
| + this.forceGetLogLines_ = false;
|
| +
|
| + /**
|
| + * 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
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Resets profiler agent to its initial state.
|
| + */
|
| +devtools.ProfilerAgent.prototype.reset = function() {
|
| + this.logPosition_ = 0;
|
| + this.activeProfilerModules_ =
|
| + devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE;
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Sets up callbacks that deal with profiles processing.
|
| + */
|
| +devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function() {
|
| + // A temporary icon indicating that the profile is being processed.
|
| + var processingIcon = new WebInspector.SidebarTreeElement(
|
| + 'profile-sidebar-tree-item',
|
| + WebInspector.UIString('Processing...'),
|
| + '', null, false);
|
| + var profilesSidebar = WebInspector.panels.profiles.getProfileType(
|
| + WebInspector.CPUProfileType.TypeId).treeElement;
|
| +
|
| + this.profilerProcessor_.setCallbacks(
|
| + function onProfileProcessingStarted() {
|
| + // Set visually empty string. Subtitle hiding is done via styles
|
| + // manipulation which doesn't play well with dynamic append / removal.
|
| + processingIcon.subtitle = ' ';
|
| + profilesSidebar.appendChild(processingIcon);
|
| + },
|
| + function onProfileProcessingStatus(ticksCount) {
|
| + processingIcon.subtitle =
|
| + WebInspector.UIString('%d ticks processed', ticksCount);
|
| + },
|
| + function onProfileProcessingFinished(profile) {
|
| + profilesSidebar.removeChild(processingIcon);
|
| + profile.typeId = WebInspector.CPUProfileType.TypeId;
|
| + InspectorBackend.addFullProfile(profile);
|
| + WebInspector.addProfileHeader(profile);
|
| + // If no profile is currently shown, show the new one.
|
| + var profilesPanel = WebInspector.panels.profiles;
|
| + if (!profilesPanel.visibleView) {
|
| + profilesPanel.showProfile(profile);
|
| + }
|
| + }
|
| + );
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Initializes profiling state.
|
| + */
|
| +devtools.ProfilerAgent.prototype.initializeProfiling = function() {
|
| + this.setupProfilerProcessorCallbacks();
|
| + this.forceGetLogLines_ = true;
|
| + this.getActiveProfilerModulesInterval_ = setInterval(
|
| + function() { RemoteProfilerAgent.GetActiveProfilerModules(); }, 1000);
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Starts profiling.
|
| + * @param {number} modules List of modules to enable.
|
| + */
|
| +devtools.ProfilerAgent.prototype.startProfiling = function(modules) {
|
| + var cmd = new devtools.DebugCommand('profile', {
|
| + 'modules': modules,
|
| + 'command': 'resume'});
|
| + devtools.DebuggerAgent.sendCommand_(cmd);
|
| + RemoteToolsAgent.ExecuteVoidJavaScript();
|
| + if (modules &
|
| + devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_HEAP_SNAPSHOT) {
|
| + var pos = this.logPosition_;
|
| + // Active modules will not change, instead, a snapshot will be logged.
|
| + setTimeout(function() { RemoteProfilerAgent.GetLogLines(pos); }, 500);
|
| + }
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Stops profiling.
|
| + */
|
| +devtools.ProfilerAgent.prototype.stopProfiling = function(modules) {
|
| + var cmd = new devtools.DebugCommand('profile', {
|
| + 'modules': modules,
|
| + 'command': 'pause'});
|
| + devtools.DebuggerAgent.sendCommand_(cmd);
|
| + RemoteToolsAgent.ExecuteVoidJavaScript();
|
| +};
|
| +
|
| +
|
| +/**
|
| + * Handles current profiler status.
|
| + * @param {number} modules List of active (started) modules.
|
| + */
|
| +devtools.ProfilerAgent.prototype.didGetActiveProfilerModules_ = function(
|
| + modules) {
|
| + var profModules = devtools.ProfilerAgent.ProfilerModules;
|
| + var profModuleNone = profModules.PROFILER_MODULE_NONE;
|
| + if (this.forceGetLogLines_ ||
|
| + (modules != profModuleNone &&
|
| + this.activeProfilerModules_ == profModuleNone)) {
|
| + this.forceGetLogLines_ = false;
|
| + // Start to query log data.
|
| + RemoteProfilerAgent.GetLogLines(this.logPosition_);
|
| + }
|
| + this.activeProfilerModules_ = modules;
|
| + // Update buttons.
|
| + WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU);
|
| +};
|
| +
|
| +
|
| +/**
|
| + * 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.didGetLogLines_ = function(pos, log) {
|
| + this.logPosition_ = pos;
|
| + if (log.length > 0) {
|
| + this.profilerProcessor_.processLogChunk(log);
|
| + } else if (this.activeProfilerModules_ ==
|
| + devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE) {
|
| + // No new data and profiling is stopped---suspend log reading.
|
| + return;
|
| + }
|
| + setTimeout(function() { RemoteProfilerAgent.GetLogLines(pos); }, 500);
|
| +};
|
|
|