# HG changeset patch # User sjohanss # Date 1460615437 -7200 # Node ID bf6caf8e99cb9d0a11f009ff324053382414ecbe # Parent 5da80e1490de43966c3cb0e495d572b8bb8a21fb 8153745: Avoid spawning G1ParPreserveCMReferentsTask when there is no work to be done Reviewed-by: brutisso, jmasa, tschatzl diff -r 5da80e1490de -r bf6caf8e99cb hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Apr 14 08:30:15 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Apr 14 08:30:37 2016 +0200 @@ -4452,7 +4452,6 @@ } void G1CollectedHeap::preserve_cm_referents(G1ParScanThreadStateSet* per_thread_states) { - double preserve_cm_referents_start = os::elapsedTime(); // Any reference objects, in the collection set, that were 'discovered' // by the CM ref processor should have already been copied (either by // applying the external root copy closure to the discovered lists, or @@ -4473,16 +4472,24 @@ // objects discovered by the STW ref processor in case one of these // referents points to another object which is also referenced by an // object discovered by the STW ref processor. - - uint no_of_gc_workers = workers()->active_workers(); - - G1ParPreserveCMReferentsTask keep_cm_referents(this, - per_thread_states, - no_of_gc_workers, - _task_queues); - workers()->run_task(&keep_cm_referents); - - g1_policy()->phase_times()->record_preserve_cm_referents_time_ms((os::elapsedTime() - preserve_cm_referents_start) * 1000.0); + double preserve_cm_referents_time = 0.0; + + // To avoid spawning task when there is no work to do, check that + // a concurrent cycle is active and that some references have been + // discovered. + if (concurrent_mark()->cmThread()->during_cycle() && + ref_processor_cm()->has_discovered_references()) { + double preserve_cm_referents_start = os::elapsedTime(); + uint no_of_gc_workers = workers()->active_workers(); + G1ParPreserveCMReferentsTask keep_cm_referents(this, + per_thread_states, + no_of_gc_workers, + _task_queues); + workers()->run_task(&keep_cm_referents); + preserve_cm_referents_time = os::elapsedTime() - preserve_cm_referents_start; + } + + g1_policy()->phase_times()->record_preserve_cm_referents_time_ms(preserve_cm_referents_time * 1000.0); } // Weak Reference processing during an evacuation pause (part 1). diff -r 5da80e1490de -r bf6caf8e99cb hotspot/src/share/vm/gc/shared/referenceProcessor.cpp --- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Thu Apr 14 08:30:15 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Thu Apr 14 08:30:37 2016 +0200 @@ -1090,6 +1090,15 @@ return true; } +bool ReferenceProcessor::has_discovered_references() { + for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { + if (!_discovered_refs[i].is_empty()) { + return true; + } + } + return false; +} + // Preclean the discovered references by removing those // whose referents are alive, and by marking from those that // are not active. These lists can be handled here diff -r 5da80e1490de -r bf6caf8e99cb hotspot/src/share/vm/gc/shared/referenceProcessor.hpp --- a/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp Thu Apr 14 08:30:15 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.hpp Thu Apr 14 08:30:37 2016 +0200 @@ -412,6 +412,9 @@ // Discover a Reference object, using appropriate discovery criteria bool discover_reference(oop obj, ReferenceType rt); + // Has discovered references that need handling + bool has_discovered_references(); + // Process references found during GC (called by the garbage collector) ReferenceProcessorStats process_discovered_references(BoolObjectClosure* is_alive,