--- old/src/share/vm/gc/g1/g1CollectedHeap.cpp 2016-04-08 12:37:53.550885266 +0200 +++ new/src/share/vm/gc/g1/g1CollectedHeap.cpp 2016-04-08 12:37:53.422880275 +0200 @@ -4440,7 +4440,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 @@ -4461,16 +4460,20 @@ // 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. + double preserve_cm_referents_time = 0.0; - uint no_of_gc_workers = workers()->active_workers(); + if (_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; + } - 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); + 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). --- old/src/share/vm/gc/shared/referenceProcessor.cpp 2016-04-08 12:37:54.186910060 +0200 +++ new/src/share/vm/gc/shared/referenceProcessor.cpp 2016-04-08 12:37:54.078905850 +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 --- old/src/share/vm/gc/shared/referenceProcessor.hpp 2016-04-08 12:37:54.882937194 +0200 +++ new/src/share/vm/gc/shared/referenceProcessor.hpp 2016-04-08 12:37:54.734931424 +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,