[metrics] Add GC related counters/histograms

Also added a base metrics class.

Test: art/test/testrunner/testrunner.py --host
Bug: 177591729
Bug: 177591724
Bug: 177591575
Change-Id: I8319b134c9afdb674427ea96b2e57e09bb078bb2
diff --git a/libartbase/base/metrics/metrics.h b/libartbase/base/metrics/metrics.h
index ee6b1f8..3ea19c8 100644
--- a/libartbase/base/metrics/metrics.h
+++ b/libartbase/base/metrics/metrics.h
@@ -28,6 +28,7 @@
 #include <vector>
 
 #include "android-base/logging.h"
+#include "base/bit_utils.h"
 #include "base/compiler_filter.h"
 #include "base/time_utils.h"
 
@@ -37,7 +38,8 @@
 // COUNTER(counter_name)
 #define ART_COUNTERS(COUNTER)    \
   COUNTER(ClassLoadingTotalTime) \
-  COUNTER(ClassVerificationTotalTime)
+  COUNTER(ClassVerificationTotalTime) \
+  COUNTER(MutatorPauseTimeDuringGC)
 
 // HISTOGRAM(counter_name, num_buckets, minimum_value, maximum_value)
 //
@@ -52,7 +54,10 @@
 // Values outside the range get clamped to the nearest bucket (basically, the two buckets on either
 // side are infinitely long). If we see those buckets being way taller than the others, it means we
 // should consider expanding the range.
-#define ART_HISTOGRAMS(HISTOGRAM) HISTOGRAM(JitMethodCompileTime, 15, 0, 1'000'000)
+#define ART_HISTOGRAMS(HISTOGRAM) \
+  HISTOGRAM(JitMethodCompileTime, 15, 0, 1'000'000) \
+  HISTOGRAM(YoungGcCollectionTime, 15, 0, 60'000) \
+  HISTOGRAM(FullGcCollectionTime, 15, 0, 60'000)
 
 // A lot of the metrics implementation code is generated by passing one-off macros into ART_COUNTERS
 // and ART_HISTOGRAMS. This means metrics.h and metrics.cc are very #define-heavy, which can be
@@ -180,21 +185,30 @@
   // Called by the metrics reporter to indicate that the current metrics report is complete.
   virtual void EndReport() = 0;
 
-  template <DatumId counter_type>
+  template <DatumId counter_type, typename T>
   friend class MetricsCounter;
   template <DatumId histogram_type, size_t num_buckets, int64_t low_value, int64_t high_value>
   friend class MetricsHistogram;
   friend class ArtMetrics;
 };
 
-template <DatumId counter_type>
-class MetricsCounter {
+template <typename value_t>
+class MetricsBase {
  public:
-  using value_t = uint64_t;
+  virtual void Add(value_t value) = 0;
+  virtual ~MetricsBase() { }
+};
 
+template <DatumId counter_type, typename T = uint64_t>
+class MetricsCounter final : public MetricsBase<T> {
+ public:
+  using value_t = T;
   explicit constexpr MetricsCounter(uint64_t value = 0) : value_{value} {
     // Ensure we do not have any unnecessary data in this class.
-    static_assert(sizeof(*this) == sizeof(uint64_t));
+    // 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(uint64_t)));
   }
 
   void AddOne() { Add(1u); }
@@ -213,7 +227,7 @@
           size_t num_buckets_,
           int64_t minimum_value_,
           int64_t maximum_value_>
-class MetricsHistogram {
+class MetricsHistogram final : public MetricsBase<int64_t> {
   static_assert(num_buckets_ >= 1);
   static_assert(minimum_value_ < maximum_value_);
 
@@ -222,7 +236,10 @@
 
   constexpr MetricsHistogram() : buckets_{} {
     // Ensure we do not have any unnecessary data in this class.
-    static_assert(sizeof(*this) == sizeof(uint32_t) * num_buckets_);
+    // 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) * num_buckets_, sizeof(uint64_t)));
   }
 
   void Add(int64_t value) {