--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-15 08:29:42.246029018 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-15 08:29:41.904028866 -0400
@@ -38,6 +38,7 @@
#include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
#include "gc/shenandoah/shenandoahConcurrentMark.inline.hpp"
+#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
#include "gc/shenandoah/shenandoahControlThread.hpp"
#include "gc/shenandoah/shenandoahFreeSet.hpp"
#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
@@ -1071,9 +1072,11 @@
DerivedPointerTable::clear();
#endif
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Only iterate roots while world is stopped");
-
{
- ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac);
+ // Include concurrent roots if current cycle can not process those roots concurrently
+ bool include_concurrent_roots = !ShenandoahConcurrentRoots::should_do_concurrent_roots();
+
+ ShenandoahRootEvacuator rp(workers()->active_workers(), ShenandoahPhaseTimings::init_evac, include_concurrent_roots);
ShenandoahEvacuateUpdateRootsTask roots_task(&rp);
workers()->run_task(&roots_task);
}
@@ -1517,7 +1520,12 @@
}
if (ShenandoahVerify) {
- verifier()->verify_roots_no_forwarded();
+ if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
+ ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::CLDGRoots);
+ verifier()->verify_roots_no_forwarded_except(types);
+ } else {
+ verifier()->verify_roots_no_forwarded();
+ }
verifier()->verify_during_evacuation();
}
} else {
@@ -1578,6 +1586,34 @@
free_set()->recycle_trash();
}
+class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
+private:
+ SuspendibleThreadSetJoiner _sts_joiner;
+ ShenandoahJNIHandleRoots _jni_roots;
+ ShenandoahClassLoaderDataRoots _cld_roots;
+public:
+ ShenandoahConcurrentRootsEvacUpdateTask() :
+ AbstractGangTask("Shenandoah Evacuate/Update Concurrent Roots Task") {
+ }
+
+ void work(uint worker_id) {
+ ShenandoahEvacOOMScope oom;
+ ShenandoahEvacuateUpdateRootsClosure cl;
+ CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
+
+ _jni_roots.oops_do(&cl);
+ _cld_roots.cld_do(&clds);
+ }
+};
+
+void ShenandoahHeap::op_concurrent_roots() {
+ if (is_evacuation_in_progress() &&
+ ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
+ ShenandoahConcurrentRootsEvacUpdateTask task;
+ workers()->run_task(&task);
+ }
+}
+
void ShenandoahHeap::op_reset() {
reset_mark_bitmap();
}
@@ -2554,6 +2590,22 @@
try_inject_alloc_failure();
op_updaterefs();
}
+
+void ShenandoahHeap::entry_concurrent_roots() {
+ ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_roots);
+
+ static const char* msg = "Concurrent roots processing";
+ GCTraceTime(Info, gc) time(msg, NULL, GCCause::_no_gc, true);
+ EventMark em("%s", msg);
+
+ ShenandoahWorkerScope scope(workers(),
+ ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing(),
+ "concurrent root processing");
+
+ try_inject_alloc_failure();
+ op_concurrent_roots();
+}
+
void ShenandoahHeap::entry_cleanup() {
ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup);