8153745: Avoid spawning G1ParPreserveCMReferentsTask when there is no work to be done
Reviewed-by: brutisso, jmasa, tschatzl
--- 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).
--- 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
--- 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,