src/share/vm/memory/referenceProcessor.cpp

Print this page
rev 2870 : 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 is guaranteed monotonic if the underlying platform provides a monotonic timesource. Changes in OS files are to make use of the newly defined constants in globalDefinitions.hpp.
Reviewed-by: dholmes


  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   // We need a montonically increasing time in ms but os::javaTimeMillis()
  47   // does not guarantee montonicity.
  48   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  49 
  50   // Initialize the soft ref timestamp clock.
  51   _soft_ref_timestamp_clock = now;
  52   // Also update the soft ref clock in j.l.r.SoftReference
  53   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  54 
  55   _always_clear_soft_ref_policy = new AlwaysClearPolicy();
  56   _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
  57                                       NOT_COMPILER2(LRUCurrentHeapPolicy());
  58   if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
  59     vm_exit_during_initialization("Could not allocate reference policy object");
  60   }
  61   guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
  62             RefDiscoveryPolicy == ReferentBasedDiscovery,
  63             "Unrecongnized RefDiscoveryPolicy");
  64   _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
  65 }
  66 
  67 void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) {
  68 #ifdef ASSERT


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