Reducing CPU impact of non-monotonic clocks on Gc.

Adding a ceiling for the Gc's histogram's num_of_windows count, ensuring the
number of data points to insert does not become extremely large when time
changes unexpectedly. This may happen when the time source is not monotonic.

Bug: 123365804
Test: confirmed the fix behaves as intended on a system with an erratic clock
Change-Id: Idd3560204d3392fe247b65d383c41de2eaf8d35c
Signed-off-by: Vincent Palomares <paillon@google.com>
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 5f62d75..8020f86 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2878,6 +2878,15 @@
   DCHECK_GE(now, last_update_time_gc_count_rate_histograms_);
   uint64_t time_since_last_update = now - last_update_time_gc_count_rate_histograms_;
   uint64_t num_of_windows = time_since_last_update / kGcCountRateHistogramWindowDuration;
+
+  // The computed number of windows can be incoherently high if NanoTime() is not monotonic.
+  // Setting a limit on its maximum value reduces the impact on CPU time in such cases.
+  if (num_of_windows > kGcCountRateHistogramMaxNumMissedWindows) {
+    LOG(WARNING) << "Reducing the number of considered missed Gc histogram windows from "
+                 << num_of_windows << " to " << kGcCountRateHistogramMaxNumMissedWindows;
+    num_of_windows = kGcCountRateHistogramMaxNumMissedWindows;
+  }
+
   if (time_since_last_update >= kGcCountRateHistogramWindowDuration) {
     // Record the first window.
     gc_count_rate_histogram_.AddValue(gc_count_last_window_ - 1);  // Exclude the current run.