Bug 1922722 - Remove default argument from WebRenderBridgeParent::FlushRendering...
[gecko.git] / tools / performance / PerfStats.h
blob0e2baa990f3acc3c582f172c6521e11eaeec3ebd
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef PerfStats_h
8 #define PerfStats_h
10 #include "mozilla/TimeStamp.h"
11 #include "mozilla/StaticMutex.h"
12 #include "mozilla/StaticPtr.h"
13 #include "mozilla/MozPromise.h"
14 #include <memory>
15 #include <string>
16 #include <limits>
18 // PerfStats
20 // Framework for low overhead selective collection of internal performance
21 // metrics through ChromeUtils.
23 // Gathering: in C++, wrap execution in an RAII class
24 // PerfStats::AutoMetricRecording<PerfStats::Metric::MyMetric> or call
25 // PerfStats::RecordMeasurement{Start,End} manually. Use
26 // RecordMeasurementCount() for incrementing counters.
28 // Controlling: Use ChromeUtils.SetPerfStatsCollectionMask(mask), where mask=0
29 // disables all metrics and mask=0xFFFFFFFF enables all of them.
31 // Reporting: Results can be accessed with ChromeUtils.CollectPerfStats().
32 // Browsertime will sum results across processes and report them.
34 // Define a new metric by adding it to this list. It will be created as a class
35 // enum value mozilla::PerfStats::Metric::MyMetricName.
36 #define FOR_EACH_PERFSTATS_METRIC(MACRO) \
37 MACRO(DisplayListBuilding) \
38 MACRO(Rasterizing) \
39 MACRO(WrDisplayListBuilding) \
40 MACRO(LayerTransactions) \
41 MACRO(FrameBuilding) \
42 MACRO(Compositing) \
43 MACRO(Reflowing) \
44 MACRO(Styling) \
45 MACRO(HttpChannelCompletion) \
46 MACRO(HttpChannelCompletion_Network) \
47 MACRO(HttpChannelCompletion_Cache) \
48 MACRO(HttpChannelAsyncOpenToTransactionPending) \
49 MACRO(HttpChannelResponseStartParentToContent) \
50 MACRO(HttpChannelResponseEndParentToContent) \
51 MACRO(HttpTransactionWaitTime) \
52 MACRO(ResponseEndSocketToParent) \
53 MACRO(OnStartRequestSocketToParent) \
54 MACRO(OnDataAvailableSocketToParent) \
55 MACRO(OnStopRequestSocketToParent) \
56 MACRO(OnStartRequestToContent) \
57 MACRO(OnDataAvailableToContent) \
58 MACRO(OnStopRequestToContent) \
59 MACRO(JSBC_Compression) \
60 MACRO(JSBC_Decompression) \
61 MACRO(JSBC_IO_Read) \
62 MACRO(JSBC_IO_Write) \
63 MACRO(MinorGC) \
64 MACRO(MajorGC) \
65 MACRO(NonIdleMajorGC) \
66 MACRO(A11Y_DoInitialUpdate) \
67 MACRO(A11Y_ProcessQueuedCacheUpdate)
69 namespace mozilla {
71 namespace dom {
72 // Forward declaration.
73 class ContentParent;
74 } // namespace dom
76 class PerfStats {
77 public:
78 typedef MozPromise<nsCString, bool, true> PerfStatsPromise;
80 enum class Metric : uint32_t {
81 #define DECLARE_ENUM(metric) metric,
82 FOR_EACH_PERFSTATS_METRIC(DECLARE_ENUM)
83 #undef DECLARE_ENUM
84 Max
87 // MetricMask is a bitmask based on 'Metric', i.e. Metric::LayerBuilding (2)
88 // is synonymous to 1 << 2 in MetricMask.
89 using MetricMask = uint64_t;
91 static void RecordMeasurementStart(Metric aMetric) {
92 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) {
93 return;
95 RecordMeasurementStartInternal(aMetric);
98 static void RecordMeasurementEnd(Metric aMetric) {
99 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) {
100 return;
102 RecordMeasurementEndInternal(aMetric);
105 static void RecordMeasurement(Metric aMetric, TimeDuration aDuration) {
106 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) {
107 return;
109 RecordMeasurementInternal(aMetric, aDuration);
112 static void RecordMeasurementCounter(Metric aMetric,
113 uint64_t aIncrementAmount) {
114 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) {
115 return;
117 RecordMeasurementCounterInternal(aMetric, aIncrementAmount);
120 template <Metric N>
121 class AutoMetricRecording {
122 public:
123 AutoMetricRecording() { PerfStats::RecordMeasurementStart(N); }
124 ~AutoMetricRecording() { PerfStats::RecordMeasurementEnd(N); }
127 static void SetCollectionMask(MetricMask aMask);
128 static MetricMask GetCollectionMask();
130 static RefPtr<PerfStatsPromise> CollectPerfStatsJSON() {
131 return GetSingleton()->CollectPerfStatsJSONInternal();
134 static nsCString CollectLocalPerfStatsJSON() {
135 return GetSingleton()->CollectLocalPerfStatsJSONInternal();
138 static void StorePerfStats(dom::ContentParent* aParent,
139 const nsACString& aPerfStats) {
140 GetSingleton()->StorePerfStatsInternal(aParent, aPerfStats);
143 private:
144 static PerfStats* GetSingleton();
145 static void RecordMeasurementStartInternal(Metric aMetric);
146 static void RecordMeasurementEndInternal(Metric aMetric);
147 static void RecordMeasurementInternal(Metric aMetric, TimeDuration aDuration);
148 static void RecordMeasurementCounterInternal(Metric aMetric,
149 uint64_t aIncrementAmount);
151 void ResetCollection();
152 void StorePerfStatsInternal(dom::ContentParent* aParent,
153 const nsACString& aPerfStats);
154 RefPtr<PerfStatsPromise> CollectPerfStatsJSONInternal();
155 nsCString CollectLocalPerfStatsJSONInternal();
157 static MetricMask sCollectionMask;
158 static StaticMutex sMutex MOZ_UNANNOTATED;
159 static StaticAutoPtr<PerfStats> sSingleton;
160 TimeStamp mRecordedStarts[static_cast<size_t>(Metric::Max)];
161 double mRecordedTimes[static_cast<size_t>(Metric::Max)];
162 uint32_t mRecordedCounts[static_cast<size_t>(Metric::Max)];
163 nsTArray<nsCString> mStoredPerfStats;
166 static_assert(1 << (static_cast<uint64_t>(PerfStats::Metric::Max) - 1) <=
167 std::numeric_limits<PerfStats::MetricMask>::max(),
168 "More metrics than can fit into sCollectionMask bitmask");
170 } // namespace mozilla
172 #endif // PerfStats_h