src/share/vm/memory/referenceProcessor.cpp

Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
   1 /*
   2  * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  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.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 monotonically non-deccreasing time in ms but
  47   // os::javaTimeMillis() does not guarantee monotonicity.


 163 
 164   NOT_PRODUCT(
 165   if (now < _soft_ref_timestamp_clock) {
 166     warning("time warp: "INT64_FORMAT" to "INT64_FORMAT,
 167             _soft_ref_timestamp_clock, now);
 168   }
 169   )
 170   // The values of now and _soft_ref_timestamp_clock are set using
 171   // javaTimeNanos(), which is guaranteed to be monotonically
 172   // non-decreasing provided the underlying platform provides such
 173   // a time source (and it is bug free).
 174   // In product mode, however, protect ourselves from non-monotonicty.
 175   if (now > _soft_ref_timestamp_clock) {
 176     _soft_ref_timestamp_clock = now;
 177     java_lang_ref_SoftReference::set_clock(now);
 178   }
 179   // Else leave clock stalled at its old value until time progresses
 180   // past clock value.
 181 }
 182 
 183 void ReferenceProcessor::process_discovered_references(








 184   BoolObjectClosure*           is_alive,
 185   OopClosure*                  keep_alive,
 186   VoidClosure*                 complete_gc,
 187   AbstractRefProcTaskExecutor* task_executor) {

 188   NOT_PRODUCT(verify_ok_to_handle_reflists());
 189 
 190   assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
 191   // Stop treating discovered references specially.
 192   disable_discovery();
 193 
 194   // If discovery was concurrent, someone could have modified
 195   // the value of the static field in the j.l.r.SoftReference
 196   // class that holds the soft reference timestamp clock using
 197   // reflection or Unsafe between when discovery was enabled and
 198   // now. Unconditionally update the static field in ReferenceProcessor
 199   // here so that we use the new value during processing of the
 200   // discovered soft refs.
 201 
 202   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
 203 
 204   bool trace_time = PrintGCDetails && PrintReferenceGC;

 205   // Soft references

 206   {
 207     TraceTime tt("SoftReference", trace_time, false, gclog_or_tty);

 208     process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
 209                                is_alive, keep_alive, complete_gc, task_executor);
 210   }
 211 
 212   update_soft_ref_master_clock();
 213 
 214   // Weak references

 215   {
 216     TraceTime tt("WeakReference", trace_time, false, gclog_or_tty);

 217     process_discovered_reflist(_discoveredWeakRefs, NULL, true,
 218                                is_alive, keep_alive, complete_gc, task_executor);
 219   }
 220 
 221   // Final references

 222   {
 223     TraceTime tt("FinalReference", trace_time, false, gclog_or_tty);

 224     process_discovered_reflist(_discoveredFinalRefs, NULL, false,
 225                                is_alive, keep_alive, complete_gc, task_executor);
 226   }
 227 
 228   // Phantom references

 229   {
 230     TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty);

 231     process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
 232                                is_alive, keep_alive, complete_gc, task_executor);
 233   }
 234 
 235   // Weak global JNI references. It would make more sense (semantically) to
 236   // traverse these simultaneously with the regular weak references above, but
 237   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 238   // thus use JNI weak references to circumvent the phantom references and
 239   // resurrect a "post-mortem" object.
 240   {
 241     TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty);
 242     if (task_executor != NULL) {
 243       task_executor->set_single_threaded_mode();
 244     }
 245     process_phaseJNI(is_alive, keep_alive, complete_gc);
 246   }


 247 }
 248 
 249 #ifndef PRODUCT
 250 // Calculate the number of jni handles.
 251 uint ReferenceProcessor::count_jni_refs() {
 252   class AlwaysAliveClosure: public BoolObjectClosure {
 253   public:
 254     virtual bool do_object_b(oop obj) { return true; }
 255   };
 256 
 257   class CountHandleClosure: public OopClosure {
 258   private:
 259     int _count;
 260   public:
 261     CountHandleClosure(): _count(0) {}
 262     void do_oop(oop* unused)       { _count++; }
 263     void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
 264     int count() { return _count; }
 265   };
 266   CountHandleClosure global_handle_count;


 861     balanced_total_refs += ref_lists[i].length();
 862     if (TraceReferenceGC && PrintGCDetails) {
 863       gclog_or_tty->print("%d ", ref_lists[i].length());
 864     }
 865   }
 866   if (TraceReferenceGC && PrintGCDetails) {
 867     gclog_or_tty->print_cr(" = %d", balanced_total_refs);
 868     gclog_or_tty->flush();
 869   }
 870   assert(total_refs == balanced_total_refs, "Balancing was incomplete");
 871 #endif
 872 }
 873 
 874 void ReferenceProcessor::balance_all_queues() {
 875   balance_queues(_discoveredSoftRefs);
 876   balance_queues(_discoveredWeakRefs);
 877   balance_queues(_discoveredFinalRefs);
 878   balance_queues(_discoveredPhantomRefs);
 879 }
 880 
 881 void
 882 ReferenceProcessor::process_discovered_reflist(
 883   DiscoveredList               refs_lists[],
 884   ReferencePolicy*             policy,
 885   bool                         clear_referent,
 886   BoolObjectClosure*           is_alive,
 887   OopClosure*                  keep_alive,
 888   VoidClosure*                 complete_gc,
 889   AbstractRefProcTaskExecutor* task_executor)
 890 {
 891   bool mt_processing = task_executor != NULL && _processing_is_mt;
 892   // If discovery used MT and a dynamic number of GC threads, then
 893   // the queues must be balanced for correctness if fewer than the
 894   // maximum number of queues were used.  The number of queue used
 895   // during discovery may be different than the number to be used
 896   // for processing so don't depend of _num_q < _max_num_q as part
 897   // of the test.
 898   bool must_balance = _discovery_is_mt;
 899 
 900   if ((mt_processing && ParallelRefProcBalancingEnabled) ||
 901       must_balance) {
 902     balance_queues(refs_lists);
 903   }



 904   if (PrintReferenceGC && PrintGCDetails) {
 905     size_t total = 0;
 906     for (uint i = 0; i < _max_num_q; ++i) {
 907       total += refs_lists[i].length();
 908     }
 909     gclog_or_tty->print(", %u refs", total);
 910   }
 911 
 912   // Phase 1 (soft refs only):
 913   // . Traverse the list and remove any SoftReferences whose
 914   //   referents are not alive, but that should be kept alive for
 915   //   policy reasons. Keep alive the transitive closure of all
 916   //   such referents.
 917   if (policy != NULL) {
 918     if (mt_processing) {
 919       RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
 920       task_executor->execute(phase1);
 921     } else {
 922       for (uint i = 0; i < _max_num_q; i++) {
 923         process_phase1(refs_lists[i], policy,
 924                        is_alive, keep_alive, complete_gc);
 925       }
 926     }
 927   } else { // policy == NULL
 928     assert(refs_lists != _discoveredSoftRefs,
 929            "Policy must be specified for soft references.");


 934   if (mt_processing) {
 935     RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
 936     task_executor->execute(phase2);
 937   } else {
 938     for (uint i = 0; i < _max_num_q; i++) {
 939       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
 940     }
 941   }
 942 
 943   // Phase 3:
 944   // . Traverse the list and process referents as appropriate.
 945   if (mt_processing) {
 946     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
 947     task_executor->execute(phase3);
 948   } else {
 949     for (uint i = 0; i < _max_num_q; i++) {
 950       process_phase3(refs_lists[i], clear_referent,
 951                      is_alive, keep_alive, complete_gc);
 952     }
 953   }


 954 }
 955 
 956 void ReferenceProcessor::clean_up_discovered_references() {
 957   // loop over the lists
 958   for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 959     if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
 960       gclog_or_tty->print_cr(
 961         "\nScrubbing %s discovered list of Null referents",
 962         list_name(i));
 963     }
 964     clean_up_discovered_reflist(_discovered_refs[i]);
 965   }
 966 }
 967 
 968 void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
 969   assert(!discovery_is_atomic(), "Else why call this method?");
 970   DiscoveredListIterator iter(refs_list, NULL, NULL);
 971   while (iter.has_next()) {
 972     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
 973     oop next = java_lang_ref_Reference::next(iter.obj());


1249     list->inc_length(1);
1250 
1251     if (TraceReferenceGC) {
1252       gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
1253                                 obj, obj->klass()->internal_name());
1254     }
1255   }
1256   assert(obj->is_oop(), "Discovered a bad reference");
1257   verify_referent(obj);
1258   return true;
1259 }
1260 
1261 // Preclean the discovered references by removing those
1262 // whose referents are alive, and by marking from those that
1263 // are not active. These lists can be handled here
1264 // in any order and, indeed, concurrently.
1265 void ReferenceProcessor::preclean_discovered_references(
1266   BoolObjectClosure* is_alive,
1267   OopClosure* keep_alive,
1268   VoidClosure* complete_gc,
1269   YieldClosure* yield) {

1270 
1271   NOT_PRODUCT(verify_ok_to_handle_reflists());
1272 
1273   // Soft references
1274   {
1275     TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
1276               false, gclog_or_tty);
1277     for (uint i = 0; i < _max_num_q; i++) {
1278       if (yield->should_return()) {
1279         return;
1280       }
1281       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
1282                                   keep_alive, complete_gc, yield);
1283     }
1284   }
1285 
1286   // Weak references
1287   {
1288     TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
1289               false, gclog_or_tty);
1290     for (uint i = 0; i < _max_num_q; i++) {
1291       if (yield->should_return()) {
1292         return;
1293       }
1294       preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
1295                                   keep_alive, complete_gc, yield);
1296     }
1297   }
1298 
1299   // Final references
1300   {
1301     TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
1302               false, gclog_or_tty);
1303     for (uint i = 0; i < _max_num_q; i++) {
1304       if (yield->should_return()) {
1305         return;
1306       }
1307       preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
1308                                   keep_alive, complete_gc, yield);
1309     }
1310   }
1311 
1312   // Phantom references
1313   {
1314     TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
1315               false, gclog_or_tty);
1316     for (uint i = 0; i < _max_num_q; i++) {
1317       if (yield->should_return()) {
1318         return;
1319       }
1320       preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
1321                                   keep_alive, complete_gc, yield);
1322     }
1323   }
1324 }
1325 
1326 // Walk the given discovered ref list, and remove all reference objects
1327 // whose referents are still alive, whose referents are NULL or which
1328 // are not active (have a non-NULL next field). NOTE: When we are
1329 // thus precleaning the ref lists (which happens single-threaded today),
1330 // we do not disable refs discovery to honour the correct semantics of
1331 // java.lang.Reference. As a result, we need to be careful below
1332 // that ref removal steps interleave safely with ref discovery steps
1333 // (in this thread).
1334 void
1335 ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,


   1 /*
   2  * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  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.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "gc_implementation/shared/gcTimer.hpp"
  29 #include "gc_implementation/shared/gcTraceTime.hpp"
  30 #include "gc_interface/collectedHeap.hpp"
  31 #include "gc_interface/collectedHeap.inline.hpp"
  32 #include "memory/referencePolicy.hpp"
  33 #include "memory/referenceProcessor.hpp"
  34 #include "oops/oop.inline.hpp"
  35 #include "runtime/java.hpp"
  36 #include "runtime/jniHandles.hpp"
  37 
  38 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
  39 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
  40 bool             ReferenceProcessor::_pending_list_uses_discovered_field = false;
  41 jlong            ReferenceProcessor::_soft_ref_timestamp_clock = 0;
  42 
  43 void referenceProcessor_init() {
  44   ReferenceProcessor::init_statics();
  45 }
  46 
  47 void ReferenceProcessor::init_statics() {
  48   // We need a monotonically non-deccreasing time in ms but
  49   // os::javaTimeMillis() does not guarantee monotonicity.


 165 
 166   NOT_PRODUCT(
 167   if (now < _soft_ref_timestamp_clock) {
 168     warning("time warp: "INT64_FORMAT" to "INT64_FORMAT,
 169             _soft_ref_timestamp_clock, now);
 170   }
 171   )
 172   // The values of now and _soft_ref_timestamp_clock are set using
 173   // javaTimeNanos(), which is guaranteed to be monotonically
 174   // non-decreasing provided the underlying platform provides such
 175   // a time source (and it is bug free).
 176   // In product mode, however, protect ourselves from non-monotonicty.
 177   if (now > _soft_ref_timestamp_clock) {
 178     _soft_ref_timestamp_clock = now;
 179     java_lang_ref_SoftReference::set_clock(now);
 180   }
 181   // Else leave clock stalled at its old value until time progresses
 182   // past clock value.
 183 }
 184 
 185 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) {
 186   size_t total = 0;
 187   for (uint i = 0; i < _max_num_q; ++i) {
 188     total += lists[i].length();
 189   }
 190   return total;
 191 }
 192 
 193 ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
 194   BoolObjectClosure*           is_alive,
 195   OopClosure*                  keep_alive,
 196   VoidClosure*                 complete_gc,
 197   AbstractRefProcTaskExecutor* task_executor,
 198   GCTimer*                     gc_timer) {
 199   NOT_PRODUCT(verify_ok_to_handle_reflists());
 200 
 201   assert(!enqueuing_is_done(), "If here enqueuing should not be complete");
 202   // Stop treating discovered references specially.
 203   disable_discovery();
 204 
 205   // If discovery was concurrent, someone could have modified
 206   // the value of the static field in the j.l.r.SoftReference
 207   // class that holds the soft reference timestamp clock using
 208   // reflection or Unsafe between when discovery was enabled and
 209   // now. Unconditionally update the static field in ReferenceProcessor
 210   // here so that we use the new value during processing of the
 211   // discovered soft refs.
 212 
 213   _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
 214 
 215   bool trace_time = PrintGCDetails && PrintReferenceGC;
 216 
 217   // Soft references
 218   size_t soft_count = 0;
 219   {
 220     GCTraceTime tt("SoftReference", trace_time, false, gc_timer);
 221     soft_count =
 222       process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
 223                                  is_alive, keep_alive, complete_gc, task_executor);
 224   }
 225 
 226   update_soft_ref_master_clock();
 227 
 228   // Weak references
 229   size_t weak_count = 0;
 230   {
 231     GCTraceTime tt("WeakReference", trace_time, false, gc_timer);
 232     weak_count =
 233       process_discovered_reflist(_discoveredWeakRefs, NULL, true,
 234                                  is_alive, keep_alive, complete_gc, task_executor);
 235   }
 236 
 237   // Final references
 238   size_t final_count = 0;
 239   {
 240     GCTraceTime tt("FinalReference", trace_time, false, gc_timer);
 241     final_count =
 242       process_discovered_reflist(_discoveredFinalRefs, NULL, false,
 243                                  is_alive, keep_alive, complete_gc, task_executor);
 244   }
 245 
 246   // Phantom references
 247   size_t phantom_count = 0;
 248   {
 249     GCTraceTime tt("PhantomReference", trace_time, false, gc_timer);
 250     phantom_count =
 251       process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
 252                                  is_alive, keep_alive, complete_gc, task_executor);
 253   }
 254 
 255   // Weak global JNI references. It would make more sense (semantically) to
 256   // traverse these simultaneously with the regular weak references above, but
 257   // that is not how the JDK1.2 specification is. See #4126360. Native code can
 258   // thus use JNI weak references to circumvent the phantom references and
 259   // resurrect a "post-mortem" object.
 260   {
 261     GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
 262     if (task_executor != NULL) {
 263       task_executor->set_single_threaded_mode();
 264     }
 265     process_phaseJNI(is_alive, keep_alive, complete_gc);
 266   }
 267 
 268   return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count);
 269 }
 270 
 271 #ifndef PRODUCT
 272 // Calculate the number of jni handles.
 273 uint ReferenceProcessor::count_jni_refs() {
 274   class AlwaysAliveClosure: public BoolObjectClosure {
 275   public:
 276     virtual bool do_object_b(oop obj) { return true; }
 277   };
 278 
 279   class CountHandleClosure: public OopClosure {
 280   private:
 281     int _count;
 282   public:
 283     CountHandleClosure(): _count(0) {}
 284     void do_oop(oop* unused)       { _count++; }
 285     void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
 286     int count() { return _count; }
 287   };
 288   CountHandleClosure global_handle_count;


 883     balanced_total_refs += ref_lists[i].length();
 884     if (TraceReferenceGC && PrintGCDetails) {
 885       gclog_or_tty->print("%d ", ref_lists[i].length());
 886     }
 887   }
 888   if (TraceReferenceGC && PrintGCDetails) {
 889     gclog_or_tty->print_cr(" = %d", balanced_total_refs);
 890     gclog_or_tty->flush();
 891   }
 892   assert(total_refs == balanced_total_refs, "Balancing was incomplete");
 893 #endif
 894 }
 895 
 896 void ReferenceProcessor::balance_all_queues() {
 897   balance_queues(_discoveredSoftRefs);
 898   balance_queues(_discoveredWeakRefs);
 899   balance_queues(_discoveredFinalRefs);
 900   balance_queues(_discoveredPhantomRefs);
 901 }
 902 
 903 size_t
 904 ReferenceProcessor::process_discovered_reflist(
 905   DiscoveredList               refs_lists[],
 906   ReferencePolicy*             policy,
 907   bool                         clear_referent,
 908   BoolObjectClosure*           is_alive,
 909   OopClosure*                  keep_alive,
 910   VoidClosure*                 complete_gc,
 911   AbstractRefProcTaskExecutor* task_executor)
 912 {
 913   bool mt_processing = task_executor != NULL && _processing_is_mt;
 914   // If discovery used MT and a dynamic number of GC threads, then
 915   // the queues must be balanced for correctness if fewer than the
 916   // maximum number of queues were used.  The number of queue used
 917   // during discovery may be different than the number to be used
 918   // for processing so don't depend of _num_q < _max_num_q as part
 919   // of the test.
 920   bool must_balance = _discovery_is_mt;
 921 
 922   if ((mt_processing && ParallelRefProcBalancingEnabled) ||
 923       must_balance) {
 924     balance_queues(refs_lists);
 925   }
 926 
 927   size_t total_list_count = total_count(refs_lists);
 928 
 929   if (PrintReferenceGC && PrintGCDetails) {
 930     gclog_or_tty->print(", %u refs", total_list_count);




 931   }
 932 
 933   // Phase 1 (soft refs only):
 934   // . Traverse the list and remove any SoftReferences whose
 935   //   referents are not alive, but that should be kept alive for
 936   //   policy reasons. Keep alive the transitive closure of all
 937   //   such referents.
 938   if (policy != NULL) {
 939     if (mt_processing) {
 940       RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
 941       task_executor->execute(phase1);
 942     } else {
 943       for (uint i = 0; i < _max_num_q; i++) {
 944         process_phase1(refs_lists[i], policy,
 945                        is_alive, keep_alive, complete_gc);
 946       }
 947     }
 948   } else { // policy == NULL
 949     assert(refs_lists != _discoveredSoftRefs,
 950            "Policy must be specified for soft references.");


 955   if (mt_processing) {
 956     RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
 957     task_executor->execute(phase2);
 958   } else {
 959     for (uint i = 0; i < _max_num_q; i++) {
 960       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
 961     }
 962   }
 963 
 964   // Phase 3:
 965   // . Traverse the list and process referents as appropriate.
 966   if (mt_processing) {
 967     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
 968     task_executor->execute(phase3);
 969   } else {
 970     for (uint i = 0; i < _max_num_q; i++) {
 971       process_phase3(refs_lists[i], clear_referent,
 972                      is_alive, keep_alive, complete_gc);
 973     }
 974   }
 975 
 976   return total_list_count;
 977 }
 978 
 979 void ReferenceProcessor::clean_up_discovered_references() {
 980   // loop over the lists
 981   for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
 982     if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
 983       gclog_or_tty->print_cr(
 984         "\nScrubbing %s discovered list of Null referents",
 985         list_name(i));
 986     }
 987     clean_up_discovered_reflist(_discovered_refs[i]);
 988   }
 989 }
 990 
 991 void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
 992   assert(!discovery_is_atomic(), "Else why call this method?");
 993   DiscoveredListIterator iter(refs_list, NULL, NULL);
 994   while (iter.has_next()) {
 995     iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
 996     oop next = java_lang_ref_Reference::next(iter.obj());


1272     list->inc_length(1);
1273 
1274     if (TraceReferenceGC) {
1275       gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
1276                                 obj, obj->klass()->internal_name());
1277     }
1278   }
1279   assert(obj->is_oop(), "Discovered a bad reference");
1280   verify_referent(obj);
1281   return true;
1282 }
1283 
1284 // Preclean the discovered references by removing those
1285 // whose referents are alive, and by marking from those that
1286 // are not active. These lists can be handled here
1287 // in any order and, indeed, concurrently.
1288 void ReferenceProcessor::preclean_discovered_references(
1289   BoolObjectClosure* is_alive,
1290   OopClosure* keep_alive,
1291   VoidClosure* complete_gc,
1292   YieldClosure* yield,
1293   GCTimer* gc_timer) {
1294 
1295   NOT_PRODUCT(verify_ok_to_handle_reflists());
1296 
1297   // Soft references
1298   {
1299     GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
1300               false, gc_timer);
1301     for (uint i = 0; i < _max_num_q; i++) {
1302       if (yield->should_return()) {
1303         return;
1304       }
1305       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
1306                                   keep_alive, complete_gc, yield);
1307     }
1308   }
1309 
1310   // Weak references
1311   {
1312     GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
1313               false, gc_timer);
1314     for (uint i = 0; i < _max_num_q; i++) {
1315       if (yield->should_return()) {
1316         return;
1317       }
1318       preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
1319                                   keep_alive, complete_gc, yield);
1320     }
1321   }
1322 
1323   // Final references
1324   {
1325     GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
1326               false, gc_timer);
1327     for (uint i = 0; i < _max_num_q; i++) {
1328       if (yield->should_return()) {
1329         return;
1330       }
1331       preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
1332                                   keep_alive, complete_gc, yield);
1333     }
1334   }
1335 
1336   // Phantom references
1337   {
1338     GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
1339               false, gc_timer);
1340     for (uint i = 0; i < _max_num_q; i++) {
1341       if (yield->should_return()) {
1342         return;
1343       }
1344       preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
1345                                   keep_alive, complete_gc, yield);
1346     }
1347   }
1348 }
1349 
1350 // Walk the given discovered ref list, and remove all reference objects
1351 // whose referents are still alive, whose referents are NULL or which
1352 // are not active (have a non-NULL next field). NOTE: When we are
1353 // thus precleaning the ref lists (which happens single-threaded today),
1354 // we do not disable refs discovery to honour the correct semantics of
1355 // java.lang.Reference. As a result, we need to be careful below
1356 // that ref removal steps interleave safely with ref discovery steps
1357 // (in this thread).
1358 void
1359 ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,