changeset 7600:b8cef6fae4c3

8066827: Remove ReferenceProcessor::clean_up_discovered_references() Summary: Abandon rather than clean up discovered references. Reviewed-by: jmasa, ysr
author kbarrett
date Wed, 17 Dec 2014 22:32:44 -0500
parents e253436e9460
children 5cdbde3a9a57
files src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp src/share/vm/gc_implementation/g1/concurrentMark.cpp src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp src/share/vm/memory/genCollectedHeap.cpp src/share/vm/memory/referenceProcessor.cpp src/share/vm/memory/referenceProcessor.hpp
diffstat 9 files changed, 22 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -1608,14 +1608,15 @@
 
   // If the collection is being acquired from the background
   // collector, there may be references on the discovered
-  // references lists that have NULL referents (being those
-  // that were concurrently cleared by a mutator) or
-  // that are no longer active (having been enqueued concurrently
-  // by the mutator).
-  // Scrub the list of those references because Mark-Sweep-Compact
-  // code assumes referents are not NULL and that all discovered
-  // Reference objects are active.
-  ref_processor()->clean_up_discovered_references();
+  // references lists.  Abandon those references, since some
+  // of them may have become unreachable after concurrent
+  // discovery; the STW compacting collector will redo discovery
+  // more precisely, without being subject to floating garbage.
+  // Leaving otherwise unreachable references in the discovered
+  // lists would require special handling.
+  ref_processor()->disable_discovery();
+  ref_processor()->abandon_partial_discovery();
+  ref_processor()->verify_no_references_recorded();
 
   if (first_state > Idling) {
     save_heap_summary();
@@ -1681,7 +1682,7 @@
   ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
 
   ref_processor()->set_enqueuing_is_done(false);
-  ref_processor()->enable_discovery(false /*verify_disabled*/, false /*check_no_refs*/);
+  ref_processor()->enable_discovery();
   ref_processor()->setup_policy(clear_all_soft_refs);
   // If an asynchronous collection finishes, the _modUnionTable is
   // all clear.  If we are assuming the collection from an asynchronous
@@ -2998,7 +2999,7 @@
                     Mutex::_no_safepoint_check_flag);
     checkpointRootsInitialWork();
     // enable ("weak") refs discovery
-    rp->enable_discovery(true /*verify_disabled*/, true /*check_no_refs*/);
+    rp->enable_discovery();
     _collectorState = Marking;
   }
   SpecializationStats::print();
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -971,7 +971,7 @@
   // Start Concurrent Marking weak-reference discovery.
   ReferenceProcessor* rp = g1h->ref_processor_cm();
   // enable ("weak") refs discovery
-  rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+  rp->enable_discovery();
   rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle
 
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -1301,7 +1301,7 @@
       // Temporarily clear the STW ref processor's _is_alive_non_header field.
       ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL);
 
-      ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+      ref_processor_stw()->enable_discovery();
       ref_processor_stw()->setup_policy(do_clear_all_soft_refs);
 
       // Do collection work
@@ -3750,8 +3750,7 @@
       // reference processing currently works in G1.
 
       // Enable discovery in the STW reference processor
-      ref_processor_stw()->enable_discovery(true /*verify_disabled*/,
-                                            true /*verify_no_refs*/);
+      ref_processor_stw()->enable_discovery();
 
       {
         // We want to temporarily turn off discovery by the
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -195,7 +195,7 @@
 
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
-    ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+    ref_processor()->enable_discovery();
     ref_processor()->setup_policy(clear_all_softrefs);
 
     mark_sweep_phase1(clear_all_softrefs);
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -2069,7 +2069,7 @@
 
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
-    ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+    ref_processor()->enable_discovery();
     ref_processor()->setup_policy(maximum_heap_compaction);
 
     bool marked_for_unloading = false;
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -362,7 +362,7 @@
 
     COMPILER2_PRESENT(DerivedPointerTable::clear());
 
-    reference_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+    reference_processor()->enable_discovery();
     reference_processor()->setup_policy(false);
 
     // We track how much was promoted to the next generation for
--- a/src/share/vm/memory/genCollectedHeap.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -465,7 +465,7 @@
           // atomic wrt other collectors in this configuration, we
           // are guaranteed to have empty discovered ref lists.
           if (rp->discovery_is_atomic()) {
-            rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/);
+            rp->enable_discovery();
             rp->setup_policy(do_clear_all_soft_refs);
           } else {
             // collect() below will enable discovery as appropriate
--- a/src/share/vm/memory/referenceProcessor.cpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/memory/referenceProcessor.cpp	Wed Dec 17 22:32:44 2014 -0500
@@ -68,10 +68,10 @@
   _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
 }
 
-void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) {
+void ReferenceProcessor::enable_discovery(bool check_no_refs) {
 #ifdef ASSERT
   // Verify that we're not currently discovering refs
-  assert(!verify_disabled || !_discovering_refs, "nested call?");
+  assert(!_discovering_refs, "nested call?");
 
   if (check_no_refs) {
     // Verify that the discovered lists are empty
@@ -963,52 +963,6 @@
   return total_list_count;
 }
 
-void ReferenceProcessor::clean_up_discovered_references() {
-  // loop over the lists
-  for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
-    if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
-      gclog_or_tty->print_cr(
-        "\nScrubbing %s discovered list of Null referents",
-        list_name(i));
-    }
-    clean_up_discovered_reflist(_discovered_refs[i]);
-  }
-}
-
-void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
-  assert(!discovery_is_atomic(), "Else why call this method?");
-  DiscoveredListIterator iter(refs_list, NULL, NULL);
-  while (iter.has_next()) {
-    iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
-    oop next = java_lang_ref_Reference::next(iter.obj());
-    assert(next->is_oop_or_null(), err_msg("Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)));
-    // If referent has been cleared or Reference is not active,
-    // drop it.
-    if (iter.referent() == NULL || next != NULL) {
-      debug_only(
-        if (PrintGCDetails && TraceReferenceGC) {
-          gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
-            INTPTR_FORMAT " with next field: " INTPTR_FORMAT
-            " and referent: " INTPTR_FORMAT,
-            (void *)iter.obj(), (void *)next, (void *)iter.referent());
-        }
-      )
-      // Remove Reference object from list
-      iter.remove();
-      iter.move_to_next();
-    } else {
-      iter.next();
-    }
-  }
-  NOT_PRODUCT(
-    if (PrintGCDetails && TraceReferenceGC) {
-      gclog_or_tty->print(
-        " Removed %d Refs with NULL referents out of %d discovered Refs",
-        iter.removed(), iter.processed());
-    }
-  )
-}
-
 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
   uint id = 0;
   // Determine the queue index to use for this object.
--- a/src/share/vm/memory/referenceProcessor.hpp	Thu Dec 18 13:30:00 2014 +0000
+++ b/src/share/vm/memory/referenceProcessor.hpp	Wed Dec 17 22:32:44 2014 -0500
@@ -353,19 +353,6 @@
                                       GCTimer*           gc_timer,
                                       GCId               gc_id);
 
-  // Delete entries in the discovered lists that have
-  // either a null referent or are not active. Such
-  // Reference objects can result from the clearing
-  // or enqueueing of Reference objects concurrent
-  // with their discovery by a (concurrent) collector.
-  // For a definition of "active" see java.lang.ref.Reference;
-  // Refs are born active, become inactive when enqueued,
-  // and never become active again. The state of being
-  // active is encoded as follows: A Ref is active
-  // if and only if its "next" field is NULL.
-  void clean_up_discovered_references();
-  void clean_up_discovered_reflist(DiscoveredList& refs_list);
-
   // Returns the name of the discovered reference list
   // occupying the i / _num_q slot.
   const char* list_name(uint i);
@@ -439,7 +426,7 @@
   void      set_span(MemRegion span) { _span = span; }
 
   // start and stop weak ref discovery
-  void enable_discovery(bool verify_disabled, bool check_no_refs);
+  void enable_discovery(bool check_no_refs = true);
   void disable_discovery()  { _discovering_refs = false; }
   bool discovery_enabled()  { return _discovering_refs;  }
 
@@ -517,7 +504,7 @@
 
   ~NoRefDiscovery() {
     if (_was_discovering_refs) {
-      _rp->enable_discovery(true /*verify_disabled*/, false /*check_no_refs*/);
+      _rp->enable_discovery(false /*check_no_refs*/);
     }
   }
 };