--- old/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp 2019-06-11 20:26:13.911680010 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp 2019-06-11 20:26:13.490679261 -0400
@@ -156,7 +156,7 @@
void work(uint worker_id) {
ShenandoahHeap* heap = ShenandoahHeap::heap();
ShenandoahConcurrentWorkerSession worker_session(worker_id);
- ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetJoiner stsj;
ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
ReferenceProcessor* rp;
if (heap->process_references()) {
@@ -982,7 +982,7 @@
if (work == 0) {
// No work encountered in current stride, try to terminate.
// Need to leave the STS here otherwise it might block safepoints.
- ShenandoahSuspendibleThreadSetLeaver stsl(CANCELLABLE && ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetLeaver stsl(CANCELLABLE);
ShenandoahTerminationTimingsTracker term_tracker(worker_id);
ShenandoahTerminatorTerminator tt(heap);
if (terminator->offer_termination(&tt)) return;
--- old/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp 2019-06-11 20:26:14.981681912 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp 2019-06-11 20:26:14.527681105 -0400
@@ -377,6 +377,9 @@
// Complete marking under STW, and start evacuation
heap->vmop_entry_final_mark();
+ // Evacuate concurrent roots
+ heap->entry_concurrent_roots();
+
// Final mark might have reclaimed some immediate garbage, kick cleanup to reclaim
// the space. This would be the last action if there is nothing to evacuate.
heap->entry_cleanup();
--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-11 20:26:15.920683581 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-06-11 20:26:15.470682781 -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"
@@ -949,7 +950,7 @@
void work(uint worker_id) {
if (_concurrent) {
ShenandoahConcurrentWorkerSession worker_session(worker_id);
- ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetJoiner stsj;
ShenandoahEvacOOMScope oom_evac_scope;
do_work();
} else {
@@ -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();
}
@@ -1851,7 +1887,6 @@
jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE);
if (prev == CANCELLABLE) return true;
else if (prev == CANCELLED) return false;
- assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers");
assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED");
{
// We need to provide a safepoint here, otherwise we might
@@ -2065,7 +2100,7 @@
void work(uint worker_id) {
if (_concurrent) {
ShenandoahConcurrentWorkerSession worker_session(worker_id);
- ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetJoiner stsj;
do_work();
} else {
ShenandoahParallelWorkerSession worker_session(worker_id);
@@ -2265,15 +2300,11 @@
}
void ShenandoahHeap::safepoint_synchronize_begin() {
- if (ShenandoahSuspendibleWorkers || UseStringDeduplication) {
- SuspendibleThreadSet::synchronize();
- }
+ SuspendibleThreadSet::synchronize();
}
void ShenandoahHeap::safepoint_synchronize_end() {
- if (ShenandoahSuspendibleWorkers || UseStringDeduplication) {
- SuspendibleThreadSet::desynchronize();
- }
+ SuspendibleThreadSet::desynchronize();
}
void ShenandoahHeap::vmop_entry_init_mark() {
@@ -2538,6 +2569,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);
--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp 2019-06-11 20:26:17.072685629 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp 2019-06-11 20:26:16.601684791 -0400
@@ -391,6 +391,7 @@
void entry_reset();
void entry_mark();
void entry_preclean();
+ void entry_concurrent_roots();
void entry_cleanup();
void entry_evac();
void entry_updaterefs();
@@ -414,6 +415,7 @@
void op_reset();
void op_mark();
void op_preclean();
+ void op_concurrent_roots();
void op_cleanup();
void op_conc_evac();
void op_stw_evac();
--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp 2019-06-11 20:26:18.352687904 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp 2019-06-11 20:26:17.780686887 -0400
@@ -187,7 +187,7 @@
}
inline bool ShenandoahHeap::check_cancelled_gc_and_yield(bool sts_active) {
- if (! (sts_active && ShenandoahSuspendibleWorkers)) {
+ if (!sts_active) {
return cancelled_gc();
}
--- old/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp 2019-06-11 20:26:19.660690229 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp 2019-06-11 20:26:19.089689214 -0400
@@ -306,6 +306,7 @@
f(conc_mark, "Concurrent Marking") \
f(conc_termination, " Termination") \
f(conc_preclean, "Concurrent Precleaning") \
+ f(conc_roots, "Concurrent Roots") \
f(conc_evac, "Concurrent Evacuation") \
f(conc_update_refs, "Concurrent Update Refs") \
f(conc_cleanup, "Concurrent Cleanup") \
--- old/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp 2019-06-11 20:26:20.931692489 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp 2019-06-11 20:26:20.428691594 -0400
@@ -71,10 +71,6 @@
_jvmti_root.oops_do(cl, worker_id);
}
-ShenandoahJNIHandleRoots::ShenandoahJNIHandleRoots() :
- ShenandoahSerialRoot(&JNIHandles::oops_do, ShenandoahPhaseTimings::JNIRoots) {
-}
-
ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) {
Threads::change_thread_claim_token();
}
@@ -126,22 +122,6 @@
}
}
-ShenandoahClassLoaderDataRoots::ShenandoahClassLoaderDataRoots() {
- ClassLoaderDataGraph::clear_claimed_marks();
-}
-
-void ShenandoahClassLoaderDataRoots::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
- ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
- ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
- ClassLoaderDataGraph::always_strong_cld_do(clds);
-}
-
-void ShenandoahClassLoaderDataRoots::cld_do(CLDClosure* clds, uint worker_id) {
- ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
- ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
- ClassLoaderDataGraph::cld_do(clds);
-}
-
ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
_heap(ShenandoahHeap::heap()),
_phase(phase) {
@@ -154,24 +134,25 @@
_heap->phase_timings()->record_workers_end(_phase);
}
-ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
+ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) :
ShenandoahRootProcessor(phase),
_thread_roots(n_workers > 1),
- _weak_roots(n_workers) {
+ _weak_roots(n_workers),
+ _include_concurrent_roots(include_concurrent_roots) {
}
void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
- CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
- CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
-
AlwaysTrueClosure always_true;
_serial_roots.oops_do(oops, worker_id);
- _jni_roots.oops_do(oops, worker_id);
+ if (_include_concurrent_roots) {
+ CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
+ _jni_roots.oops_do(oops, worker_id);
+ _cld_roots.cld_do(&clds, worker_id);
+ }
_thread_roots.oops_do(oops, NULL, worker_id);
- _cld_roots.cld_do(&clds, worker_id);
_code_roots.code_blobs_do(&blobsCl, worker_id);
_weak_roots.oops_do(&always_true, oops, worker_id);
--- old/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp 2019-06-11 20:26:22.253694838 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp 2019-06-11 20:26:21.743693932 -0400
@@ -61,9 +61,16 @@
void oops_do(OopClosure* cl, uint worker_id);
};
-class ShenandoahJNIHandleRoots : public ShenandoahSerialRoot {
+template
+class ShenandoahJNIHandleRoots {
+private:
+ volatile bool _claimed;
+ OopStorage::ParState _itr;
public:
ShenandoahJNIHandleRoots();
+
+ template
+ void oops_do(T* cl, uint worker_id = 0);
};
class ShenandoahThreadRoots {
@@ -108,12 +115,14 @@
void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
};
+template
class ShenandoahClassLoaderDataRoots {
public:
ShenandoahClassLoaderDataRoots();
+ ~ShenandoahClassLoaderDataRoots();
- void always_strong_cld_do(CLDClosure* clds, uint worker_id);
- void cld_do(CLDClosure* clds, uint worker_id);
+ void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
+ void cld_do(CLDClosure* clds, uint worker_id = 0);
};
class ShenandoahRootProcessor : public StackObj {
@@ -130,11 +139,11 @@
template
class ShenandoahRootScanner : public ShenandoahRootProcessor {
private:
- ShenandoahSerialRoots _serial_roots;
- ShenandoahJNIHandleRoots _jni_roots;
- ShenandoahClassLoaderDataRoots _cld_roots;
- ShenandoahThreadRoots _thread_roots;
- ShenandoahCodeCacheRoots _code_roots;
+ ShenandoahSerialRoots _serial_roots;
+ ShenandoahJNIHandleRoots<> _jni_roots;
+ ShenandoahClassLoaderDataRoots<> _cld_roots;
+ ShenandoahThreadRoots _thread_roots;
+ ShenandoahCodeCacheRoots _code_roots;
public:
ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
@@ -158,16 +167,17 @@
// Evacuate all roots at a safepoint
class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
private:
- ShenandoahSerialRoots _serial_roots;
- ShenandoahJNIHandleRoots _jni_roots;
- ShenandoahClassLoaderDataRoots _cld_roots;
- ShenandoahThreadRoots _thread_roots;
- ShenandoahWeakRoots _weak_roots;
- ShenandoahStringDedupRoots _dedup_roots;
+ ShenandoahSerialRoots _serial_roots;
+ ShenandoahJNIHandleRoots<> _jni_roots;
+ ShenandoahClassLoaderDataRoots<> _cld_roots;
+ ShenandoahThreadRoots _thread_roots;
+ ShenandoahWeakRoots _weak_roots;
+ ShenandoahStringDedupRoots _dedup_roots;
ShenandoahCodeCacheRoots _code_roots;
+ bool _include_concurrent_roots;
public:
- ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase);
+ ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots);
void roots_do(uint worker_id, OopClosure* oops);
};
@@ -175,14 +185,14 @@
// Update all roots at a safepoint
class ShenandoahRootUpdater : public ShenandoahRootProcessor {
private:
- ShenandoahSerialRoots _serial_roots;
- ShenandoahJNIHandleRoots _jni_roots;
- ShenandoahClassLoaderDataRoots _cld_roots;
- ShenandoahThreadRoots _thread_roots;
- ShenandoahWeakRoots _weak_roots;
- ShenandoahStringDedupRoots _dedup_roots;
+ ShenandoahSerialRoots _serial_roots;
+ ShenandoahJNIHandleRoots<> _jni_roots;
+ ShenandoahClassLoaderDataRoots<> _cld_roots;
+ ShenandoahThreadRoots _thread_roots;
+ ShenandoahWeakRoots _weak_roots;
+ ShenandoahStringDedupRoots _dedup_roots;
ShenandoahCodeCacheRoots _code_roots;
- const bool _update_code_cache;
+ const bool _update_code_cache;
public:
ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache);
@@ -194,12 +204,12 @@
// Adjuster all roots at a safepoint during full gc
class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
private:
- ShenandoahSerialRoots _serial_roots;
- ShenandoahJNIHandleRoots _jni_roots;
- ShenandoahClassLoaderDataRoots _cld_roots;
- ShenandoahThreadRoots _thread_roots;
- ShenandoahWeakRoots _weak_roots;
- ShenandoahStringDedupRoots _dedup_roots;
+ ShenandoahSerialRoots _serial_roots;
+ ShenandoahJNIHandleRoots<> _jni_roots;
+ ShenandoahClassLoaderDataRoots<> _cld_roots;
+ ShenandoahThreadRoots _thread_roots;
+ ShenandoahWeakRoots _weak_roots;
+ ShenandoahStringDedupRoots _dedup_roots;
ShenandoahCodeCacheRoots _code_roots;
public:
--- old/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp 2019-06-11 20:26:23.606697244 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp 2019-06-11 20:26:23.076696301 -0400
@@ -24,17 +24,76 @@
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
+#include "classfile/classLoaderDataGraph.hpp"
+#include "gc/shared/oopStorageParState.inline.hpp"
#include "gc/shenandoah/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahRootProcessor.hpp"
#include "gc/shenandoah/shenandoahTimingTracker.hpp"
#include "gc/shenandoah/shenandoahUtils.hpp"
#include "memory/resourceArea.hpp"
+template
+ShenandoahJNIHandleRoots::ShenandoahJNIHandleRoots() :
+ _claimed(false),
+ _itr(JNIHandles::global_handles()) {
+}
+
+template
+template
+void ShenandoahJNIHandleRoots::oops_do(T* cl, uint worker_id) {
+ if (CONCURRENT) {
+ _itr.oops_do(cl);
+ } else {
+ if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
+ ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+ ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
+ _itr.oops_do(cl);
+ }
+ }
+}
+
template
void ShenandoahWeakRoots::oops_do(IsAlive* is_alive, KeepAlive* keep_alive, uint worker_id) {
_task.work(worker_id, is_alive, keep_alive);
}
+template
+ShenandoahClassLoaderDataRoots::ShenandoahClassLoaderDataRoots() {
+ ClassLoaderDataGraph::clear_claimed_marks();
+ if (CONCURRENT) {
+ ClassLoaderDataGraph_lock->lock();
+ }
+}
+
+template
+ShenandoahClassLoaderDataRoots::~ShenandoahClassLoaderDataRoots() {
+ if (CONCURRENT) {
+ ClassLoaderDataGraph_lock->unlock();
+ }
+}
+
+template
+void ShenandoahClassLoaderDataRoots::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
+ if (CONCURRENT) {
+ ClassLoaderDataGraph::always_strong_cld_do(clds);
+ } else {
+ ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+ ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
+ ClassLoaderDataGraph::always_strong_cld_do(clds);
+ }
+}
+
+template
+void ShenandoahClassLoaderDataRoots::cld_do(CLDClosure* clds, uint worker_id) {
+ if (CONCURRENT) {
+ ClassLoaderDataGraph::cld_do(clds);
+ } else {
+ ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+ ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
+ ClassLoaderDataGraph::cld_do(clds);
+ }
+}
+
template
ShenandoahCodeCacheRoots::ShenandoahCodeCacheRoots() {
nmethod::oops_do_marking_prologue();
--- old/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp 2019-06-11 20:26:24.780699330 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.cpp 2019-06-11 20:26:24.280698442 -0400
@@ -54,6 +54,10 @@
return (_types & type) != 0;
}
+ShenandoahRootVerifier::RootTypes ShenandoahRootVerifier::combine(RootTypes t1, RootTypes t2) {
+ return static_cast(static_cast(t1) | static_cast(t2));
+}
+
void ShenandoahRootVerifier::oops_do(OopClosure* oops) {
CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
if (verify(CodeRoots)) {
--- old/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp 2019-06-11 20:26:25.892701307 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahRootVerifier.hpp 2019-06-11 20:26:25.428700482 -0400
@@ -52,6 +52,8 @@
// Used to seed ShenandoahVerifier, do not honor root type filter
void roots_do(OopClosure* cl);
void strong_roots_do(OopClosure* cl);
+
+ static RootTypes combine(RootTypes t1, RootTypes t2);
private:
bool verify(RootTypes type) const;
};
--- old/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp 2019-06-11 20:26:26.985703250 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp 2019-06-11 20:26:26.508702402 -0400
@@ -214,7 +214,7 @@
void work(uint worker_id) {
ShenandoahConcurrentWorkerSession worker_session(worker_id);
- ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetJoiner stsj;
ShenandoahEvacOOMScope oom_evac_scope;
ShenandoahTraversalGC* traversal_gc = _heap->traversal_gc();
@@ -534,7 +534,7 @@
if (work == 0) {
// No more work, try to terminate
ShenandoahEvacOOMScopeLeaver oom_scope_leaver;
- ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield && ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetLeaver stsl(sts_yield);
ShenandoahTerminationTimingsTracker term_tracker(worker_id);
ShenandoahTerminatorTerminator tt(_heap);
@@ -847,7 +847,7 @@
void work(uint worker_id) {
assert(worker_id == 0, "The code below is single-threaded, only one worker is expected");
ShenandoahParallelWorkerSession worker_session(worker_id);
- ShenandoahSuspendibleThreadSetJoiner stsj(ShenandoahSuspendibleWorkers);
+ ShenandoahSuspendibleThreadSetJoiner stsj;
ShenandoahEvacOOMScope oom_evac_scope;
ShenandoahHeap* sh = ShenandoahHeap::heap();
--- old/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp 2019-06-11 20:26:28.038705122 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.cpp 2019-06-11 20:26:27.564704279 -0400
@@ -30,6 +30,7 @@
uint ShenandoahWorkerPolicy::_prev_par_marking = 0;
uint ShenandoahWorkerPolicy::_prev_conc_marking = 0;
uint ShenandoahWorkerPolicy::_prev_conc_evac = 0;
+uint ShenandoahWorkerPolicy::_prev_conc_root_proc = 0;
uint ShenandoahWorkerPolicy::_prev_fullgc = 0;
uint ShenandoahWorkerPolicy::_prev_degengc = 0;
uint ShenandoahWorkerPolicy::_prev_stw_traversal = 0;
@@ -63,6 +64,16 @@
return _prev_par_marking;
}
+// Calculate workers for concurrent root processing
+uint ShenandoahWorkerPolicy::calc_workers_for_conc_root_processing() {
+ uint active_workers = (_prev_conc_root_proc == 0) ? ConcGCThreads : _prev_conc_root_proc;
+ _prev_conc_root_proc =
+ WorkerPolicy::calc_active_conc_workers(ConcGCThreads,
+ active_workers,
+ Threads::number_of_non_daemon_threads());
+ return _prev_conc_root_proc;
+}
+
// Calculate workers for concurrent evacuation (concurrent GC)
uint ShenandoahWorkerPolicy::calc_workers_for_conc_evac() {
uint active_workers = (_prev_conc_evac == 0) ? ConcGCThreads : _prev_conc_evac;
--- old/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp 2019-06-11 20:26:29.151707100 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp 2019-06-11 20:26:28.685706272 -0400
@@ -30,6 +30,7 @@
private:
static uint _prev_par_marking;
static uint _prev_conc_marking;
+ static uint _prev_conc_root_proc;
static uint _prev_conc_evac;
static uint _prev_fullgc;
static uint _prev_degengc;
@@ -50,6 +51,9 @@
// Calculate the number of workers for final marking
static uint calc_workers_for_final_marking();
+ // Calculate workers for concurrent root processing
+ static uint calc_workers_for_conc_root_processing();
+
// Calculate workers for concurrent evacuation (concurrent GC)
static uint calc_workers_for_conc_evac();
--- old/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp 2019-06-11 20:26:30.282709111 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp 2019-06-11 20:26:29.790708236 -0400
@@ -343,9 +343,6 @@
"definitely alive references to avoid dealing with them during " \
"pause.") \
\
- experimental(bool, ShenandoahSuspendibleWorkers, false, \
- "Suspend concurrent GC worker threads at safepoints") \
- \
diagnostic(bool, ShenandoahSATBBarrier, true, \
"Turn on/off SATB barriers in Shenandoah") \
\
--- old/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java 2019-06-11 20:26:31.447711182 -0400
+++ new/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java 2019-06-11 20:26:30.988710366 -0400
@@ -45,12 +45,6 @@
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static TestAllocObjects
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact TestAllocObjects
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal TestAllocObjects
- *
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=adaptive -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=static -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=compact -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -Xms1g -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahSuspendibleWorkers TestAllocObjects
*/
import java.util.Random;
--- /dev/null 2019-06-03 18:05:13.248999865 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.cpp 2019-06-11 20:26:32.015712191 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
+
+bool ShenandoahConcurrentRoots::can_do_concurrent_roots() {
+ // Don't support traversal GC at this moment
+ return !ShenandoahHeap::heap()->is_concurrent_traversal_in_progress();
+}
+
+bool ShenandoahConcurrentRoots::should_do_concurrent_roots() {
+ ShenandoahHeap* const heap = ShenandoahHeap::heap();
+ bool stw_gc_in_progress = heap->is_full_gc_in_progress() ||
+ heap->is_degenerated_gc_in_progress();
+ return can_do_concurrent_roots() &&
+ !stw_gc_in_progress;
+}
--- /dev/null 2019-06-03 18:05:13.248999865 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahConcurrentRoots.hpp 2019-06-11 20:26:33.139714189 -0400
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTROOTS_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTROOTS_HPP
+
+#include "memory/allocation.hpp"
+
+class ShenandoahConcurrentRoots : public AllStatic {
+public:
+ // Can GC settings allow concurrent root processing
+ static bool can_do_concurrent_roots();
+ // If current GC cycle can process roots concurrently
+ static bool should_do_concurrent_roots();
+};
+
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTROOTS_HPP