--- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2014-12-12 02:18:53.846000000 -0500 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2014-12-12 02:18:53.739000000 -0500 @@ -1608,14 +1608,13 @@ // 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 due to later mutator + // activity, and the compacting collector we're about to run + // won't see them as live. + ref_processor()->disable_discovery(); + ref_processor()->abandon_partial_discovery(); + ref_processor()->verify_no_references_recorded(); if (first_state > Idling) { save_heap_summary(); @@ -1681,7 +1680,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 +2997,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(); --- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-12-12 02:18:54.469000000 -0500 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-12-12 02:18:54.351000000 -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(); --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-12-12 02:18:54.975000000 -0500 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-12-12 02:18:54.851000000 -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 --- old/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp 2014-12-12 02:18:55.456000000 -0500 +++ new/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp 2014-12-12 02:18:55.378000000 -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); --- old/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2014-12-12 02:18:55.889000000 -0500 +++ new/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2014-12-12 02:18:55.809000000 -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; --- old/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp 2014-12-12 02:18:56.342000000 -0500 +++ new/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp 2014-12-12 02:18:56.264000000 -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 --- old/src/share/vm/memory/genCollectedHeap.cpp 2014-12-12 02:18:56.775000000 -0500 +++ new/src/share/vm/memory/genCollectedHeap.cpp 2014-12-12 02:18:56.697000000 -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 --- old/src/share/vm/memory/referenceProcessor.cpp 2014-12-12 02:18:57.207000000 -0500 +++ new/src/share/vm/memory/referenceProcessor.cpp 2014-12-12 02:18:57.129000000 -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. --- old/src/share/vm/memory/referenceProcessor.hpp 2014-12-12 02:18:57.649000000 -0500 +++ new/src/share/vm/memory/referenceProcessor.hpp 2014-12-12 02:18:57.570000000 -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*/); } } };