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/. */ 6 7 #ifndef PerfStats_h 8 #define PerfStats_h 9 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> 17 18 namespace mozilla { 19 20 class PerfStats { 21 public: 22 typedef MozPromise<nsCString, bool, true> PerfStatsPromise; 23 24 enum class Metric : uint32_t { 25 DisplayListBuilding = 0, 26 Rasterizing, 27 LayerBuilding, 28 LayerTransactions, 29 Compositing, 30 Reflowing, 31 Styling, 32 HttpChannelCompletion, 33 HttpChannelCompletion_Network, 34 HttpChannelCompletion_Cache, 35 Max 36 }; 37 38 // MetricMask is a bitmask based on 'Metric', i.e. Metric::LayerBuilding (2) 39 // is synonymous to 1 << 2 in MetricMask. 40 using MetricMask = uint64_t; 41 RecordMeasurementStart(Metric aMetric)42 static void RecordMeasurementStart(Metric aMetric) { 43 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) { 44 return; 45 } 46 RecordMeasurementStartInternal(aMetric); 47 } 48 RecordMeasurementEnd(Metric aMetric)49 static void RecordMeasurementEnd(Metric aMetric) { 50 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) { 51 return; 52 } 53 RecordMeasurementEndInternal(aMetric); 54 } 55 RecordMeasurement(Metric aMetric,TimeDuration aDuration)56 static void RecordMeasurement(Metric aMetric, TimeDuration aDuration) { 57 if (!(sCollectionMask & (1 << static_cast<uint64_t>(aMetric)))) { 58 return; 59 } 60 RecordMeasurementInternal(aMetric, aDuration); 61 } 62 63 template <Metric N> 64 class AutoMetricRecording { 65 public: AutoMetricRecording()66 AutoMetricRecording() { PerfStats::RecordMeasurementStart(N); } ~AutoMetricRecording()67 ~AutoMetricRecording() { PerfStats::RecordMeasurementEnd(N); } 68 }; 69 70 static void SetCollectionMask(MetricMask aMask); 71 CollectPerfStatsJSON()72 static RefPtr<PerfStatsPromise> CollectPerfStatsJSON() { 73 return GetSingleton()->CollectPerfStatsJSONInternal(); 74 } 75 CollectLocalPerfStatsJSON()76 static nsCString CollectLocalPerfStatsJSON() { 77 return GetSingleton()->CollectLocalPerfStatsJSONInternal(); 78 } 79 80 private: 81 static PerfStats* GetSingleton(); 82 static void RecordMeasurementStartInternal(Metric aMetric); 83 static void RecordMeasurementEndInternal(Metric aMetric); 84 static void RecordMeasurementInternal(Metric aMetric, TimeDuration aDuration); 85 86 RefPtr<PerfStatsPromise> CollectPerfStatsJSONInternal(); 87 nsCString CollectLocalPerfStatsJSONInternal(); 88 89 static MetricMask sCollectionMask; 90 static StaticMutex sMutex; 91 static StaticAutoPtr<PerfStats> sSingleton; 92 TimeStamp mRecordedStarts[static_cast<size_t>(Metric::Max)]; 93 double mRecordedTimes[static_cast<size_t>(Metric::Max)]; 94 }; 95 96 static_assert(1 << (static_cast<uint64_t>(PerfStats::Metric::Max) - 1) <= 97 std::numeric_limits<PerfStats::MetricMask>::max(), 98 "More metrics than can fit into sCollectionMask bitmask"); 99 100 } // namespace mozilla 101 102 #endif // PerfStats_h 103