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/. */
10 #include "mozilla/TimeStamp.h"
11 #include "mozilla/StaticMutex.h"
12 #include "mozilla/StaticPtr.h"
13 #include "mozilla/MozPromise.h"
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) \
39 MACRO(WrDisplayListBuilding) \
40 MACRO(LayerTransactions) \
44 MACRO(HttpChannelCompletion) \
45 MACRO(HttpChannelCompletion_Network) \
46 MACRO(HttpChannelCompletion_Cache) \
47 MACRO(HttpChannelAsyncOpenToTransactionPending) \
48 MACRO(HttpChannelResponseStartParentToContent) \
49 MACRO(HttpChannelResponseEndParentToContent) \
50 MACRO(HttpTransactionWaitTime) \
51 MACRO(ResponseEndSocketToParent) \
52 MACRO(OnStartRequestSocketToParent) \
53 MACRO(OnDataAvailableSocketToParent) \
54 MACRO(OnStopRequestSocketToParent) \
55 MACRO(OnStartRequestToContent) \
56 MACRO(OnDataAvailableToContent) \
57 MACRO(OnStopRequestToContent) \
58 MACRO(JSBC_Compression) \
59 MACRO(JSBC_Decompression) \
61 MACRO(JSBC_IO_Write) \
64 MACRO(NonIdleMajorGC) \
65 MACRO(A11Y_DoInitialUpdate) \
66 MACRO(A11Y_ProcessQueuedCacheUpdate)
71 // Forward declaration.
77 typedef MozPromise
<nsCString
, bool, true> PerfStatsPromise
;
79 enum class Metric
: uint32_t {
80 #define DECLARE_ENUM(metric) metric,
81 FOR_EACH_PERFSTATS_METRIC(DECLARE_ENUM
)
86 // MetricMask is a bitmask based on 'Metric', i.e. Metric::LayerBuilding (2)
87 // is synonymous to 1 << 2 in MetricMask.
88 using MetricMask
= uint64_t;
90 static void RecordMeasurementStart(Metric aMetric
) {
91 if (!(sCollectionMask
& (1 << static_cast<uint64_t>(aMetric
)))) {
94 RecordMeasurementStartInternal(aMetric
);
97 static void RecordMeasurementEnd(Metric aMetric
) {
98 if (!(sCollectionMask
& (1 << static_cast<uint64_t>(aMetric
)))) {
101 RecordMeasurementEndInternal(aMetric
);
104 static void RecordMeasurement(Metric aMetric
, TimeDuration aDuration
) {
105 if (!(sCollectionMask
& (1 << static_cast<uint64_t>(aMetric
)))) {
108 RecordMeasurementInternal(aMetric
, aDuration
);
111 static void RecordMeasurementCounter(Metric aMetric
,
112 uint64_t aIncrementAmount
) {
113 if (!(sCollectionMask
& (1 << static_cast<uint64_t>(aMetric
)))) {
116 RecordMeasurementCounterInternal(aMetric
, aIncrementAmount
);
120 class AutoMetricRecording
{
122 AutoMetricRecording() { PerfStats::RecordMeasurementStart(N
); }
123 ~AutoMetricRecording() { PerfStats::RecordMeasurementEnd(N
); }
126 static void SetCollectionMask(MetricMask aMask
);
127 static MetricMask
GetCollectionMask();
129 static RefPtr
<PerfStatsPromise
> CollectPerfStatsJSON() {
130 return GetSingleton()->CollectPerfStatsJSONInternal();
133 static nsCString
CollectLocalPerfStatsJSON() {
134 return GetSingleton()->CollectLocalPerfStatsJSONInternal();
137 static void StorePerfStats(dom::ContentParent
* aParent
,
138 const nsACString
& aPerfStats
) {
139 GetSingleton()->StorePerfStatsInternal(aParent
, aPerfStats
);
143 static PerfStats
* GetSingleton();
144 static void RecordMeasurementStartInternal(Metric aMetric
);
145 static void RecordMeasurementEndInternal(Metric aMetric
);
146 static void RecordMeasurementInternal(Metric aMetric
, TimeDuration aDuration
);
147 static void RecordMeasurementCounterInternal(Metric aMetric
,
148 uint64_t aIncrementAmount
);
150 void ResetCollection();
151 void StorePerfStatsInternal(dom::ContentParent
* aParent
,
152 const nsACString
& aPerfStats
);
153 RefPtr
<PerfStatsPromise
> CollectPerfStatsJSONInternal();
154 nsCString
CollectLocalPerfStatsJSONInternal();
156 static MetricMask sCollectionMask
;
157 static StaticMutex sMutex MOZ_UNANNOTATED
;
158 static StaticAutoPtr
<PerfStats
> sSingleton
;
159 TimeStamp mRecordedStarts
[static_cast<size_t>(Metric::Max
)];
160 double mRecordedTimes
[static_cast<size_t>(Metric::Max
)];
161 uint32_t mRecordedCounts
[static_cast<size_t>(Metric::Max
)];
162 nsTArray
<nsCString
> mStoredPerfStats
;
165 static_assert(1 << (static_cast<uint64_t>(PerfStats::Metric::Max
) - 1) <=
166 std::numeric_limits
<PerfStats::MetricMask
>::max(),
167 "More metrics than can fit into sCollectionMask bitmask");
169 } // namespace mozilla
171 #endif // PerfStats_h