8066827: Remove ReferenceProcessor::clean_up_discovered_references()
Abandon rather than clean up discovered references. Reviewed-by: jmasa, ysr
This commit is contained in:
parent
c40b1dd803
commit
093d2698fc
hotspot/src/share/vm
gc_implementation
concurrentMarkSweep
g1
parallelScavenge
memory
@ -1608,14 +1608,15 @@ void CMSCollector::acquire_control_and_collect(bool full,
|
||||
|
||||
// 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 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
|
||||
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 @@ void CMSCollector::checkpointRootsInitial() {
|
||||
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();
|
||||
|
@ -971,7 +971,7 @@ void ConcurrentMark::checkpointRootsInitialPost() {
|
||||
// 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();
|
||||
|
@ -1301,7 +1301,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
|
||||
// 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 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
// 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
|
||||
|
@ -195,7 +195,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
||||
|
||||
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);
|
||||
|
@ -2069,7 +2069,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
|
||||
|
||||
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;
|
||||
|
@ -362,7 +362,7 @@ bool PSScavenge::invoke_no_policy() {
|
||||
|
||||
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
|
||||
|
@ -465,7 +465,7 @@ void GenCollectedHeap::do_collection(bool full,
|
||||
// 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
|
||||
|
@ -68,10 +68,10 @@ void ReferenceProcessor::init_statics() {
|
||||
_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 @@ ReferenceProcessor::process_discovered_reflist(
|
||||
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.
|
||||
|
@ -353,19 +353,6 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
|
||||
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 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
|
||||
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 @@ class NoRefDiscovery: StackObj {
|
||||
|
||||
~NoRefDiscovery() {
|
||||
if (_was_discovering_refs) {
|
||||
_rp->enable_discovery(true /*verify_disabled*/, false /*check_no_refs*/);
|
||||
_rp->enable_discovery(false /*check_no_refs*/);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user