< prev index next >

src/hotspot/share/gc/shared/referenceProcessor.cpp

Print this page




  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc/shared/collectedHeap.hpp"
  29 #include "gc/shared/collectedHeap.inline.hpp"
  30 #include "gc/shared/gcTimer.hpp"
  31 #include "gc/shared/gcTraceTime.inline.hpp"
  32 #include "gc/shared/referencePolicy.hpp"
  33 #include "gc/shared/referenceProcessor.inline.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/allocation.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "runtime/java.hpp"
  39 #include "runtime/jniHandles.hpp"
  40 
  41 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  42 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  43 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  44 
  45 void referenceProcessor_init() {
  46   ReferenceProcessor::init_statics();
  47 }
  48 
  49 void ReferenceProcessor::init_statics() {
  50   // We need a monotonically non-decreasing time in ms but
  51   // os::javaTimeMillis() does not guarantee monotonicity.
  52   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  53 
  54   // Initialize the soft ref timestamp clock.
  55   _soft_ref_timestamp_clock = now;
  56   // Also update the soft ref clock in j.l.r.SoftReference
  57   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  58 
  59   _always_clear_soft_ref_policy = new AlwaysClearPolicy();


 228   {
 229     RefProcPhaseTimesTracker tt(REF_WEAK, phase_times, this);
 230     process_discovered_reflist(_discoveredWeakRefs, NULL, true,
 231                                is_alive, keep_alive, complete_gc, task_executor, phase_times);
 232   }
 233 
 234   // Final references
 235   {
 236     RefProcPhaseTimesTracker tt(REF_FINAL, phase_times, this);
 237     process_discovered_reflist(_discoveredFinalRefs, NULL, false,
 238                                is_alive, keep_alive, complete_gc, task_executor, phase_times);
 239   }
 240 
 241   // Phantom references
 242   {
 243     RefProcPhaseTimesTracker tt(REF_PHANTOM, phase_times, this);
 244     process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
 245                                is_alive, keep_alive, complete_gc, task_executor, phase_times);
 246   }
 247 
 248   // Weak global JNI references. It would make more sense (semantically) to
 249   // traverse these simultaneously with the regular weak references above, but
 250   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 251   // thus use JNI weak references to circumvent the phantom references and
 252   // resurrect a "post-mortem" object.
 253   {
 254     GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", phase_times->gc_timer());
 255     if (task_executor != NULL) {
 256       task_executor->set_single_threaded_mode();
 257     }
 258     process_phaseJNI(is_alive, keep_alive, complete_gc);
 259   }
 260 
 261   phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000);
 262 
 263   log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());
 264 
 265   return stats;
 266 }
 267 
 268 #ifndef PRODUCT
 269 // Calculate the number of jni handles.
 270 size_t ReferenceProcessor::count_jni_refs() {
 271   class CountHandleClosure: public OopClosure {
 272   private:
 273     size_t _count;
 274   public:
 275     CountHandleClosure(): _count(0) {}
 276     void do_oop(oop* unused)       { _count++; }
 277     void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
 278     size_t count() { return _count; }
 279   };
 280   CountHandleClosure global_handle_count;
 281   JNIHandles::weak_oops_do(&global_handle_count);
 282   return global_handle_count.count();
 283 }
 284 #endif
 285 
 286 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
 287                                           OopClosure*        keep_alive,
 288                                           VoidClosure*       complete_gc) {
 289   JNIHandles::weak_oops_do(is_alive, keep_alive);
 290   complete_gc->do_void();
 291 }
 292 
 293 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor*  task_executor,
 294                                                        ReferenceProcessorPhaseTimes* phase_times) {
 295   // Enqueue references that are not made active again, and
 296   // clear the decks for the next collection (cycle).
 297   enqueue_discovered_reflists(task_executor, phase_times);
 298 
 299   // Stop treating discovered references specially.
 300   disable_discovery();
 301 }
 302 
 303 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
 304   // Given a list of refs linked through the "discovered" field
 305   // (java.lang.ref.Reference.discovered), self-loop their "next" field
 306   // thus distinguishing them from active References, then
 307   // prepend them to the pending list.
 308   //
 309   // The Java threads will see the Reference objects linked together through
 310   // the discovered field. Instead of trying to do the write barrier updates




  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc/shared/collectedHeap.hpp"
  29 #include "gc/shared/collectedHeap.inline.hpp"
  30 #include "gc/shared/gcTimer.hpp"
  31 #include "gc/shared/gcTraceTime.inline.hpp"
  32 #include "gc/shared/referencePolicy.hpp"
  33 #include "gc/shared/referenceProcessor.inline.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/allocation.hpp"
  36 #include "memory/resourceArea.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "runtime/java.hpp"

  39 
  40 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  41 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  42 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  43 
  44 void referenceProcessor_init() {
  45   ReferenceProcessor::init_statics();
  46 }
  47 
  48 void ReferenceProcessor::init_statics() {
  49   // We need a monotonically non-decreasing time in ms but
  50   // os::javaTimeMillis() does not guarantee monotonicity.
  51   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
  52 
  53   // Initialize the soft ref timestamp clock.
  54   _soft_ref_timestamp_clock = now;
  55   // Also update the soft ref clock in j.l.r.SoftReference
  56   java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
  57 
  58   _always_clear_soft_ref_policy = new AlwaysClearPolicy();


 227   {
 228     RefProcPhaseTimesTracker tt(REF_WEAK, phase_times, this);
 229     process_discovered_reflist(_discoveredWeakRefs, NULL, true,
 230                                is_alive, keep_alive, complete_gc, task_executor, phase_times);
 231   }
 232 
 233   // Final references
 234   {
 235     RefProcPhaseTimesTracker tt(REF_FINAL, phase_times, this);
 236     process_discovered_reflist(_discoveredFinalRefs, NULL, false,
 237                                is_alive, keep_alive, complete_gc, task_executor, phase_times);
 238   }
 239 
 240   // Phantom references
 241   {
 242     RefProcPhaseTimesTracker tt(REF_PHANTOM, phase_times, this);
 243     process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
 244                                is_alive, keep_alive, complete_gc, task_executor, phase_times);
 245   }
 246 













 247   phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000);
 248 


 249   return stats;

























 250 }
 251 
 252 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor*  task_executor,
 253                                                        ReferenceProcessorPhaseTimes* phase_times) {
 254   // Enqueue references that are not made active again, and
 255   // clear the decks for the next collection (cycle).
 256   enqueue_discovered_reflists(task_executor, phase_times);
 257 
 258   // Stop treating discovered references specially.
 259   disable_discovery();
 260 }
 261 
 262 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
 263   // Given a list of refs linked through the "discovered" field
 264   // (java.lang.ref.Reference.discovered), self-loop their "next" field
 265   // thus distinguishing them from active References, then
 266   // prepend them to the pending list.
 267   //
 268   // The Java threads will see the Reference objects linked together through
 269   // the discovered field. Instead of trying to do the write barrier updates


< prev index next >