LCOV - code coverage report
Current view: top level - toolkit/components/perfmonitoring - nsPerformanceStats.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 28 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef nsPerformanceStats_h
       7             : #define nsPerformanceStats_h
       8             : 
       9             : #include "jsapi.h"
      10             : 
      11             : #include "nsHashKeys.h"
      12             : #include "nsTHashtable.h"
      13             : 
      14             : #include "nsIObserver.h"
      15             : #include "nsPIDOMWindow.h"
      16             : 
      17             : #include "nsIPerformanceStats.h"
      18             : 
      19             : class nsPerformanceGroup;
      20             : class nsPerformanceGroupDetails;
      21             : 
      22             : typedef mozilla::Vector<RefPtr<nsPerformanceGroup>, 8> GroupVector;
      23             : 
      24             : /**
      25             :  * A data structure for registering observers interested in
      26             :  * performance alerts.
      27             :  *
      28             :  * Each performance group owns a single instance of this class.
      29             :  * Additionally, the service owns instances designed to observe the
      30             :  * performance alerts in all webpages.
      31             :  */
      32           0 : class nsPerformanceObservationTarget final: public nsIPerformanceObservable {
      33             : public:
      34             :   NS_DECL_ISUPPORTS
      35             :   NS_DECL_NSIPERFORMANCEOBSERVABLE
      36             : 
      37             :   /**
      38             :    * `true` if this target has at least once performance observer
      39             :    * registered, `false` otherwise.
      40             :    */
      41             :   bool HasObservers() const;
      42             : 
      43             :   /**
      44             :    * Notify all the observers that jank has happened.
      45             :    */
      46             :   void NotifyJankObservers(nsIPerformanceGroupDetails* source, nsIPerformanceAlert* gravity);
      47             : 
      48             :   /**
      49             :    * Set the details on the group being observed.
      50             :    */
      51             :   void SetTarget(nsPerformanceGroupDetails* details);
      52             : 
      53             : private:
      54           0 :   ~nsPerformanceObservationTarget() {}
      55             : 
      56             :   // The observers for this target. We hold them as a vector, despite
      57             :   // the linear removal cost, as we expect that the typical number of
      58             :   // observers will be lower than 3, and that (un)registrations will
      59             :   // be fairly infrequent.
      60             :   mozilla::Vector<nsCOMPtr<nsIPerformanceObserver>> mObservers;
      61             : 
      62             :   // Details on the group being observed. May be `nullptr`.
      63             :   RefPtr<nsPerformanceGroupDetails> mDetails;
      64             : };
      65             : 
      66             : /**
      67             :  * The base class for entries of maps from window id to
      68             :  * performance group.
      69             :  *
      70             :  * Performance observers may be registered before their group is
      71             :  * created (e.g., one may register an observer for a webpage before all
      72             :  * its iframes are loaded). This class serves to hold the observation
      73             :  * target until the performance group may be created, and then to
      74             :  * associate the observation target and the performance group.
      75             :  */
      76           0 : class nsGroupHolder {
      77             : public:
      78           0 :   nsGroupHolder()
      79           0 :     : mGroup(nullptr)
      80           0 :     , mPendingObservationTarget(nullptr)
      81           0 :   { }
      82             : 
      83             :   /**
      84             :    * Get the observation target, creating it if necessary.
      85             :    */
      86             :   nsPerformanceObservationTarget* ObservationTarget();
      87             : 
      88             :   /**
      89             :    * Get the group, if it has been created.
      90             :    *
      91             :    * May return `null` if the group hasn't been created yet.
      92             :    */
      93             :   class nsPerformanceGroup* GetGroup();
      94             : 
      95             :   /**
      96             :    * Set the group.
      97             :    *
      98             :    * Once this method has been called, calling
      99             :    * `this->ObservationTarget()` and `group->ObservationTarget()` is equivalent.
     100             :    *
     101             :    * Must only be called once.
     102             :    */
     103             :   void SetGroup(class nsPerformanceGroup*);
     104             : private:
     105             :   // The group. Initially `nullptr`, until we have called `SetGroup`.
     106             :   class nsPerformanceGroup* mGroup;
     107             : 
     108             :   // The observation target. Instantiated by the first call to
     109             :   // `ObservationTarget()`.
     110             :   RefPtr<nsPerformanceObservationTarget> mPendingObservationTarget;
     111             : };
     112             : 
     113             : /**
     114             :  * An implementation of the nsIPerformanceStatsService.
     115             :  *
     116             :  * Note that this implementation is not thread-safe.
     117             :  */
     118             : class nsPerformanceStatsService final : public nsIPerformanceStatsService,
     119             :                                         public nsIObserver
     120             : {
     121             : public:
     122             :   NS_DECL_ISUPPORTS
     123             :   NS_DECL_NSIPERFORMANCESTATSSERVICE
     124             :   NS_DECL_NSIOBSERVER
     125             : 
     126             :   nsPerformanceStatsService();
     127             :   nsresult Init();
     128             : 
     129             : private:
     130             :   nsresult InitInternal();
     131             :   void Dispose();
     132             :   ~nsPerformanceStatsService();
     133             : 
     134             : protected:
     135             :   friend nsPerformanceGroup;
     136             : 
     137             :   /**
     138             :    * `false` until `Init()` and after `Dispose()`, `true` inbetween.
     139             :    */
     140             :   bool mIsAvailable;
     141             : 
     142             :   /**
     143             :    * `true` once we have called `Dispose()`.
     144             :    */
     145             :   bool mDisposed;
     146             : 
     147             :   /**
     148             :    * A unique identifier for the process.
     149             :    *
     150             :    * Process HANDLE under Windows, pid under Unix.
     151             :    */
     152             :   const uint64_t mProcessId;
     153             : 
     154             :   /**
     155             :    * Generate unique identifiers.
     156             :    */
     157             :   uint64_t GetNextId();
     158             :   uint64_t mUIdCounter;
     159             : 
     160             : 
     161             : 
     162             :   /**
     163             :    * Extract a snapshot of performance statistics from a performance group.
     164             :    */
     165             :   static nsIPerformanceStats* GetStatsForGroup(const js::PerformanceGroup* group);
     166             :   static nsIPerformanceStats* GetStatsForGroup(const nsPerformanceGroup* group);
     167             : 
     168             : 
     169             : 
     170             :   /**
     171             :    * Get the performance groups associated to a given JS compartment.
     172             :    *
     173             :    * A compartment is typically associated to the following groups:
     174             :    * - the top group, shared by the entire process;
     175             :    * - the window group, if the code is executed in a window, shared
     176             :    *     by all compartments for that window (typically, all frames);
     177             :    * - the compartment's own group.
     178             :    *
     179             :    * Pre-condition: the VM must have entered the JS compartment.
     180             :    *
     181             :    * The caller is expected to cache the results of this method, as
     182             :    * calling it more than once may not return the same instances of
     183             :    * performance groups.
     184             :    */
     185             :   bool GetPerformanceGroups(JSContext* cx, js::PerformanceGroupVector&);
     186             :   static bool GetPerformanceGroupsCallback(JSContext* cx, js::PerformanceGroupVector&, void* closure);
     187             : 
     188             : 
     189             : 
     190             :   /**********************************************************
     191             :    *
     192             :    * Sets of all performance groups, indexed by several keys.
     193             :    *
     194             :    * These sets do not keep the performance groups alive. Rather, a
     195             :    * performance group is inserted in the relevant sets upon
     196             :    * construction and removed from the sets upon destruction or when
     197             :    * we Dispose() of the service.
     198             :    *
     199             :    * A `nsPerformanceGroup` is typically kept alive (as a
     200             :    * `js::PerformanceGroup`) by the JSCompartment to which it is
     201             :    * associated. It may also temporarily be kept alive by the JS
     202             :    * stack, in particular in case of nested event loops.
     203             :    */
     204             : 
     205             :   /**
     206             :    * Set of performance groups associated to windows, indexed by outer
     207             :    * window id. Each item is shared by all the compartments that
     208             :    * belong to the window.
     209             :    */
     210           0 :   struct WindowIdToGroup: public nsUint64HashKey,
     211             :                           public nsGroupHolder {
     212           0 :     explicit WindowIdToGroup(const uint64_t* key)
     213           0 :       : nsUint64HashKey(key)
     214           0 :     {}
     215             :   };
     216             :   nsTHashtable<WindowIdToGroup> mWindowIdToGroup;
     217             : 
     218             :   /**
     219             :    * Set of all performance groups.
     220             :    */
     221           0 :   struct Groups: public nsPtrHashKey<nsPerformanceGroup> {
     222           0 :     explicit Groups(const nsPerformanceGroup* key)
     223           0 :       : nsPtrHashKey<nsPerformanceGroup>(key)
     224           0 :     {}
     225             :   };
     226             :   nsTHashtable<Groups> mGroups;
     227             : 
     228             :   /**
     229             :    * The performance group representing the runtime itself.  All
     230             :    * compartments are associated to this group.
     231             :    */
     232             :   RefPtr<nsPerformanceGroup> mTopGroup;
     233             : 
     234             :   /**********************************************************
     235             :    *
     236             :    * Measuring and recording the CPU use of the system.
     237             :    *
     238             :    */
     239             : 
     240             :   /**
     241             :    * Get the OS-reported time spent in userland/systemland, in
     242             :    * microseconds. On most platforms, this data is per-thread,
     243             :    * but on some platforms we need to fall back to per-process.
     244             :    *
     245             :    * Data is not guaranteed to be monotonic.
     246             :    */
     247             :   nsresult GetResources(uint64_t* userTime, uint64_t* systemTime) const;
     248             : 
     249             :   /**
     250             :    * Amount of user/system CPU time used by the thread (or process,
     251             :    * for platforms that don't support per-thread measure) since start.
     252             :    * Updated by `StopwatchStart` at most once per event.
     253             :    *
     254             :    * Unit: microseconds.
     255             :    */
     256             :   uint64_t mUserTimeStart;
     257             :   uint64_t mSystemTimeStart;
     258             : 
     259             :   bool mIsHandlingUserInput;
     260             : 
     261             :   /**
     262             :    * The number of user inputs since the start of the process. Used to
     263             :    * determine whether the current iteration has triggered a
     264             :    * (JS-implemented) user input.
     265             :    */
     266             :   uint64_t mUserInputCount;
     267             : 
     268             :   /**********************************************************
     269             :    *
     270             :    * Callbacks triggered by the JS VM when execution of JavaScript
     271             :    * code starts/completes.
     272             :    *
     273             :    * As measures of user CPU time/system CPU time have low resolution
     274             :    * (and are somewhat slow), we measure both only during the calls to
     275             :    * `StopwatchStart`/`StopwatchCommit` and we make the assumption
     276             :    * that each group's user/system CPU time is proportional to the
     277             :    * number of clock cycles spent executing code in the group between
     278             :    * `StopwatchStart`/`StopwatchCommit`.
     279             :    *
     280             :    * The results may be skewed by the thread being rescheduled to a
     281             :    * different CPU during the measure, but we expect that on average,
     282             :    * the skew will have limited effects, and will generally tend to
     283             :    * make already-slow executions appear slower.
     284             :    */
     285             : 
     286             :   /**
     287             :    * Execution of JavaScript code has started. This may happen several
     288             :    * times in succession if the JavaScript code contains nested event
     289             :    * loops, in which case only the innermost call will receive
     290             :    * `StopwatchCommitCallback`.
     291             :    *
     292             :    * @param iteration The number of times we have started executing
     293             :    * JavaScript code.
     294             :    */
     295             :   static bool StopwatchStartCallback(uint64_t iteration, void* closure);
     296             :   bool StopwatchStart(uint64_t iteration);
     297             : 
     298             :   /**
     299             :    * Execution of JavaScript code has reached completion (including
     300             :    * enqueued microtasks). In cse of tested event loops, any ongoing
     301             :    * measurement on outer loops is silently cancelled without any call
     302             :    * to this method.
     303             :    *
     304             :    * @param iteration The number of times we have started executing
     305             :    * JavaScript code.
     306             :    * @param recentGroups The groups that have seen activity during this
     307             :    * event.
     308             :    */
     309             :   static bool StopwatchCommitCallback(uint64_t iteration,
     310             :                                       js::PerformanceGroupVector& recentGroups,
     311             :                                       void* closure);
     312             :   bool StopwatchCommit(uint64_t iteration, js::PerformanceGroupVector& recentGroups);
     313             : 
     314             :   /**
     315             :    * The number of times we have started executing JavaScript code.
     316             :    */
     317             :   uint64_t mIteration;
     318             : 
     319             :   /**
     320             :    * Commit performance measures of a single group.
     321             :    *
     322             :    * Data is transfered from `group->recent*` to `group->data`.
     323             :    *
     324             :    *
     325             :    * @param iteration The current iteration.
     326             :    * @param userTime The total user CPU time for this thread (or
     327             :    *   process, if per-thread data is not available) between the
     328             :    *   calls to `StopwatchStart` and `StopwatchCommit`.
     329             :    * @param systemTime The total system CPU time for this thread (or
     330             :    *   process, if per-thread data is not available) between the
     331             :    *   calls to `StopwatchStart` and `StopwatchCommit`.
     332             :    * @param cycles The total number of cycles for this thread
     333             :    *   between the calls to `StopwatchStart` and `StopwatchCommit`.
     334             :    * @param isJankVisible If `true`, expect that the user will notice
     335             :    *   any slowdown.
     336             :    * @param group The group containing the data to commit.
     337             :    */
     338             :   void CommitGroup(uint64_t iteration,
     339             :                    uint64_t userTime, uint64_t systemTime,  uint64_t cycles,
     340             :                    bool isJankVisible,
     341             :                    nsPerformanceGroup* group);
     342             : 
     343             : 
     344             : 
     345             : 
     346             :   /**********************************************************
     347             :    *
     348             :    * To check whether our algorithm makes sense, we keep count of the
     349             :    * number of times the process has been rescheduled to another CPU
     350             :    * while we were monitoring the performance of a group and we upload
     351             :    * this data through Telemetry.
     352             :    */
     353             :   nsresult UpdateTelemetry();
     354             : 
     355             :   uint64_t mProcessStayed;
     356             :   uint64_t mProcessMoved;
     357             :   uint32_t mProcessUpdateCounter;
     358             : 
     359             :   /**********************************************************
     360             :    *
     361             :    * Options controlling measurements.
     362             :    */
     363             : 
     364             :   /**
     365             :    * Determine if we are measuring the performance of every individual
     366             :    * compartment (in particular, every individual module, frame,
     367             :    * sandbox). Note that this makes measurements noticeably slower.
     368             :    */
     369             :   bool mIsMonitoringPerCompartment;
     370             : 
     371             : 
     372             :   /**********************************************************
     373             :    *
     374             :    * Determining whether jank is user-visible.
     375             :    */
     376             : 
     377             :   /**
     378             :    * `true` if we believe that any slowdown can cause a noticeable
     379             :    * delay in handling user-input.
     380             :    *
     381             :    * In the current implementation, we return `true` if the latest
     382             :    * user input was less than MAX_DURATION_OF_INTERACTION_MS ago. This
     383             :    * includes all inputs (mouse, keyboard, other devices), with the
     384             :    * exception of mousemove.
     385             :    */
     386             :   bool IsHandlingUserInput();
     387             : 
     388             : 
     389             : public:
     390             :   /**********************************************************
     391             :    *
     392             :    * Letting observers register themselves to watch for performance
     393             :    * alerts.
     394             :    *
     395             :    * To avoid saturating clients with alerts (or even creating loops
     396             :    * of alerts), each alert is buffered. At the end of each iteration
     397             :    * of the event loop, groups that have caused performance alerts
     398             :    * are registered in a set of pending alerts, and the collection
     399             :    * timer hasn't been started yet, it is started. Once the timer
     400             :    * firers, we gather all the pending alerts, empty the set and
     401             :    * dispatch to observers.
     402             :    */
     403             : 
     404             :   /**
     405             :    * Clear the set of pending alerts and dispatch the pending alerts
     406             :    * to observers.
     407             :    */
     408             :   void NotifyJankObservers(const mozilla::Vector<uint64_t>& previousJankLevels);
     409             : 
     410             : private:
     411             :   /**
     412             :    * The set of groups for which we know that an alert should be
     413             :    * raised. This set is cleared once `mPendingAlertsCollector`
     414             :    * fires.
     415             :    *
     416             :    * Invariant: no group may appear twice in this vector.
     417             :    */
     418             :   GroupVector mPendingAlerts;
     419             : 
     420             :   /**
     421             :    * A timer callback in charge of collecting the groups in
     422             :    * `mPendingAlerts` and triggering `NotifyJankObservers` to dispatch
     423             :    * performance alerts.
     424             :    */
     425             :   RefPtr<class PendingAlertsCollector> mPendingAlertsCollector;
     426             : 
     427             : 
     428             :   /**
     429             :    * Observation targets that are not attached to a specific group.
     430             :    */
     431           0 :   struct UniversalTargets {
     432             :     UniversalTargets();
     433             :     /**
     434             :      * A target for observers interested in watching all windows.
     435             :      */
     436             :     RefPtr<nsPerformanceObservationTarget> mWindows;
     437             :   };
     438             :   UniversalTargets mUniversalTargets;
     439             : 
     440             :   /**
     441             :    * The threshold, in microseconds, above which a performance group is
     442             :    * considered "slow" and should raise performance alerts.
     443             :    */
     444             :   uint64_t mJankAlertThreshold;
     445             : 
     446             :   /**
     447             :    * A buffering delay, in milliseconds, used by the service to
     448             :    * regroup performance alerts, before observers are actually
     449             :    * noticed. Higher delays let the system avoid redundant
     450             :    * notifications for the same group, and are generally better for
     451             :    * performance.
     452             :    */
     453             :   uint32_t mJankAlertBufferingDelay;
     454             : 
     455             :   /**
     456             :    * The threshold above which jank, as reported by the refresh drivers,
     457             :    * is considered user-visible.
     458             :    *
     459             :    * A value of n means that any jank above 2^n ms will be considered
     460             :    * user visible.
     461             :    */
     462             :   short mJankLevelVisibilityThreshold;
     463             : 
     464             :   /**
     465             :    * The number of microseconds during which we assume that a
     466             :    * user-interaction can keep the code jank-critical. Any user
     467             :    * interaction that lasts longer than this duration is expected to
     468             :    * either have already caused jank or have caused a nested event
     469             :    * loop.
     470             :    *
     471             :    * In either case, we consider that monitoring
     472             :    * jank-during-interaction after this duration is useless.
     473             :    */
     474             :   uint64_t mMaxExpectedDurationOfInteractionUS;
     475             : };
     476             : 
     477             : 
     478             : 
     479             : /**
     480             :  * Container for performance data.
     481             :  *
     482             :  * All values are monotonic.
     483             :  *
     484             :  * All values are updated after running to completion.
     485             :  */
     486             : struct PerformanceData {
     487             :   /**
     488             :    * Number of times we have spent at least 2^n consecutive
     489             :    * milliseconds executing code in this group.
     490             :    * durations[0] is increased whenever we spend at least 1 ms
     491             :    * executing code in this group
     492             :    * durations[1] whenever we spend 2ms+
     493             :    * ...
     494             :    * durations[i] whenever we spend 2^ims+
     495             :    */
     496             :   uint64_t mDurations[10];
     497             : 
     498             :   /**
     499             :    * Total amount of time spent executing code in this group, in
     500             :    * microseconds.
     501             :    */
     502             :   uint64_t mTotalUserTime;
     503             :   uint64_t mTotalSystemTime;
     504             :   uint64_t mTotalCPOWTime;
     505             : 
     506             :   /**
     507             :    * Total number of times code execution entered this group, since
     508             :    * process launch. This may be greater than the number of times we
     509             :    * have entered the event loop.
     510             :    */
     511             :   uint64_t mTicks;
     512             : 
     513             :   PerformanceData();
     514             :   PerformanceData(const PerformanceData& from) = default;
     515             :   PerformanceData& operator=(const PerformanceData& from) = default;
     516             : };
     517             : 
     518             : 
     519             : 
     520             : /**
     521             :  * Identification information for an item that can hold performance
     522             :  * data.
     523             :  */
     524             : class nsPerformanceGroupDetails final: public nsIPerformanceGroupDetails {
     525             : public:
     526             :   NS_DECL_ISUPPORTS
     527             :   NS_DECL_NSIPERFORMANCEGROUPDETAILS
     528             : 
     529           0 :   nsPerformanceGroupDetails(const nsAString& aName,
     530             :                             const nsAString& aGroupId,
     531             :                             const uint64_t aWindowId,
     532             :                             const uint64_t aProcessId,
     533             :                             const bool aIsSystem)
     534           0 :     : mName(aName)
     535             :     , mGroupId(aGroupId)
     536             :     , mWindowId(aWindowId)
     537             :     , mProcessId(aProcessId)
     538           0 :     , mIsSystem(aIsSystem)
     539           0 :   { }
     540             : public:
     541             :   const nsAString& Name() const;
     542             :   const nsAString& GroupId() const;
     543             :   uint64_t WindowId() const;
     544             :   uint64_t ProcessId() const;
     545             :   bool IsWindow() const;
     546             :   bool IsSystem() const;
     547             :   bool IsContentProcess() const;
     548             : private:
     549           0 :   ~nsPerformanceGroupDetails() {}
     550             : 
     551             :   const nsString mName;
     552             :   const nsString mGroupId;
     553             :   const uint64_t mWindowId;
     554             :   const uint64_t mProcessId;
     555             :   const bool mIsSystem;
     556             : };
     557             : 
     558             : /**
     559             :  * The kind of compartments represented by this group.
     560             :  */
     561             : enum class PerformanceGroupScope {
     562             :   /**
     563             :    * This group represents the entire runtime (i.e. the thread).
     564             :    */
     565             :   RUNTIME,
     566             : 
     567             :   /**
     568             :    * This group represents all the compartments executed in a window.
     569             :    */
     570             :   WINDOW,
     571             : 
     572             :   /**
     573             :    * This group represents a single compartment.
     574             :    */
     575             :   COMPARTMENT,
     576             : };
     577             : 
     578             : /**
     579             :  * A concrete implementation of `js::PerformanceGroup`, also holding
     580             :  * performance data. Instances may represent individual compartments,
     581             :  * windows or the entire runtime.
     582             :  *
     583             :  * This class is intended to be the sole implementation of
     584             :  * `js::PerformanceGroup`.
     585             :  */
     586             : class nsPerformanceGroup final: public js::PerformanceGroup {
     587             : public:
     588             : 
     589             :   // Ideally, we would define the enum class in nsPerformanceGroup,
     590             :   // but this seems to choke some versions of gcc.
     591             :   typedef PerformanceGroupScope GroupScope;
     592             : 
     593             :   /**
     594             :    * Construct a performance group.
     595             :    *
     596             :    * @param cx The container context. Used to generate a unique identifier.
     597             :    * @param service The performance service. Used during destruction to
     598             :    *   cleanup the hash tables.
     599             :    * @param name A name for the group, designed mostly for debugging purposes,
     600             :    *   so it should be at least somewhat human-readable.
     601             :    * @param windowId The identifier of the window. Should be 0 when the
     602             :    *   group is not part of a window.
     603             :    * @param processId A unique identifier for the process.
     604             :    * @param isSystem `true` if the code of the group is executed with
     605             :    *   system credentials, `false` otherwise.
     606             :    * @param scope the scope of this group.
     607             :    */
     608             :   static nsPerformanceGroup*
     609             :     Make(nsPerformanceStatsService* service,
     610             :          const nsAString& name,
     611             :          uint64_t windowId,
     612             :          uint64_t processId,
     613             :          bool isSystem,
     614             :          GroupScope scope);
     615             : 
     616             :   /**
     617             :    * Utility: type-safer conversion from js::PerformanceGroup to nsPerformanceGroup.
     618             :    */
     619           0 :   static inline nsPerformanceGroup* Get(js::PerformanceGroup* self) {
     620           0 :     return static_cast<nsPerformanceGroup*>(self);
     621             :   }
     622           0 :   static inline const nsPerformanceGroup* Get(const js::PerformanceGroup* self) {
     623           0 :     return static_cast<const nsPerformanceGroup*>(self);
     624             :   }
     625             : 
     626             :   /**
     627             :    * The performance data committed to this group.
     628             :    */
     629             :   PerformanceData data;
     630             : 
     631             :   /**
     632             :    * The scope of this group. Used to determine whether the group
     633             :    * should be (de)activated.
     634             :    */
     635             :   GroupScope Scope() const;
     636             : 
     637             :   /**
     638             :    * Identification details for this group.
     639             :    */
     640             :   nsPerformanceGroupDetails* Details() const;
     641             : 
     642             :   /**
     643             :    * Cleanup any references.
     644             :    */
     645             :   void Dispose();
     646             : 
     647             :   /**
     648             :    * Set the observation target for this group.
     649             :    *
     650             :    * This method must be called exactly once, when the performance
     651             :    * group is attached to its `nsGroupHolder`.
     652             :    */
     653             :   void SetObservationTarget(nsPerformanceObservationTarget*);
     654             : 
     655             : 
     656             :   /**
     657             :    * `true` if we have already noticed that a performance alert should
     658             :    * be raised for this group but we have not dispatched it yet,
     659             :    * `false` otherwise.
     660             :    */
     661             :   bool HasPendingAlert() const;
     662             :   void SetHasPendingAlert(bool value);
     663             : 
     664             : protected:
     665             :   nsPerformanceGroup(nsPerformanceStatsService* service,
     666             :                      const nsAString& name,
     667             :                      const nsAString& groupId,
     668             :                      uint64_t windowId,
     669             :                      uint64_t processId,
     670             :                      bool isSystem,
     671             :                      GroupScope scope);
     672             : 
     673             : 
     674             :   /**
     675             :    * Virtual implementation of `delete`, to make sure that objects are
     676             :    * destoyed with an implementation of `delete` compatible with the
     677             :    * implementation of `new` used to allocate them.
     678             :    *
     679             :    * Called by SpiderMonkey.
     680             :    */
     681           0 :   virtual void Delete() override {
     682           0 :     delete this;
     683           0 :   }
     684             :   ~nsPerformanceGroup();
     685             : 
     686             : private:
     687             :   /**
     688             :    * Identification details for this group.
     689             :    */
     690             :   RefPtr<nsPerformanceGroupDetails> mDetails;
     691             : 
     692             :   /**
     693             :    * The stats service. Used to perform cleanup during destruction.
     694             :    */
     695             :   RefPtr<nsPerformanceStatsService> mService;
     696             : 
     697             :   /**
     698             :    * The scope of this group. Used to determine whether the group
     699             :    * should be (de)activated.
     700             :    */
     701             :   const GroupScope mScope;
     702             : 
     703             : // Observing performance alerts.
     704             : 
     705             : public:
     706             :   /**
     707             :    * The observation target, used to register observers.
     708             :    */
     709             :   nsPerformanceObservationTarget* ObservationTarget() const;
     710             : 
     711             :   /**
     712             :    * Record a jank duration.
     713             :    *
     714             :    * Update the highest recent jank if necessary.
     715             :    */
     716             :   void RecordJank(uint64_t jank);
     717             :   uint64_t HighestRecentJank();
     718             : 
     719             :   /**
     720             :    * Record a CPOW duration.
     721             :    *
     722             :    * Update the highest recent CPOW if necessary.
     723             :    */
     724             :   void RecordCPOW(uint64_t cpow);
     725             :   uint64_t HighestRecentCPOW();
     726             : 
     727             :   /**
     728             :    * Record that this group has recently been involved in handling
     729             :    * user input. Note that heuristics are involved here, so the
     730             :    * result is not 100% accurate.
     731             :    */
     732             :   void RecordUserInput();
     733             :   bool HasRecentUserInput();
     734             : 
     735             :   /**
     736             :    * Reset recent values (recent highest CPOW and jank, involvement in
     737             :    * user input).
     738             :    */
     739             :   void ResetRecent();
     740             : private:
     741             :   /**
     742             :    * The target used by observers to register for watching slow
     743             :    * performance alerts caused by this group.
     744             :    *
     745             :    * May be nullptr for groups that cannot be watched (the top group).
     746             :    */
     747             :   RefPtr<class nsPerformanceObservationTarget> mObservationTarget;
     748             : 
     749             :   /**
     750             :    * The highest jank encountered since jank observers for this group
     751             :    * were last called, in microseconds.
     752             :    */
     753             :   uint64_t mHighestJank;
     754             : 
     755             :   /**
     756             :    * The highest CPOW encountered since jank observers for this group
     757             :    * were last called, in microseconds.
     758             :    */
     759             :   uint64_t mHighestCPOW;
     760             : 
     761             :   /**
     762             :    * `true` if this group has been involved in handling user input,
     763             :    * `false` otherwise.
     764             :    *
     765             :    * Note that we use heuristics to determine whether a group is
     766             :    * involved in handling user input, so this value is not 100%
     767             :    * accurate.
     768             :    */
     769             :   bool mHasRecentUserInput;
     770             : 
     771             :   /**
     772             :    * `true` if this group has caused a performance alert and this alert
     773             :    * hasn't been dispatched yet.
     774             :    *
     775             :    * We use this as part of the buffering of performance alerts. If
     776             :    * the group generates several alerts several times during the
     777             :    * buffering delay, we only wish to add the group once to the list
     778             :    * of alerts.
     779             :    */
     780             :   bool mHasPendingAlert;
     781             : };
     782             : 
     783             : #endif

Generated by: LCOV version 1.13