src/share/vm/memory/referenceProcessor.cpp

Print this page
rev 2869 : 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
Summary: Replaces calls to os::javaTimeMillis(), which does not guarantee montonicity, in GC code to os::javaTimeNanos() with a suitable conversion factor. os::javaTimeNanos() mostly guarantees montonicity depending on the underlying OS implementation and, as a result, a better alternative. Changes in OS files are to make use of the newly defined constants in globalDefinitions.hpp.
Reviewed-by:


  26 #include "classfile/javaClasses.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc_interface/collectedHeap.hpp"
  29 #include "gc_interface/collectedHeap.inline.hpp"
  30 #include "memory/referencePolicy.hpp"
  31 #include "memory/referenceProcessor.hpp"
  32 #include "oops/oop.inline.hpp"
  33 #include "runtime/java.hpp"
  34 #include "runtime/jniHandles.hpp"
  35 
  36 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  37 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  38 bool             ReferenceProcessor::_pending_list_uses_discovered_field = false;
  39 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  40 
  41 void referenceProcessor_init() {
  42   ReferenceProcessor::init_statics();
  43 }
  44 
  45 void ReferenceProcessor::init_statics() {
  46   jlong now = os::javaTimeMillis();

  47 
  48   // Initialize the soft ref timestamp clock.
  49   _soft_ref_timestamp_clock = now;
  50   // Also update the soft ref clock in j.l.r.SoftReference
  51   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  52 
  53   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
  54   _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
  55                                       NOT_COMPILER2(LRUCurrentHeapPolicy());
  56   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
  57     vm_exit_during_initialization("Could not allocate reference policy object");
  58   }
  59   guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
  60             RefDiscoveryPolicy == ReferentBasedDiscovery,
  61             "Unrecongnized RefDiscoveryPolicy");
  62   _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
  63 }
  64 
  65 void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) {
  66 #ifdef ASSERT


 134   for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 135     guarantee(_discovered_refs[i].is_empty(),
 136               "Found non-empty discovered list");
 137   }
 138 }
 139 #endif
 140 
 141 void ReferenceProcessor::weak_oops_do(OopClosure* f) {
 142   for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 143     if (UseCompressedOops) {
 144       f->do_oop((narrowOop*)_discovered_refs[i].adr_head());
 145     } else {
 146       f->do_oop((oop*)_discovered_refs[i].adr_head());
 147     }
 148   }
 149 }
 150 
 151 void ReferenceProcessor::update_soft_ref_master_clock() {
 152   // Update (advance) the soft ref master clock field. This must be done
 153   // after processing the soft ref list.
 154   jlong now = os::javaTimeMillis();


 155   jlong soft_ref_clock = java_lang_ref_SoftReference::clock();
 156   assert(soft_ref_clock == _soft_ref_timestamp_clock, "soft ref clocks out of sync");
 157 
 158   NOT_PRODUCT(
 159   if (now < _soft_ref_timestamp_clock) {
 160     warning("time warp: "INT64_FORMAT" to "INT64_FORMAT,
 161             _soft_ref_timestamp_clock, now);
 162   }
 163   )
 164   // In product mode, protect ourselves from system time being adjusted
 165   // externally and going backward; see note in the implementation of
 166   // GenCollectedHeap::time_since_last_gc() for the right way to fix
 167   // this uniformly throughout the VM; see bug-id 4741166. XXX
 168   if (now > _soft_ref_timestamp_clock) {
 169     _soft_ref_timestamp_clock = now;
 170     java_lang_ref_SoftReference::set_clock(now);
 171   }
 172   // Else leave clock stalled at its old value until time progresses
 173   // past clock value.
 174 }




  26 #include "classfile/javaClasses.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc_interface/collectedHeap.hpp"
  29 #include "gc_interface/collectedHeap.inline.hpp"
  30 #include "memory/referencePolicy.hpp"
  31 #include "memory/referenceProcessor.hpp"
  32 #include "oops/oop.inline.hpp"
  33 #include "runtime/java.hpp"
  34 #include "runtime/jniHandles.hpp"
  35 
  36 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  37 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  38 bool             ReferenceProcessor::_pending_list_uses_discovered_field = false;
  39 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  40 
  41 void referenceProcessor_init() {
  42   ReferenceProcessor::init_statics();
  43 }
  44 
  45 void ReferenceProcessor::init_statics() {
  46   // os::javaTimeMillis() does not guarantee monotonicity.
  47   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  48 
  49   // Initialize the soft ref timestamp clock.
  50   _soft_ref_timestamp_clock = now;
  51   // Also update the soft ref clock in j.l.r.SoftReference
  52   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  53 
  54   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
  55   _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
  56                                       NOT_COMPILER2(LRUCurrentHeapPolicy());
  57   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
  58     vm_exit_during_initialization("Could not allocate reference policy object");
  59   }
  60   guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
  61             RefDiscoveryPolicy == ReferentBasedDiscovery,
  62             "Unrecongnized RefDiscoveryPolicy");
  63   _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
  64 }
  65 
  66 void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) {
  67 #ifdef ASSERT


 135   for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 136     guarantee(_discovered_refs[i].is_empty(),
 137               "Found non-empty discovered list");
 138   }
 139 }
 140 #endif
 141 
 142 void ReferenceProcessor::weak_oops_do(OopClosure* f) {
 143   for (int i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 144     if (UseCompressedOops) {
 145       f->do_oop((narrowOop*)_discovered_refs[i].adr_head());
 146     } else {
 147       f->do_oop((oop*)_discovered_refs[i].adr_head());
 148     }
 149   }
 150 }
 151 
 152 void ReferenceProcessor::update_soft_ref_master_clock() {
 153   // Update (advance) the soft ref master clock field. This must be done
 154   // after processing the soft ref list.
 155 
 156   // os::javaTimeMillis() does not guarantee monotonicity.
 157   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
 158   jlong soft_ref_clock = java_lang_ref_SoftReference::clock();
 159   assert(soft_ref_clock == _soft_ref_timestamp_clock, "soft ref clocks out of sync");
 160 
 161   NOT_PRODUCT(
 162   if (now < _soft_ref_timestamp_clock) {
 163     warning("time warp: "INT64_FORMAT" to "INT64_FORMAT,
 164             _soft_ref_timestamp_clock, now);
 165   }
 166   )
 167   // In product mode, protect ourselves from system time being adjusted
 168   // externally and going backward; see note in the implementation of
 169   // GenCollectedHeap::time_since_last_gc() for the right way to fix
 170   // this uniformly throughout the VM; see bug-id 4741166. XXX
 171   if (now > _soft_ref_timestamp_clock) {
 172     _soft_ref_timestamp_clock = now;
 173     java_lang_ref_SoftReference::set_clock(now);
 174   }
 175   // Else leave clock stalled at its old value until time progresses
 176   // past clock value.
 177 }