--- old/src/share/vm/gc/shared/referenceProcessor.cpp 2017-06-12 16:20:25.071222230 -0700 +++ new/src/share/vm/gc/shared/referenceProcessor.cpp 2017-06-12 16:20:24.947222234 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -127,6 +127,8 @@ _discovered_refs[i].set_length(0); } + _phase_times = new ReferenceProcessorPhaseTimes(_num_q, _processing_is_mt); + setup_policy(false /* default soft ref policy */); } @@ -208,40 +210,39 @@ _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); - ReferenceProcessorStats stats( - total_count(_discoveredSoftRefs), - total_count(_discoveredWeakRefs), - total_count(_discoveredFinalRefs), - total_count(_discoveredPhantomRefs)); + ReferenceProcessorStats stats(total_count(_discoveredSoftRefs), + total_count(_discoveredWeakRefs), + total_count(_discoveredFinalRefs), + total_count(_discoveredPhantomRefs)); // Soft references { - GCTraceTime(Debug, gc, ref) tt("SoftReference", gc_timer); + RefProcPhaseTimesLogger tt("SoftReference", phase_times(), _discoveredSoftRefs, gc_timer); process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, - is_alive, keep_alive, complete_gc, task_executor); + is_alive, keep_alive, complete_gc, task_executor, gc_timer); } update_soft_ref_master_clock(); // Weak references { - GCTraceTime(Debug, gc, ref) tt("WeakReference", gc_timer); + RefProcPhaseTimesLogger tt("WeakReference", phase_times(), _discoveredWeakRefs, gc_timer); process_discovered_reflist(_discoveredWeakRefs, NULL, true, - is_alive, keep_alive, complete_gc, task_executor); + is_alive, keep_alive, complete_gc, task_executor, gc_timer); } // Final references { - GCTraceTime(Debug, gc, ref) tt("FinalReference", gc_timer); + RefProcPhaseTimesLogger tt("FinalReference", phase_times(), _discoveredFinalRefs, gc_timer); process_discovered_reflist(_discoveredFinalRefs, NULL, false, - is_alive, keep_alive, complete_gc, task_executor); + is_alive, keep_alive, complete_gc, task_executor, gc_timer); } // Phantom references { - GCTraceTime(Debug, gc, ref) tt("PhantomReference", gc_timer); + RefProcPhaseTimesLogger tt("PhantomReference", phase_times(), _discoveredPhantomRefs, gc_timer); process_discovered_reflist(_discoveredPhantomRefs, NULL, true, - is_alive, keep_alive, complete_gc, task_executor); + is_alive, keep_alive, complete_gc, task_executor, gc_timer); } // Weak global JNI references. It would make more sense (semantically) to @@ -257,8 +258,6 @@ process_phaseJNI(is_alive, keep_alive, complete_gc); } - log_debug(gc, ref)("Ref Counts: Soft: " SIZE_FORMAT " Weak: " SIZE_FORMAT " Final: " SIZE_FORMAT " Phantom: " SIZE_FORMAT, - stats.soft_count(), stats.weak_count(), stats.final_count(), stats.phantom_count()); log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs()); return stats; @@ -289,10 +288,10 @@ complete_gc->do_void(); } -void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) { +void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor, GCTimer* gc_timer) { // Enqueue references that are not made active again, and // clear the decks for the next collection (cycle). - enqueue_discovered_reflists(task_executor); + enqueue_discovered_reflists(task_executor, gc_timer); // Stop treating discovered references specially. disable_discovery(); @@ -350,6 +349,8 @@ { } virtual void work(unsigned int work_id) { + RefProcWorkerTimeTracker tt(_ref_processor.phase_times()->worker_time_sec(ReferenceProcessorPhaseTimes::RefEnqueue), work_id); + assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds"); // Simplest first cut: static partitioning. int index = work_id; @@ -369,7 +370,15 @@ }; // Enqueue references that are not made active again -void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor) { +void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor, GCTimer* gc_timer) { + + ReferenceProcessorStats stats(total_count(_discoveredSoftRefs), + total_count(_discoveredWeakRefs), + total_count(_discoveredFinalRefs), + total_count(_discoveredPhantomRefs)); + + RefProcEnqueueTimeLogger tt(phase_times(), stats, gc_timer); + if (_processing_is_mt && task_executor != NULL) { // Parallel code RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_q); @@ -469,7 +478,7 @@ complete_gc->do_void(); log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT, iter.removed(), iter.processed(), p2i(&refs_list)); - } +} // Traverse the list and remove any Refs that are not active, or // whose referents are either alive or NULL. @@ -611,6 +620,8 @@ OopClosure& keep_alive, VoidClosure& complete_gc) { + RefProcWorkerTimeTracker tt(_ref_processor.phase_times()->worker_time_sec(ReferenceProcessorPhaseTimes::RefPhase1), i); + _ref_processor.process_phase1(_refs_lists[i], _policy, &is_alive, &keep_alive, &complete_gc); } @@ -629,6 +640,8 @@ OopClosure& keep_alive, VoidClosure& complete_gc) { + RefProcWorkerTimeTracker tt(_ref_processor.phase_times()->worker_time_sec(ReferenceProcessorPhaseTimes::RefPhase2), i); + _ref_processor.process_phase2(_refs_lists[i], &is_alive, &keep_alive, &complete_gc); } @@ -647,6 +660,8 @@ OopClosure& keep_alive, VoidClosure& complete_gc) { + RefProcWorkerTimeTracker tt(_ref_processor.phase_times()->worker_time_sec(ReferenceProcessorPhaseTimes::RefPhase3), i); + _ref_processor.process_phase3(_refs_lists[i], _clear_referent, &is_alive, &keep_alive, &complete_gc); } @@ -776,9 +791,13 @@ BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, - AbstractRefProcTaskExecutor* task_executor) + AbstractRefProcTaskExecutor* task_executor, + GCTimer* gc_timer) { bool mt_processing = task_executor != NULL && _processing_is_mt; + + phase_times()->set_processing_is_mt(mt_processing); + // If discovery used MT and a dynamic number of GC threads, then // the queues must be balanced for correctness if fewer than the // maximum number of queues were used. The number of queue used @@ -789,6 +808,7 @@ if ((mt_processing && ParallelRefProcBalancingEnabled) || must_balance) { + RefProcBalanceQueuesTimeTracker tt(phase_times(), gc_timer); balance_queues(refs_lists); } @@ -798,6 +818,8 @@ // policy reasons. Keep alive the transitive closure of all // such referents. if (policy != NULL) { + RefProcPhaseTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase1, phase_times(), gc_timer); + if (mt_processing) { RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/); task_executor->execute(phase1); @@ -814,24 +836,32 @@ // Phase 2: // . Traverse the list and remove any refs whose referents are alive. - if (mt_processing) { - RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/); - task_executor->execute(phase2); - } else { - for (uint i = 0; i < _max_num_q; i++) { - process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc); + { + RefProcPhaseTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase2, phase_times(), gc_timer); + + if (mt_processing) { + RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/); + task_executor->execute(phase2); + } else { + for (uint i = 0; i < _max_num_q; i++) { + process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc); + } } } // Phase 3: // . Traverse the list and process referents as appropriate. - if (mt_processing) { - RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/); - task_executor->execute(phase3); - } else { - for (uint i = 0; i < _max_num_q; i++) { - process_phase3(refs_lists[i], clear_referent, - is_alive, keep_alive, complete_gc); + { + RefProcPhaseTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase3, phase_times(), gc_timer); + + if (mt_processing) { + RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/); + task_executor->execute(phase3); + } else { + for (uint i = 0; i < _max_num_q; i++) { + process_phase3(refs_lists[i], clear_referent, + is_alive, keep_alive, complete_gc); + } } } } @@ -1196,4 +1226,3 @@ ShouldNotReachHere(); return NULL; } -