[metrics] Add total-gc-time and adjust other metrics

This change introduces the following:
1) Added total-gc-collection-time in ms as a counter so that, at anytime,
we can know how much time is spent in GC.
2) Added MetricsAverage to report average of the given data point.
3) Changed mutator-paue-time to average, which makes more sense. Also it
is renamed to world-stop-time.
4) Added averages of gc-throughputs.
5) Removed gc-meta-data-size metric as we don't capture it normally due
to the high cost of capturing this data.

Test: Observe pitot data
Bug: 191404436
Change-Id: I9da7f8c588ac4b42414beedb1b4004e0ac4b5fc2
diff --git a/libartbase/base/metrics/metrics.h b/libartbase/base/metrics/metrics.h
index 78a6387..c9110ee 100644
--- a/libartbase/base/metrics/metrics.h
+++ b/libartbase/base/metrics/metrics.h
@@ -36,22 +36,26 @@
 #pragma clang diagnostic error "-Wconversion"
 
 // See README.md in this directory for how to define metrics.
-#define ART_METRICS(METRIC)                                        \
-  METRIC(ClassLoadingTotalTime, MetricsCounter)                    \
-  METRIC(ClassVerificationTotalTime, MetricsCounter)               \
-  METRIC(ClassVerificationCount, MetricsCounter)                   \
-  METRIC(MutatorPauseTimeDuringGC, MetricsCounter)                 \
-  METRIC(YoungGcCount, MetricsCounter)                             \
-  METRIC(FullGcCount, MetricsCounter)                              \
-  METRIC(TotalBytesAllocated, MetricsCounter)                      \
-  METRIC(TotalGcMetaDataSize, MetricsCounter)                      \
-  METRIC(JitMethodCompileTime, MetricsHistogram, 15, 0, 1'000'000) \
-  METRIC(JitMethodCompileCount, MetricsCounter)                    \
-  METRIC(YoungGcCollectionTime, MetricsHistogram, 15, 0, 60'000)   \
-  METRIC(FullGcCollectionTime, MetricsHistogram, 15, 0, 60'000)    \
-  METRIC(YoungGcThroughput, MetricsHistogram, 15, 0, 10'000)       \
-  METRIC(FullGcThroughput, MetricsHistogram, 15, 0, 10'000)        \
-  METRIC(YoungGcTracingThroughput, MetricsHistogram, 15, 0, 10'000)   \
+#define ART_METRICS(METRIC)                                             \
+  METRIC(ClassLoadingTotalTime, MetricsCounter)                         \
+  METRIC(ClassVerificationTotalTime, MetricsCounter)                    \
+  METRIC(ClassVerificationCount, MetricsCounter)                        \
+  METRIC(WorldStopTimeDuringGCAvg, MetricsAverage)                      \
+  METRIC(YoungGcCount, MetricsCounter)                                  \
+  METRIC(FullGcCount, MetricsCounter)                                   \
+  METRIC(TotalBytesAllocated, MetricsCounter)                           \
+  METRIC(TotalGcCollectionTime, MetricsCounter)                         \
+  METRIC(YoungGcThroughputAvg, MetricsAverage)                          \
+  METRIC(FullGcThroughputAvg, MetricsAverage)                           \
+  METRIC(YoungGcTracingThroughputAvg, MetricsAverage)                   \
+  METRIC(FullGcTracingThroughputAvg, MetricsAverage)                    \
+  METRIC(JitMethodCompileTime, MetricsHistogram, 15, 0, 1'000'000)      \
+  METRIC(JitMethodCompileCount, MetricsCounter)                         \
+  METRIC(YoungGcCollectionTime, MetricsHistogram, 15, 0, 60'000)        \
+  METRIC(FullGcCollectionTime, MetricsHistogram, 15, 0, 60'000)         \
+  METRIC(YoungGcThroughput, MetricsHistogram, 15, 0, 10'000)            \
+  METRIC(FullGcThroughput, MetricsHistogram, 15, 0, 10'000)             \
+  METRIC(YoungGcTracingThroughput, MetricsHistogram, 15, 0, 10'000)     \
   METRIC(FullGcTracingThroughput, MetricsHistogram, 15, 0, 10'000)
 
 // A lot of the metrics implementation code is generated by passing one-off macros into ART_COUNTERS
@@ -262,6 +266,8 @@
   friend class MetricsHistogram;
   template <DatumId datum_id, typename T, const T& AccumulatorFunction(const T&, const T&)>
   friend class MetricsAccumulator;
+  template <DatumId datum_id, typename T>
+  friend class MetricsAverage;
   friend class ArtMetrics;
 };
 
@@ -273,7 +279,7 @@
 };
 
 template <DatumId counter_type, typename T = uint64_t>
-class MetricsCounter final : public MetricsBase<T> {
+class MetricsCounter : public MetricsBase<T> {
  public:
   using value_t = T;
   explicit constexpr MetricsCounter(uint64_t value = 0) : value_{value} {
@@ -294,15 +300,62 @@
     value_ = 0;
   }
 
- private:
   value_t Value() const { return value_.load(std::memory_order::memory_order_relaxed); }
 
+ private:
   std::atomic<value_t> value_;
   static_assert(std::atomic<value_t>::is_always_lock_free);
 
   friend class ArtMetrics;
 };
 
+template <DatumId datum_id, typename T = uint64_t>
+class MetricsAverage final : public MetricsCounter<datum_id, T> {
+ public:
+  using value_t = T;
+  using count_t = T;
+  explicit constexpr MetricsAverage(uint64_t value = 0, uint64_t count = 0) :
+      MetricsCounter<datum_id, value_t>(value), count_(count) {
+    // Ensure we do not have any unnecessary data in this class.
+    // Adding intptr_t to accommodate vtable, and rounding up to incorporate
+    // padding.
+    static_assert(RoundUp(sizeof(*this), sizeof(uint64_t))
+                  == RoundUp(sizeof(intptr_t) + sizeof(value_t) + sizeof(count_t),
+                             sizeof(uint64_t)));
+  }
+
+  // We use release memory-order here and then acquire in Report() to ensure
+  // that at least the non-racy reads/writes to this metric are consistent. This
+  // doesn't guarantee the atomicity of the change to both fields, but that
+  // may not be desired because:
+  // 1. The metric eventually becomes consistent.
+  // 2. For sufficiently large count_, a few data points which are off shouldn't
+  // make a huge difference to the reporter.
+  void Add(value_t value) {
+    MetricsCounter<datum_id, value_t>::Add(value);
+    count_.fetch_add(1, std::memory_order::memory_order_release);
+  }
+
+  void Report(MetricsBackend* backend) const {
+    count_t count = count_.load(std::memory_order::memory_order_acquire);
+    backend->ReportCounter(datum_id,
+                           // Avoid divide-by-0.
+                           count != 0 ? MetricsCounter<datum_id, value_t>::Value() / count : 0);
+  }
+
+ protected:
+  void Reset() {
+    count_ = 0;
+    MetricsCounter<datum_id, value_t>::Reset();
+  }
+
+ private:
+  std::atomic<count_t> count_;
+  static_assert(std::atomic<count_t>::is_always_lock_free);
+
+  friend class ArtMetrics;
+};
+
 template <DatumId histogram_type_,
           size_t num_buckets_,
           int64_t minimum_value_,