/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_LIBARTBASE_BASE_METRICS_METRICS_H_
#define ART_LIBARTBASE_BASE_METRICS_METRICS_H_

#include <stdint.h>

#include <array>
#include <atomic>
#include <optional>
#include <sstream>
#include <string_view>
#include <thread>
#include <vector>

#include "android-base/logging.h"
#include "base/bit_utils.h"
#include "base/macros.h"
#include "base/time_utils.h"
#include "tinyxml2.h"

#pragma clang diagnostic push
#pragma clang diagnostic error "-Wconversion"

// See README.md in this directory for how to define metrics.

// Metrics reported as Event Metrics.
#define ART_EVENT_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(JitMethodCompileTotalTime, MetricsCounter)                 \
  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)  \
  METRIC(GcWorldStopTime, MetricsCounter)                           \
  METRIC(GcWorldStopCount, MetricsCounter)                          \
  METRIC(YoungGcScannedBytes, MetricsCounter)                       \
  METRIC(YoungGcFreedBytes, MetricsCounter)                         \
  METRIC(YoungGcDuration, MetricsCounter)                           \
  METRIC(FullGcScannedBytes, MetricsCounter)                        \
  METRIC(FullGcFreedBytes, MetricsCounter)                          \
  METRIC(FullGcDuration, MetricsCounter)

// Increasing counter metrics, reported as Value Metrics in delta increments.
#define ART_VALUE_METRICS(METRIC)                              \
  METRIC(GcWorldStopTimeDelta, MetricsDeltaCounter)            \
  METRIC(GcWorldStopCountDelta, MetricsDeltaCounter)           \
  METRIC(YoungGcScannedBytesDelta, MetricsDeltaCounter)        \
  METRIC(YoungGcFreedBytesDelta, MetricsDeltaCounter)          \
  METRIC(YoungGcDurationDelta, MetricsDeltaCounter)            \
  METRIC(FullGcScannedBytesDelta, MetricsDeltaCounter)         \
  METRIC(FullGcFreedBytesDelta, MetricsDeltaCounter)           \
  METRIC(FullGcDurationDelta, MetricsDeltaCounter)             \
  METRIC(JitMethodCompileTotalTimeDelta, MetricsDeltaCounter)  \
  METRIC(JitMethodCompileCountDelta, MetricsDeltaCounter)      \
  METRIC(ClassVerificationTotalTimeDelta, MetricsDeltaCounter) \
  METRIC(ClassVerificationCountDelta, MetricsDeltaCounter)     \
  METRIC(ClassLoadingTotalTimeDelta, MetricsDeltaCounter)      \
  METRIC(TotalBytesAllocatedDelta, MetricsDeltaCounter)        \
  METRIC(TotalGcCollectionTimeDelta, MetricsDeltaCounter)      \
  METRIC(YoungGcCountDelta, MetricsDeltaCounter)               \
  METRIC(FullGcCountDelta, MetricsDeltaCounter)

#define ART_METRICS(METRIC) \
  ART_EVENT_METRICS(METRIC) \
  ART_VALUE_METRICS(METRIC)

// 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
// challenging to read. The alternative was to require a lot of boilerplate code for each new metric
// added, all of which would need to be rewritten if the metrics implementation changed. Using
// macros lets us add new metrics by adding a single line to either ART_COUNTERS or ART_HISTOGRAMS,
// and modifying the implementation only requires changing the implementation once, instead of once
// per metric.

namespace art {

class Runtime;
struct RuntimeArgumentMap;

namespace metrics {
template <typename value_t>
class MetricsBase;
}  // namespace metrics

namespace gc {
class HeapTest_GCMetrics_Test;
}  // namespace gc

namespace metrics {

/**
 * An enumeration of all ART counters and histograms.
 */
enum class DatumId {
#define METRIC(name, type, ...) k##name,
  ART_METRICS(METRIC)
#undef METRIC
};

// Names come from PackageManagerServiceCompilerMapping.java
#define REASON_NAME_LIST(V)                                               \
  V(kError, "error")                                                      \
  V(kUnknown, "unknown")                                                  \
  V(kFirstBoot, "first-boot")                                             \
  V(kBootAfterOTA, "boot-after-ota")                                      \
  V(kPostBoot, "post-boot")                                               \
  V(kInstall, "install")                                                  \
  V(kInstallFast, "install-fast")                                         \
  V(kInstallBulk, "install-bulk")                                         \
  V(kInstallBulkSecondary, "install-bulk-secondary")                      \
  V(kInstallBulkDowngraded, "install-bulk-downgraded")                    \
  V(kInstallBulkSecondaryDowngraded, "install-bulk-secondary-downgraded") \
  V(kBgDexopt, "bg-dexopt")                                               \
  V(kABOTA, "ab-ota")                                                     \
  V(kInactive, "inactive")                                                \
  V(kShared, "shared")                                                    \
  V(kInstallWithDexMetadata, "install-with-dex-metadata")                 \
  V(kPrebuilt, "prebuilt")                                                \
  V(kCmdLine, "cmdline")                                                  \
  V(kVdex, "vdex")                                                        \
  V(kBootAfterMainlineUpdate, "boot-after-mainline-update")

// We log compilation reasons as part of the metadata we report. Since elsewhere compilation reasons
// are specified as a string, we define them as an enum here which indicates the reasons that we
// support.
enum class CompilationReason {
#define REASON(kind, name) kind,
  REASON_NAME_LIST(REASON)
#undef REASON
};

#define REASON_NAME(kind, kind_name) \
    case CompilationReason::kind: return kind_name;
#define REASON_FROM_NAME(kind, kind_name) \
    if (name == (kind_name)) { return CompilationReason::kind; }

constexpr const char* CompilationReasonName(CompilationReason reason) {
  switch (reason) {
    REASON_NAME_LIST(REASON_NAME)
  }
}

constexpr CompilationReason CompilationReasonFromName(std::string_view name) {
  REASON_NAME_LIST(REASON_FROM_NAME)
  return CompilationReason::kError;
}

#undef REASON_NAME
#undef REASON_FROM_NAME

#define COMPILER_FILTER_REPORTING_LIST(V) \
  V(kError, "error") /* Error (invalid value) condition */ \
  V(kUnknown, "unknown") /* Unknown (not set) condition */ \
  V(kAssumeVerified, "assume-verified") /* Standard compiler filters */ \
  V(kExtract, "extract") \
  V(kVerify, "verify") \
  V(kSpaceProfile, "space-profile") \
  V(kSpace, "space") \
  V(kSpeedProfile, "speed-profile") \
  V(kSpeed, "speed") \
  V(kEverythingProfile, "everything-profile") \
  V(kEverything, "everything") \
  V(kRunFromApk, "run-from-apk") /* Augmented compiler filters as produces by OatFileAssistant#GetOptimizationStatus */ \
  V(kRunFromApkFallback, "run-from-apk-fallback")

// Augmented compiler filter enum, used in the reporting infra.
enum class CompilerFilterReporting {
#define FILTER(kind, name) kind,
  COMPILER_FILTER_REPORTING_LIST(FILTER)
#undef FILTER
};

#define FILTER_NAME(kind, kind_name) \
    case CompilerFilterReporting::kind: return kind_name;
#define FILTER_FROM_NAME(kind, kind_name) \
    if (name == (kind_name)) { return CompilerFilterReporting::kind; }

constexpr const char* CompilerFilterReportingName(CompilerFilterReporting filter) {
  switch (filter) {
    COMPILER_FILTER_REPORTING_LIST(FILTER_NAME)
  }
}

constexpr CompilerFilterReporting CompilerFilterReportingFromName(std::string_view name) {
  COMPILER_FILTER_REPORTING_LIST(FILTER_FROM_NAME)
  return CompilerFilterReporting::kError;
}

#undef FILTER_NAME
#undef FILTER_FROM_NAME

// SessionData contains metadata about a metrics session (basically the lifetime of an ART process).
// This information should not change for the lifetime of the session.
struct SessionData {
  static SessionData CreateDefault();

  static constexpr int64_t kInvalidSessionId = -1;
  static constexpr int32_t kInvalidUserId = -1;

  int64_t session_id;
  int32_t uid;
  CompilationReason compilation_reason;
  CompilerFilterReporting compiler_filter;
};

// MetricsBackends are used by a metrics reporter to write metrics to some external location. For
// example, a backend might write to logcat, or to a file, or to statsd.
class MetricsBackend {
 public:
  virtual ~MetricsBackend() {}

  // Begins an ART metrics session.
  //
  // This is called by the metrics reporter when the runtime is starting up. The session_data
  // includes a session id which is used to correlate any metric reports with the same instance of
  // the ART runtime. Additionally, session_data includes useful metadata such as the package name
  // for this process.
  //
  // It may also be called whenever there is an update to the session metadata (e.g. optimization
  // state).
  virtual void BeginOrUpdateSession(const SessionData& session_data) = 0;

 protected:
  // Called by the metrics reporter to indicate that a new metrics report is starting.
  virtual void BeginReport(uint64_t timestamp_since_start_ms) = 0;

  // Called by the metrics reporter to give the current value of the counter with id counter_type.
  //
  // This will be called multiple times for each counter based on when the metrics reporter chooses
  // to report metrics. For example, the metrics reporter may call this at shutdown or every N
  // minutes. Counters are not reset in between invocations, so the value should represent the
  // total count at the point this method is called.
  virtual void ReportCounter(DatumId counter_type, uint64_t value) = 0;

  // Called by the metrics reporter to report a histogram.
  //
  // This is called similarly to ReportCounter, but instead of receiving a single value, it receives
  // a vector of the value in each bucket. Additionally, the function receives the lower and upper
  // limit for the histogram. Note that these limits are the allowed limits, and not the observed
  // range. Values below the lower limit will be counted in the first bucket, and values above the
  // upper limit will be counted in the last bucket. Backends should store the minimum and maximum
  // values to allow comparisons across module versions, since the minimum and maximum values may
  // change over time.
  virtual void ReportHistogram(DatumId histogram_type,
                               int64_t minimum_value,
                               int64_t maximum_value,
                               const std::vector<uint32_t>& buckets) = 0;

  // Called by the metrics reporter to indicate that the current metrics report is complete.
  virtual void EndReport() = 0;

  template <DatumId counter_type, typename T>
  friend class MetricsCounter;
  template <DatumId counter_type, typename T>
  friend class MetricsDeltaCounter;
  template <DatumId histogram_type, size_t num_buckets, int64_t low_value, int64_t high_value>
  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;
};

template <typename value_t>
class MetricsBase {
 public:
  virtual void Add(value_t value) = 0;
  virtual ~MetricsBase() { }

 private:
  // Is the metric "null", i.e. never updated or freshly reset?
  // Used for testing purpose only.
  virtual bool IsNull() const = 0;

  ART_FRIEND_TEST(gc::HeapTest, GCMetrics);
};

template <DatumId counter_type, typename T = uint64_t>
class MetricsCounter : 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.
    // 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); }
  void Add(value_t value) override {
    value_.fetch_add(value, std::memory_order::memory_order_relaxed);
  }

  void Report(const std::vector<MetricsBackend*>& backends) const {
    for (MetricsBackend* backend : backends) {
      backend->ReportCounter(counter_type, Value());
    }
  }

 protected:
  void Reset() { value_ = 0; }
  value_t Value() const { return value_.load(std::memory_order::memory_order_relaxed); }

 private:
  bool IsNull() const override { return Value() == 0; }

  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) override {
    MetricsCounter<datum_id, value_t>::Add(value);
    count_.fetch_add(1, std::memory_order::memory_order_release);
  }

  void Report(const std::vector<MetricsBackend*>& backends) const {
    count_t value = MetricsCounter<datum_id, value_t>::Value();
    count_t count = count_.load(std::memory_order::memory_order_acquire);
    // Avoid divide-by-0.
    count_t average_value = count != 0 ? value / count : 0;
    for (MetricsBackend* backend : backends) {
      backend->ReportCounter(datum_id, average_value);
    }
  }

 protected:
  void Reset() {
    count_ = 0;
    MetricsCounter<datum_id, value_t>::Reset();
  }

 private:
  count_t Count() const { return count_.load(std::memory_order::memory_order_relaxed); }

  bool IsNull() const override { return Count() == 0; }

  std::atomic<count_t> count_;
  static_assert(std::atomic<count_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId datum_id, typename T = uint64_t>
class MetricsDeltaCounter : public MetricsBase<T> {
 public:
  using value_t = T;

  explicit constexpr MetricsDeltaCounter(uint64_t value = 0) : value_{value} {
    // 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(uint64_t)));
  }

  void Add(value_t value) override {
    value_.fetch_add(value, std::memory_order::memory_order_relaxed);
  }
  void AddOne() { Add(1u); }

  void ReportAndReset(const std::vector<MetricsBackend*>& backends) {
    value_t value = value_.exchange(0, std::memory_order::memory_order_relaxed);
    for (MetricsBackend* backend : backends) {
      backend->ReportCounter(datum_id, value);
    }
  }

  void Reset() { value_ = 0; }

 private:
  value_t Value() const { return value_.load(std::memory_order::memory_order_relaxed); }

  bool IsNull() const override { return Value() == 0; }

  std::atomic<value_t> value_;
  static_assert(std::atomic<value_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId histogram_type_,
          size_t num_buckets_,
          int64_t minimum_value_,
          int64_t maximum_value_>
class MetricsHistogram final : public MetricsBase<int64_t> {
  static_assert(num_buckets_ >= 1);
  static_assert(minimum_value_ < maximum_value_);

 public:
  using value_t = uint32_t;

  constexpr MetricsHistogram() : buckets_{} {
    // 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) * num_buckets_, sizeof(uint64_t)));
  }

  void Add(int64_t value) override {
    const size_t i = FindBucketId(value);
    buckets_[i].fetch_add(1u, std::memory_order::memory_order_relaxed);
  }

  void Report(const std::vector<MetricsBackend*>& backends) const {
    for (MetricsBackend* backend : backends) {
      backend->ReportHistogram(histogram_type_, minimum_value_, maximum_value_, GetBuckets());
    }
  }

 protected:
  void Reset() {
    for (auto& bucket : buckets_) {
      bucket = 0;
    }
  }

 private:
  inline constexpr size_t FindBucketId(int64_t value) const {
    // Values below the minimum are clamped into the first bucket.
    if (value <= minimum_value_) {
      return 0;
    }
    // Values above the maximum are clamped into the last bucket.
    if (value >= maximum_value_) {
      return num_buckets_ - 1;
    }
    // Otherise, linearly interpolate the value into the right bucket
    constexpr size_t bucket_width = maximum_value_ - minimum_value_;
    return static_cast<size_t>(value - minimum_value_) * num_buckets_ / bucket_width;
  }

  std::vector<value_t> GetBuckets() const {
    // The loads from buckets_ will all be memory_order_seq_cst, which means they will be acquire
    // loads. This is a stricter memory order than is needed, but this should not be a
    // performance-critical section of code.
    return std::vector<value_t>{buckets_.begin(), buckets_.end()};
  }

  bool IsNull() const override {
    std::vector<value_t> buckets = GetBuckets();
    return std::all_of(buckets.cbegin(), buckets.cend(), [](value_t i) { return i == 0; });
  }

  std::array<std::atomic<value_t>, num_buckets_> buckets_;
  static_assert(std::atomic<value_t>::is_always_lock_free);

  friend class ArtMetrics;
};

template <DatumId datum_id, typename T, const T& AccumulatorFunction(const T&, const T&)>
class MetricsAccumulator final : MetricsBase<T> {
 public:
  explicit constexpr MetricsAccumulator(T value = 0) : value_{value} {
    // 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(T), sizeof(uint64_t)));
  }

  void Add(T value) override {
    T current = value_.load(std::memory_order::memory_order_relaxed);
    T new_value;
    do {
      new_value = AccumulatorFunction(current, value);
      // If the value didn't change, don't bother storing it.
      if (current == new_value) {
        break;
      }
    } while (!value_.compare_exchange_weak(
        current, new_value, std::memory_order::memory_order_relaxed));
  }

  // Report the metric as a counter, since this has only a single value.
  void Report(MetricsBackend* backend) const {
    backend->ReportCounter(datum_id, static_cast<uint64_t>(Value()));
  }

 protected:
  void Reset() {
    value_ = 0;
  }

 private:
  T Value() const { return value_.load(std::memory_order::memory_order_relaxed); }

  bool IsNull() const override { return Value() == 0; }

  std::atomic<T> value_;

  friend class ArtMetrics;
};

// Base class for formatting metrics into different formats
// (human-readable text, JSON, etc.)
class MetricsFormatter {
 public:
  virtual ~MetricsFormatter() = default;

  virtual void FormatBeginReport(uint64_t timestamp_since_start_ms,
                                 const std::optional<SessionData>& session_data) = 0;
  virtual void FormatEndReport() = 0;
  virtual void FormatReportCounter(DatumId counter_type, uint64_t value) = 0;
  virtual void FormatReportHistogram(DatumId histogram_type,
                                     int64_t low_value,
                                     int64_t high_value,
                                     const std::vector<uint32_t>& buckets) = 0;
  virtual std::string GetAndResetBuffer() = 0;

 protected:
  const std::string version = "1.0";
};

// Formatter outputting metrics in human-readable text format
class TextFormatter : public MetricsFormatter {
 public:
  TextFormatter() = default;

  void FormatBeginReport(uint64_t timestamp_millis,
                         const std::optional<SessionData>& session_data) override;

  void FormatReportCounter(DatumId counter_type, uint64_t value) override;

  void FormatReportHistogram(DatumId histogram_type,
                             int64_t low_value,
                             int64_t high_value,
                             const std::vector<uint32_t>& buckets) override;

  void FormatEndReport() override;

  std::string GetAndResetBuffer() override;

 private:
  std::ostringstream os_;
};

// Formatter outputting metrics in XML format
class XmlFormatter : public MetricsFormatter {
 public:
  XmlFormatter() = default;

  void FormatBeginReport(uint64_t timestamp_millis,
                         const std::optional<SessionData>& session_data) override;

  void FormatReportCounter(DatumId counter_type, uint64_t value) override;

  void FormatReportHistogram(DatumId histogram_type,
                             int64_t low_value,
                             int64_t high_value,
                             const std::vector<uint32_t>& buckets) override;

  void FormatEndReport() override;

  std::string GetAndResetBuffer() override;

 private:
  tinyxml2::XMLDocument document_;
};

// A backend that writes metrics to a string.
// The format of the metrics' output is delegated
// to the MetricsFormatter class.
//
// This is used as a base for LogBackend and FileBackend.
class StringBackend : public MetricsBackend {
 public:
  explicit StringBackend(std::unique_ptr<MetricsFormatter> formatter);

  void BeginOrUpdateSession(const SessionData& session_data) override;

  void BeginReport(uint64_t timestamp_millis) override;

  void ReportCounter(DatumId counter_type, uint64_t value) override;

  void ReportHistogram(DatumId histogram_type,
                       int64_t low_value,
                       int64_t high_value,
                       const std::vector<uint32_t>& buckets) override;

  void EndReport() override;

  std::string GetAndResetBuffer();

 private:
  std::unique_ptr<MetricsFormatter> formatter_;
  std::optional<SessionData> session_data_;
};

// A backend that writes metrics in human-readable format to the log (i.e. logcat).
class LogBackend : public StringBackend {
 public:
  explicit LogBackend(std::unique_ptr<MetricsFormatter> formatter,
                      android::base::LogSeverity level);

  void BeginReport(uint64_t timestamp_millis) override;
  void EndReport() override;

 private:
  android::base::LogSeverity level_;
};

// A backend that writes metrics to a file.
class FileBackend : public StringBackend {
 public:
  explicit FileBackend(std::unique_ptr<MetricsFormatter> formatter,
                       const std::string& filename);

  void BeginReport(uint64_t timestamp_millis) override;
  void EndReport() override;

 private:
  std::string filename_;
};

/**
 * AutoTimer simplifies time-based metrics collection.
 *
 * Several modes are supported. In the default case, the timer starts immediately and stops when it
 * goes out of scope. Example:
 *
 *     {
 *       AutoTimer timer{metric};
 *       DoStuff();
 *       // timer stops and updates metric automatically here.
 *     }
 *
 * You can also stop the timer early:
 *
 *     timer.Stop();
 *
 * Finally, you can choose to not automatically start the timer at the beginning by passing false as
 * the second argument to the constructor:
 *
 *     AutoTimer timer{metric, false};
 *     DoNotTimeThis();
 *     timer.Start();
 *     TimeThis();
 *
 * Manually started timers will still automatically stop in the destructor, but they can be manually
 * stopped as well.
 *
 * Note that AutoTimer makes calls to MicroTime(), so this may not be suitable on critical paths, or
 * in cases where the counter needs to be started and stopped on different threads.
 */
template <typename Metric>
class AutoTimer {
 public:
  explicit AutoTimer(Metric* metric, bool autostart = true)
      : running_{false}, start_time_microseconds_{}, metric_{metric} {
    if (autostart) {
      Start();
    }
  }

  ~AutoTimer() {
    if (running_) {
      Stop();
    }
  }

  void Start() {
    DCHECK(!running_);
    running_ = true;
    start_time_microseconds_ = MicroTime();
  }

  // Stops a running timer. Returns the time elapsed since starting the timer in microseconds.
  uint64_t Stop() {
    DCHECK(running_);
    uint64_t stop_time_microseconds = MicroTime();
    running_ = false;

    uint64_t elapsed_time = stop_time_microseconds - start_time_microseconds_;
    metric_->Add(static_cast<typename Metric::value_t>(elapsed_time));
    return elapsed_time;
  }

 private:
  bool running_;
  uint64_t start_time_microseconds_;
  Metric* metric_;
};

/**
 * This struct contains all of the metrics that ART reports.
 */
class ArtMetrics {
 public:
  ArtMetrics();

  void ReportAllMetricsAndResetValueMetrics(const std::vector<MetricsBackend*>& backends);
  void DumpForSigQuit(std::ostream& os);

  // Resets all metrics to their initial value. This is intended to be used after forking from the
  // zygote so we don't attribute parent values to the child process.
  void Reset();

#define METRIC_ACCESSORS(name, Kind, ...)                                        \
  Kind<DatumId::k##name, ##__VA_ARGS__>* name() { return &name##_; } \
  const Kind<DatumId::k##name, ##__VA_ARGS__>* name() const { return &name##_; }
  ART_METRICS(METRIC_ACCESSORS)
#undef METRIC_ACCESSORS

 private:
  uint64_t beginning_timestamp_;

#define METRIC(name, Kind, ...) Kind<DatumId::k##name, ##__VA_ARGS__> name##_;
  ART_METRICS(METRIC)
#undef METRIC
};

// Returns a human readable name for the given DatumId.
std::string DatumName(DatumId datum);

// We also log the thread type for metrics so we can distinguish things that block the UI thread
// from things that happen on the background thread. This enum keeps track of what thread types we
// support.
enum class ThreadType {
  kMain,
  kBackground,
};

}  // namespace metrics
}  // namespace art

#pragma clang diagnostic pop  // -Wconversion

#endif  // ART_LIBARTBASE_BASE_METRICS_METRICS_H_
