hotspot/src/share/vm/gc/shared/referenceProcessor.cpp
changeset 33103 116b558af514
parent 32817 acc2744fd84b
child 33105 294e48b4f704
equal deleted inserted replaced
33102:81a6fd1ab98d 33103:116b558af514
    29 #include "gc/shared/collectedHeap.inline.hpp"
    29 #include "gc/shared/collectedHeap.inline.hpp"
    30 #include "gc/shared/gcTimer.hpp"
    30 #include "gc/shared/gcTimer.hpp"
    31 #include "gc/shared/gcTraceTime.hpp"
    31 #include "gc/shared/gcTraceTime.hpp"
    32 #include "gc/shared/referencePolicy.hpp"
    32 #include "gc/shared/referencePolicy.hpp"
    33 #include "gc/shared/referenceProcessor.hpp"
    33 #include "gc/shared/referenceProcessor.hpp"
       
    34 #include "memory/allocation.hpp"
    34 #include "oops/oop.inline.hpp"
    35 #include "oops/oop.inline.hpp"
    35 #include "runtime/java.hpp"
    36 #include "runtime/java.hpp"
    36 #include "runtime/jniHandles.hpp"
    37 #include "runtime/jniHandles.hpp"
    37 
    38 
    38 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
    39 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
   180     total += lists[i].length();
   181     total += lists[i].length();
   181   }
   182   }
   182   return total;
   183   return total;
   183 }
   184 }
   184 
   185 
       
   186 static void log_ref_count(size_t count, bool doit) {
       
   187   if (doit) {
       
   188     gclog_or_tty->print(", " SIZE_FORMAT " refs", count);
       
   189   }
       
   190 }
       
   191 
       
   192 class GCRefTraceTime : public StackObj {
       
   193   GCTraceTimeImpl _gc_trace_time;
       
   194  public:
       
   195   GCRefTraceTime(const char* title, bool doit, GCTimer* timer, GCId gc_id, size_t count) :
       
   196     _gc_trace_time(title, doit, false, timer, gc_id) {
       
   197     log_ref_count(count, doit);
       
   198   }
       
   199 };
       
   200 
   185 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
   201 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
   186   BoolObjectClosure*           is_alive,
   202   BoolObjectClosure*           is_alive,
   187   OopClosure*                  keep_alive,
   203   OopClosure*                  keep_alive,
   188   VoidClosure*                 complete_gc,
   204   VoidClosure*                 complete_gc,
   189   AbstractRefProcTaskExecutor* task_executor,
   205   AbstractRefProcTaskExecutor* task_executor,
   204 
   220 
   205   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
   221   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
   206 
   222 
   207   bool trace_time = PrintGCDetails && PrintReferenceGC;
   223   bool trace_time = PrintGCDetails && PrintReferenceGC;
   208 
   224 
       
   225   // Include cleaners in phantom statistics.  We expect Cleaner
       
   226   // references to be temporary, and don't want to deal with
       
   227   // possible incompatibilities arising from making it more visible.
       
   228   ReferenceProcessorStats stats(
       
   229       total_count(_discoveredSoftRefs),
       
   230       total_count(_discoveredWeakRefs),
       
   231       total_count(_discoveredFinalRefs),
       
   232       total_count(_discoveredPhantomRefs) + total_count(_discoveredCleanerRefs));
       
   233 
   209   // Soft references
   234   // Soft references
   210   size_t soft_count = 0;
       
   211   {
   235   {
   212     GCTraceTime tt("SoftReference", trace_time, false, gc_timer, gc_id);
   236     GCRefTraceTime tt("SoftReference", trace_time, gc_timer, gc_id, stats.soft_count());
   213     soft_count =
   237     process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
   214       process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
   238                                is_alive, keep_alive, complete_gc, task_executor);
   215                                  is_alive, keep_alive, complete_gc, task_executor);
       
   216   }
   239   }
   217 
   240 
   218   update_soft_ref_master_clock();
   241   update_soft_ref_master_clock();
   219 
   242 
   220   // Weak references
   243   // Weak references
   221   size_t weak_count = 0;
       
   222   {
   244   {
   223     GCTraceTime tt("WeakReference", trace_time, false, gc_timer, gc_id);
   245     GCRefTraceTime tt("WeakReference", trace_time, gc_timer, gc_id, stats.weak_count());
   224     weak_count =
   246     process_discovered_reflist(_discoveredWeakRefs, NULL, true,
   225       process_discovered_reflist(_discoveredWeakRefs, NULL, true,
   247                                is_alive, keep_alive, complete_gc, task_executor);
   226                                  is_alive, keep_alive, complete_gc, task_executor);
       
   227   }
   248   }
   228 
   249 
   229   // Final references
   250   // Final references
   230   size_t final_count = 0;
       
   231   {
   251   {
   232     GCTraceTime tt("FinalReference", trace_time, false, gc_timer, gc_id);
   252     GCRefTraceTime tt("FinalReference", trace_time, gc_timer, gc_id, stats.final_count());
   233     final_count =
   253     process_discovered_reflist(_discoveredFinalRefs, NULL, false,
   234       process_discovered_reflist(_discoveredFinalRefs, NULL, false,
   254                                is_alive, keep_alive, complete_gc, task_executor);
   235                                  is_alive, keep_alive, complete_gc, task_executor);
       
   236   }
   255   }
   237 
   256 
   238   // Phantom references
   257   // Phantom references
   239   size_t phantom_count = 0;
       
   240   {
   258   {
   241     GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id);
   259     GCRefTraceTime tt("PhantomReference", trace_time, gc_timer, gc_id, stats.phantom_count());
   242     phantom_count =
   260     process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
   243       process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
   261                                is_alive, keep_alive, complete_gc, task_executor);
   244                                  is_alive, keep_alive, complete_gc, task_executor);
   262 
   245 
   263     // Process cleaners, but include them in phantom timing.  We expect
   246     // Process cleaners, but include them in phantom statistics.  We expect
       
   247     // Cleaner references to be temporary, and don't want to deal with
   264     // Cleaner references to be temporary, and don't want to deal with
   248     // possible incompatibilities arising from making it more visible.
   265     // possible incompatibilities arising from making it more visible.
   249     phantom_count +=
   266     process_discovered_reflist(_discoveredCleanerRefs, NULL, true,
   250       process_discovered_reflist(_discoveredCleanerRefs, NULL, true,
       
   251                                  is_alive, keep_alive, complete_gc, task_executor);
   267                                  is_alive, keep_alive, complete_gc, task_executor);
   252   }
   268   }
   253 
   269 
   254   // Weak global JNI references. It would make more sense (semantically) to
   270   // Weak global JNI references. It would make more sense (semantically) to
   255   // traverse these simultaneously with the regular weak references above, but
   271   // traverse these simultaneously with the regular weak references above, but
   256   // that is not how the JDK1.2 specification is. See #4126360. Native code can
   272   // that is not how the JDK1.2 specification is. See #4126360. Native code can
   257   // thus use JNI weak references to circumvent the phantom references and
   273   // thus use JNI weak references to circumvent the phantom references and
   258   // resurrect a "post-mortem" object.
   274   // resurrect a "post-mortem" object.
   259   {
   275   {
   260     GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id);
   276     GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id);
       
   277     NOT_PRODUCT(log_ref_count(count_jni_refs(), trace_time);)
   261     if (task_executor != NULL) {
   278     if (task_executor != NULL) {
   262       task_executor->set_single_threaded_mode();
   279       task_executor->set_single_threaded_mode();
   263     }
   280     }
   264     process_phaseJNI(is_alive, keep_alive, complete_gc);
   281     process_phaseJNI(is_alive, keep_alive, complete_gc);
   265   }
   282   }
   266 
   283 
   267   return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count);
   284   return stats;
   268 }
   285 }
   269 
   286 
   270 #ifndef PRODUCT
   287 #ifndef PRODUCT
   271 // Calculate the number of jni handles.
   288 // Calculate the number of jni handles.
   272 uint ReferenceProcessor::count_jni_refs() {
   289 uint ReferenceProcessor::count_jni_refs() {
   292 #endif
   309 #endif
   293 
   310 
   294 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
   311 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
   295                                           OopClosure*        keep_alive,
   312                                           OopClosure*        keep_alive,
   296                                           VoidClosure*       complete_gc) {
   313                                           VoidClosure*       complete_gc) {
   297 #ifndef PRODUCT
       
   298   if (PrintGCDetails && PrintReferenceGC) {
       
   299     unsigned int count = count_jni_refs();
       
   300     gclog_or_tty->print(", %u refs", count);
       
   301   }
       
   302 #endif
       
   303   JNIHandles::weak_oops_do(is_alive, keep_alive);
   314   JNIHandles::weak_oops_do(is_alive, keep_alive);
   304   complete_gc->do_void();
   315   complete_gc->do_void();
   305 }
   316 }
   306 
   317 
   307 
   318 
   824   balance_queues(_discoveredFinalRefs);
   835   balance_queues(_discoveredFinalRefs);
   825   balance_queues(_discoveredPhantomRefs);
   836   balance_queues(_discoveredPhantomRefs);
   826   balance_queues(_discoveredCleanerRefs);
   837   balance_queues(_discoveredCleanerRefs);
   827 }
   838 }
   828 
   839 
   829 size_t
   840 void ReferenceProcessor::process_discovered_reflist(
   830 ReferenceProcessor::process_discovered_reflist(
       
   831   DiscoveredList               refs_lists[],
   841   DiscoveredList               refs_lists[],
   832   ReferencePolicy*             policy,
   842   ReferencePolicy*             policy,
   833   bool                         clear_referent,
   843   bool                         clear_referent,
   834   BoolObjectClosure*           is_alive,
   844   BoolObjectClosure*           is_alive,
   835   OopClosure*                  keep_alive,
   845   OopClosure*                  keep_alive,
   848   if ((mt_processing && ParallelRefProcBalancingEnabled) ||
   858   if ((mt_processing && ParallelRefProcBalancingEnabled) ||
   849       must_balance) {
   859       must_balance) {
   850     balance_queues(refs_lists);
   860     balance_queues(refs_lists);
   851   }
   861   }
   852 
   862 
   853   size_t total_list_count = total_count(refs_lists);
       
   854 
       
   855   if (PrintReferenceGC && PrintGCDetails) {
       
   856     gclog_or_tty->print(", " SIZE_FORMAT " refs", total_list_count);
       
   857   }
       
   858 
       
   859   // Phase 1 (soft refs only):
   863   // Phase 1 (soft refs only):
   860   // . Traverse the list and remove any SoftReferences whose
   864   // . Traverse the list and remove any SoftReferences whose
   861   //   referents are not alive, but that should be kept alive for
   865   //   referents are not alive, but that should be kept alive for
   862   //   policy reasons. Keep alive the transitive closure of all
   866   //   policy reasons. Keep alive the transitive closure of all
   863   //   such referents.
   867   //   such referents.
   896     for (uint i = 0; i < _max_num_q; i++) {
   900     for (uint i = 0; i < _max_num_q; i++) {
   897       process_phase3(refs_lists[i], clear_referent,
   901       process_phase3(refs_lists[i], clear_referent,
   898                      is_alive, keep_alive, complete_gc);
   902                      is_alive, keep_alive, complete_gc);
   899     }
   903     }
   900   }
   904   }
   901 
       
   902   return total_list_count;
       
   903 }
   905 }
   904 
   906 
   905 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
   907 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
   906   uint id = 0;
   908   uint id = 0;
   907   // Determine the queue index to use for this object.
   909   // Determine the queue index to use for this object.