8231324: Shenandoah: avoid duplicated weak root works during final traversal
Reviewed-by: rkennke
--- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp Fri Oct 18 14:56:01 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp Fri Oct 18 11:36:35 2019 -0400
@@ -27,6 +27,7 @@
class ShenandoahHeap;
class ShenandoahMarkingContext;
+class ShenandoahHeapRegionSet;
class Thread;
class ShenandoahForwardedIsAliveClosure: public BoolObjectClosure {
@@ -65,6 +66,20 @@
inline void do_oop_work(T* p);
};
+class ShenandoahTraversalUpdateRefsClosure: public OopClosure {
+private:
+ ShenandoahHeap* const _heap;
+ ShenandoahHeapRegionSet* const _traversal_set;
+
+public:
+ inline ShenandoahTraversalUpdateRefsClosure();
+ inline void do_oop(oop* p);
+ inline void do_oop(narrowOop* p);
+private:
+ template <class T>
+ inline void do_oop_work(T* p);
+};
+
class ShenandoahEvacuateUpdateRootsClosure: public BasicOopIterateClosure {
private:
ShenandoahHeap* _heap;
--- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp Fri Oct 18 14:56:01 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp Fri Oct 18 11:36:35 2019 -0400
@@ -26,6 +26,7 @@
#include "gc/shenandoah/shenandoahAsserts.hpp"
#include "gc/shenandoah/shenandoahClosures.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
+#include "gc/shenandoah/shenandoahTraversalGC.hpp"
#include "oops/compressedOops.inline.hpp"
#include "runtime/thread.hpp"
@@ -78,6 +79,29 @@
void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }
void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
+ShenandoahTraversalUpdateRefsClosure::ShenandoahTraversalUpdateRefsClosure() :
+ _heap(ShenandoahHeap::heap()),
+ _traversal_set(ShenandoahHeap::heap()->traversal_gc()->traversal_set()) {
+ assert(_heap->is_traversal_mode(), "Why we here?");
+}
+
+template <class T>
+void ShenandoahTraversalUpdateRefsClosure::do_oop_work(T* p) {
+ T o = RawAccess<>::oop_load(p);
+ if (!CompressedOops::is_null(o)) {
+ oop obj = CompressedOops::decode_not_null(o);
+ if (_heap->in_collection_set(obj) || _traversal_set->is_in((HeapWord*)obj)) {
+ obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
+ RawAccess<IS_NOT_NULL>::oop_store(p, obj);
+ } else {
+ shenandoah_assert_not_forwarded(p, obj);
+ }
+ }
+}
+
+void ShenandoahTraversalUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }
+void ShenandoahTraversalUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }
+
ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() :
_heap(ShenandoahHeap::heap()), _thread(Thread::current()) {
}
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Fri Oct 18 14:56:01 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Fri Oct 18 11:36:35 2019 -0400
@@ -2042,11 +2042,19 @@
// Cleanup weak roots
ShenandoahGCPhase phase(timing_phase);
if (has_forwarded_objects()) {
- ShenandoahForwardedIsAliveClosure is_alive;
- ShenandoahUpdateRefsClosure keep_alive;
- ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahUpdateRefsClosure>
- cleaning_task(&is_alive, &keep_alive, num_workers);
- _workers->run_task(&cleaning_task);
+ if (is_traversal_mode()) {
+ ShenandoahForwardedIsAliveClosure is_alive;
+ ShenandoahTraversalUpdateRefsClosure keep_alive;
+ ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalUpdateRefsClosure>
+ cleaning_task(&is_alive, &keep_alive, num_workers);
+ _workers->run_task(&cleaning_task);
+ } else {
+ ShenandoahForwardedIsAliveClosure is_alive;
+ ShenandoahUpdateRefsClosure keep_alive;
+ ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahUpdateRefsClosure>
+ cleaning_task(&is_alive, &keep_alive, num_workers);
+ _workers->run_task(&cleaning_task);
+ }
} else {
ShenandoahIsAliveClosure is_alive;
#ifdef ASSERT
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Fri Oct 18 14:56:01 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Fri Oct 18 11:36:35 2019 -0400
@@ -189,6 +189,18 @@
_thread_roots(n_workers > 1) {
}
+void ShenandoahRootUpdater::strong_roots_do(uint worker_id, OopClosure* oops_cl) {
+ CodeBlobToOopClosure update_blobs(oops_cl, CodeBlobToOopClosure::FixRelocations);
+ CLDToOopClosure clds(oops_cl, ClassLoaderData::_claim_strong);
+
+ _serial_roots.oops_do(oops_cl, worker_id);
+ _vm_roots.oops_do(oops_cl, worker_id);
+
+ _thread_roots.oops_do(oops_cl, NULL, worker_id);
+ _cld_roots.cld_do(&clds, worker_id);
+ _code_roots.code_blobs_do(&update_blobs, worker_id);
+}
+
ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
ShenandoahRootProcessor(phase),
_thread_roots(n_workers > 1) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Fri Oct 18 14:56:01 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Fri Oct 18 11:36:35 2019 -0400
@@ -304,6 +304,8 @@
template<typename IsAlive, typename KeepAlive>
void roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive);
+
+ void strong_roots_do(uint worker_id, OopClosure* oops_cl);
};
// Adjuster all roots at a safepoint during full gc
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Fri Oct 18 14:56:01 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Fri Oct 18 11:36:35 2019 -0400
@@ -700,8 +700,7 @@
void work(uint worker_id) {
ShenandoahParallelWorkerSession worker_session(worker_id);
ShenandoahTraversalFixRootsClosure cl;
- ShenandoahForwardedIsAliveClosure is_alive;
- _rp->roots_do<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalFixRootsClosure>(worker_id, &is_alive, &cl);
+ _rp->strong_roots_do(worker_id, &cl);
}
};