/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-*/ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" #include "nsIArray.idl" #include "nsIDOMWindow.idl" /** * Mechanisms for querying the current process about performance * information. * * JavaScript clients should rather use PerformanceStats.jsm. */ /** * Identification details for a performance group. * * A performance group is a set of JavaScript compartments whose * performance is observed as a single entity. Typical examples of * performance groups: an add-on, a webpage without its frames, a * webpage with all its frames, the entire JS runtime, ... */ [scriptable, builtinclass, uuid(994c56be-939a-4f20-8364-124f6422d86a)] interface nsIPerformanceGroupDetails: nsISupports { /** * An identifier unique to the component. * * This identifier is somewhat human-readable to aid with debugging, * but clients should not rely upon the format. */ readonly attribute AString groupId; /** * A somewhat human-readable name for the component. */ readonly attribute AString name; /** * If the component is an add-on, the ID of the addon, * otherwise an empty string. */ readonly attribute AString addonId; /** * If the component is code executed in a window, the ID of the topmost * outer window (i.e. the tab), otherwise 0. */ readonly attribute uint64_t windowId; /** * `true` if this component is executed with system privileges * (e.g. the platform itself or an add-on), `false` otherwise * (e.g. webpages). */ readonly attribute bool isSystem; /** * The process running this group. */ readonly attribute unsigned long long processId; /** * `true` if the code is executed in a content process, `false` otherwise. */ readonly attribute bool isContentProcess; }; /** * Snapshot of the performance of a component, e.g. an add-on, a web * page, system built-ins, a module or the entire process itself. * * All values are monotonic and are updated only when * `nsIPerformanceStatsService.isStopwatchActive` is `true`. */ [scriptable, builtinclass, uuid(8a635d4b-aa56-466b-9a7d-9f91ca9405ef)] interface nsIPerformanceStats: nsIPerformanceGroupDetails { /** * Total amount of time spent executing code in this group, in * microseconds. */ readonly attribute unsigned long long totalUserTime; readonly attribute unsigned long long totalSystemTime; readonly attribute unsigned long long totalCPOWTime; /** * Total number of times code execution entered this group, * since process launch. This may be greater than the number * of times we have entered the event loop. */ readonly attribute unsigned long long ticks; /** * Jank indicator. * * durations[i] == number of times execution of this group * lasted at lest 2^i ms. */ void getDurations([optional] out unsigned long aCount, [retval, array, size_is(aCount)]out unsigned long long aNumberOfOccurrences); }; /** * A snapshot of the performance data of the process. */ [scriptable, builtinclass, uuid(13cc235b-739e-4690-b0e3-d89cbe036a93)] interface nsIPerformanceSnapshot: nsISupports { /** * Data on all individual components. */ nsIArray getComponentsData(); /** * Information on the process itself. * * This contains the total amount of time spent executing JS code, * the total amount of time spent waiting for system calls while * executing JS code, the total amount of time performing blocking * inter-process calls, etc. */ nsIPerformanceStats getProcessData(); }; /** * A performance alert. */ [scriptable, builtinclass, uuid(a85706ab-d703-4687-8865-78cd771eab93)] interface nsIPerformanceAlert: nsISupports { /** * A slowdown was detected. * * See REASON_JANK_* for details on whether this slowdown was user-noticeable. */ const unsigned long REASON_SLOWDOWN = 1; /** * This alert was triggered during a jank in animation. * * In the current implementation, we consider that there is a jank * in animation if delivery of the vsync message to the main thread * has been delayed too much (see * nsIPerformanceStatsService.animationJankLevelThreshold). * * Note that this is a heuristic which may provide false positives, * so clients of this API are expected to perform post-processing to * filter out such false positives. */ const unsigned long REASON_JANK_IN_ANIMATION = 2; /** * This alert was triggered during a jank in user input. * * In the current implementation, we consider that there is a jank * in animation if a user input was received either immediately * before executing the offending code (see * nsIPerformanceStatsService.userInputDelayThreshold) or while * executing the offending code. * * Note that this is a heuristic which may provide false positives, * so clients of this API are expected to perform post-processing to * filter out such false positives. */ const unsigned long REASON_JANK_IN_INPUT = 4; /** * The reason for the alert, as a bitwise or of the various REASON_* * constants. */ readonly attribute unsigned long reason; /** * Longest interval spent executing code in this group * since the latest alert, in microseconds. * * Note that the underlying algorithm is probabilistic and may * provide false positives, so clients of this API are expected to * perform post-processing to filter out such false positives. In * particular, a high system load will increase the noise level on * this measure. */ readonly attribute unsigned long long highestJank; /** * Longest interval spent executing CPOW in this group * since the latest alert, in microseconds. * * This measure is reliable and involves no heuristics. However, * note that the duration of CPOWs is increased by high system * loads. */ readonly attribute unsigned long long highestCPOW; }; /** * An observer for slow performance alerts. */ [scriptable, function, uuid(b746a929-3fec-420b-8ed8-c35d71995e05)] interface nsIPerformanceObserver: nsISupports { /** * @param target The performance group that caused the jank. * @param alert The performance cost that triggered the alert. */ void observe(in nsIPerformanceGroupDetails target, in nsIPerformanceAlert alert); }; /** * A part of the system that may be observed for slow performance. */ [scriptable, builtinclass, uuid(b85720d0-e328-4342-9e46-8ca1acf8c70e)] interface nsIPerformanceObservable: nsISupports { /** * If a single group is being observed, information on this group. */ readonly attribute nsIPerformanceGroupDetails target; /** * Add an observer that will be informed in case of jank. * * Set `jankAlertThreshold` to determine how much jank is needed * to trigger alerts. * * If the same observer is added more than once, it will be * triggered as many times as it has been added. */ void addJankObserver(in nsIPerformanceObserver observer); /** * Remove an observer previously added with `addJankObserver`. * * Noop if the observer hasn't been added. */ void removeJankObserver(in nsIPerformanceObserver observer); }; [scriptable, uuid(505bc42e-be38-4a53-baba-92cb33690cde)] interface nsIPerformanceStatsService : nsISupports { /** * `true` if we should monitor CPOW, `false` otherwise. */ [implicit_jscontext] attribute bool isMonitoringCPOW; /** * `true` if we should monitor jank, `false` otherwise. */ [implicit_jscontext] attribute bool isMonitoringJank; /** * `true` if all compartments need to be monitored individually, * `false` if only performance groups (i.e. entire add-ons, entire * webpages, etc.) need to be monitored. */ [implicit_jscontext] attribute bool isMonitoringPerCompartment; /** * Capture a snapshot of the performance data. */ [implicit_jscontext] nsIPerformanceSnapshot getSnapshot(); /** * The threshold, in microseconds, above which a performance group is * considered "slow" and should raise performance alerts. */ attribute unsigned long long jankAlertThreshold; /** * If a user is seeing an animation and we spend too long executing * JS code while blocking refresh, this will be visible to the user. * * We assume that any jank during an animation and lasting more than * 2^animationJankLevelThreshold ms will be visible. */ attribute short animationJankLevelThreshold; /** * If a user performs an input (e.g. clicking, pressing a key, but * *NOT* moving the mouse), and we spend too long executing JS code * before displaying feedback, this will be visible to the user even * if there is no ongoing animation. * * We assume that any jank during `userInputDelayThreshold` us after * the user input will be visible. */ attribute unsigned long long userInputDelayThreshold; /** * A buffering delay, in milliseconds, used by the service to * regroup performance alerts, before observers are actually * noticed. Higher delays let the system avoid redundant * notifications for the same group, and are generally better for * performance. */ attribute unsigned long jankAlertBufferingDelay; /** * Get a nsIPerformanceObservable representing an add-on. This * observable may then be used to (un)register for watching * performance alerts for this add-on. * * Note that this method has no way of finding out whether an add-on with this * id is installed on the system. Also note that this covers only the current * process. * * Use special add-on name "*" to get an observable that may be used * to (un)register for watching performance alerts of all add-ons at * once. */ nsIPerformanceObservable getObservableAddon(in AString addonId); /** * Get a nsIPerformanceObservable representing a DOM window. This * observable may then be used to (un)register for watching * performance alerts for this window. * * Note that this covers only the current process. * * Use special window id 0 to get an observable that may be used to * (un)register for watching performance alerts of all windows at * once. */ nsIPerformanceObservable getObservableWindow(in unsigned long long windowId); }; %{C++ #define NS_TOOLKIT_PERFORMANCESTATSSERVICE_CID {0xfd7435d4, 0x9ec4, 0x4699, \ {0xad, 0xd4, 0x1b, 0xe8, 0x3d, 0xd6, 0x8e, 0xf3} } #define NS_TOOLKIT_PERFORMANCESTATSSERVICE_CONTRACTID "@mozilla.org/toolkit/performance-stats-service;1" %}