8164482: [REDO] G1 does not implement millis_since_last_gc which is needed by RMI GC
authorjprovino
Tue, 20 Sep 2016 10:27:51 -0400
changeset 41284 b4276ec89d0d
parent 41182 dbd59c1da636
child 41285 0eb0a2183ff2
8164482: [REDO] G1 does not implement millis_since_last_gc which is needed by RMI GC Summary: G1 does not return a correct value for the CollectedHeap::millis_since_last_gc() Reviewed-by: tschatzl, kbarrett
hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp
hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp
hotspot/src/share/vm/gc/g1/g1Policy.hpp
hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Sun Sep 18 21:10:48 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Tue Sep 20 10:27:51 2016 -0400
@@ -2474,8 +2474,16 @@
 }
 
 jlong G1CollectedHeap::millis_since_last_gc() {
-  // assert(false, "NYI");
-  return 0;
+  // See the notes in GenCollectedHeap::millis_since_last_gc()
+  // for more information about the implementation.
+  jlong ret_val = (os::javaTimeNanos() / NANOSECS_PER_MILLISEC) -
+    _g1_policy->collection_pause_end_millis();
+  if (ret_val < 0) {
+    log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT
+      ". returning zero instead.", ret_val);
+    return 0;
+  }
+  return ret_val;
 }
 
 void G1CollectedHeap::prepare_for_verify() {
--- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp	Sun Sep 18 21:10:48 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.cpp	Tue Sep 20 10:27:51 2016 -0400
@@ -66,7 +66,8 @@
   _phase_times(new G1GCPhaseTimes(ParallelGCThreads)),
   _tenuring_threshold(MaxTenuringThreshold),
   _max_survivor_regions(0),
-  _survivors_age_table(true) { }
+  _survivors_age_table(true),
+  _collection_pause_end_millis(os::javaTimeNanos() / NANOSECS_PER_MILLISEC) { }
 
 G1DefaultPolicy::~G1DefaultPolicy() {
   delete _ihop_control;
@@ -575,6 +576,8 @@
 
   record_pause(young_gc_pause_kind(), end_time_sec - pause_time_ms / 1000.0, end_time_sec);
 
+  _collection_pause_end_millis = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
+
   last_pause_included_initial_mark = collector_state()->during_initial_mark_pause();
   if (last_pause_included_initial_mark) {
     record_concurrent_mark_init_end(0.0);
--- a/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp	Sun Sep 18 21:10:48 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1DefaultPolicy.hpp	Tue Sep 20 10:27:51 2016 -0400
@@ -64,6 +64,8 @@
 
   double _full_collection_start_sec;
 
+  jlong _collection_pause_end_millis;
+
   uint _young_list_target_length;
   uint _young_list_fixed_length;
 
@@ -237,6 +239,8 @@
 
   double reclaimable_bytes_perc(size_t reclaimable_bytes) const;
 
+  jlong collection_pause_end_millis() { return _collection_pause_end_millis; }
+
 private:
   // Sets up marking if proper conditions are met.
   void maybe_start_marking();
--- a/hotspot/src/share/vm/gc/g1/g1Policy.hpp	Sun Sep 18 21:10:48 2016 -0400
+++ b/hotspot/src/share/vm/gc/g1/g1Policy.hpp	Tue Sep 20 10:27:51 2016 -0400
@@ -119,6 +119,8 @@
   virtual void record_full_collection_start() = 0;
   virtual void record_full_collection_end() = 0;
 
+  virtual jlong collection_pause_end_millis() = 0;
+
   // Must currently be called while the world is stopped.
   virtual void record_concurrent_mark_init_end(double mark_init_elapsed_time_ms) = 0;
 
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Sun Sep 18 21:10:48 2016 -0400
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp	Tue Sep 20 10:27:51 2016 -0400
@@ -1256,21 +1256,20 @@
 };
 
 jlong GenCollectedHeap::millis_since_last_gc() {
-  // We need a monotonically non-decreasing time in ms but
-  // os::javaTimeMillis() does not guarantee monotonicity.
+  // javaTimeNanos() is guaranteed to be monotonically non-decreasing
+  // provided the underlying platform provides such a time source
+  // (and it is bug free). So we still have to guard against getting
+  // back a time later than 'now'.
   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   GenTimeOfLastGCClosure tolgc_cl(now);
   // iterate over generations getting the oldest
   // time that a generation was collected
   generation_iterate(&tolgc_cl, false);
 
-  // javaTimeNanos() is guaranteed to be monotonically non-decreasing
-  // provided the underlying platform provides such a time source
-  // (and it is bug free). So we still have to guard against getting
-  // back a time later than 'now'.
   jlong retVal = now - tolgc_cl.time();
   if (retVal < 0) {
-    NOT_PRODUCT(log_warning(gc)("time warp: " JLONG_FORMAT, retVal);)
+    log_warning(gc)("millis_since_last_gc() would return : " JLONG_FORMAT
+       ". returning zero instead.", retVal);
     return 0;
   }
   return retVal;