| /* |
| * Copyright (C) 2014 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: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. 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. |
| * |
| * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS 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 GOOGLE INC. |
| * OR ITS 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. |
| */ |
| |
| /** |
| * @implements {Protocol.ProfilerDispatcher} |
| */ |
| export default class CPUProfilerModel extends SDK.SDKModel { |
| /** |
| * @param {!SDK.Target} target |
| */ |
| constructor(target) { |
| super(target); |
| this._isRecording = false; |
| this._nextAnonymousConsoleProfileNumber = 1; |
| this._anonymousConsoleProfileIdToTitle = new Map(); |
| this._profilerAgent = target.profilerAgent(); |
| target.registerProfilerDispatcher(this); |
| this._profilerAgent.enable(); |
| this._debuggerModel = /** @type {!SDK.DebuggerModel} */ (target.model(SDK.DebuggerModel)); |
| } |
| |
| /** |
| * @return {!SDK.RuntimeModel} |
| */ |
| runtimeModel() { |
| return this._debuggerModel.runtimeModel(); |
| } |
| |
| /** |
| * @return {!SDK.DebuggerModel} |
| */ |
| debuggerModel() { |
| return this._debuggerModel; |
| } |
| |
| /** |
| * @override |
| * @param {string} id |
| * @param {!Protocol.Debugger.Location} scriptLocation |
| * @param {string=} title |
| */ |
| consoleProfileStarted(id, scriptLocation, title) { |
| if (!title) { |
| title = Common.UIString('Profile %d', this._nextAnonymousConsoleProfileNumber++); |
| this._anonymousConsoleProfileIdToTitle.set(id, title); |
| } |
| this._dispatchProfileEvent(Events.ConsoleProfileStarted, id, scriptLocation, title); |
| } |
| |
| /** |
| * @override |
| * @param {string} id |
| * @param {!Protocol.Debugger.Location} scriptLocation |
| * @param {!Protocol.Profiler.Profile} cpuProfile |
| * @param {string=} title |
| */ |
| consoleProfileFinished(id, scriptLocation, cpuProfile, title) { |
| if (!title) { |
| title = this._anonymousConsoleProfileIdToTitle.get(id); |
| this._anonymousConsoleProfileIdToTitle.delete(id); |
| } |
| // Make sure ProfilesPanel is initialized and CPUProfileType is created. |
| self.runtime.loadModulePromise('profiler').then(() => { |
| this._dispatchProfileEvent(Events.ConsoleProfileFinished, id, scriptLocation, title, cpuProfile); |
| }); |
| } |
| |
| /** |
| * @param {symbol} eventName |
| * @param {string} id |
| * @param {!Protocol.Debugger.Location} scriptLocation |
| * @param {string=} title |
| * @param {!Protocol.Profiler.Profile=} cpuProfile |
| */ |
| _dispatchProfileEvent(eventName, id, scriptLocation, title, cpuProfile) { |
| const debuggerLocation = SDK.DebuggerModel.Location.fromPayload(this._debuggerModel, scriptLocation); |
| const globalId = this.target().id() + '.' + id; |
| const data = /** @type {!SDK.CPUProfilerModel.EventData} */ ( |
| {id: globalId, scriptLocation: debuggerLocation, cpuProfile: cpuProfile, title: title, cpuProfilerModel: this}); |
| this.dispatchEventToListeners(eventName, data); |
| } |
| |
| /** |
| * @return {boolean} |
| */ |
| isRecordingProfile() { |
| return this._isRecording; |
| } |
| |
| /** |
| * @return {!Promise} |
| */ |
| startRecording() { |
| this._isRecording = true; |
| const intervalUs = Common.moduleSetting('highResolutionCpuProfiling').get() ? 100 : 1000; |
| this._profilerAgent.setSamplingInterval(intervalUs); |
| return this._profilerAgent.start(); |
| } |
| |
| /** |
| * @return {!Promise<?Protocol.Profiler.Profile>} |
| */ |
| stopRecording() { |
| this._isRecording = false; |
| return this._profilerAgent.stop(); |
| } |
| |
| /** |
| * @param {boolean} jsCoveragePerBlock - Collect per Block coverage if `true`, per function coverage otherwise. |
| * @return {!Promise} |
| */ |
| startPreciseCoverage(jsCoveragePerBlock) { |
| const callCount = false; |
| return this._profilerAgent.startPreciseCoverage(callCount, jsCoveragePerBlock); |
| } |
| |
| /** |
| * @return {!Promise<!Array<!Protocol.Profiler.ScriptCoverage>>} |
| */ |
| takePreciseCoverage() { |
| return this._profilerAgent.takePreciseCoverage().then(result => result || []); |
| } |
| |
| /** |
| * @return {!Promise} |
| */ |
| stopPreciseCoverage() { |
| return this._profilerAgent.stopPreciseCoverage(); |
| } |
| } |
| |
| /** @enum {symbol} */ |
| export const Events = { |
| ConsoleProfileStarted: Symbol('ConsoleProfileStarted'), |
| ConsoleProfileFinished: Symbol('ConsoleProfileFinished') |
| }; |
| |
| /* Legacy exported object */ |
| self.SDK = self.SDK || {}; |
| |
| /* Legacy exported object */ |
| SDK = SDK || {}; |
| |
| /** @constructor */ |
| SDK.CPUProfilerModel = CPUProfilerModel; |
| |
| /** @enum {symbol} */ |
| SDK.CPUProfilerModel.Events = Events; |
| |
| SDK.SDKModel.register(SDK.CPUProfilerModel, SDK.Target.Capability.JS, true); |
| |
| /** @typedef {!{id: string, scriptLocation: !SDK.DebuggerModel.Location, title: string, cpuProfile: (!Protocol.Profiler.Profile|undefined), cpuProfilerModel: !SDK.CPUProfilerModel}} */ |
| SDK.CPUProfilerModel.EventData; |