summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorY. Srinivas Ramakrishna <ysr@openjdk.org>2024-03-02 02:02:09 +0000
committerY. Srinivas Ramakrishna <ysr@openjdk.org>2024-03-02 02:02:09 +0000
commitf62f2adbc3ec3cf8a9a59d3d766c60d11ebd77e2 (patch)
tree8b52f81644b2004c2a31462ce92acc4f7cae1c61
parentf68a4b9fc4b0add186754465bbeb908b8362be8d (diff)
8325671: Shenandoah: Introduce a ShenandoahGenerationType and templatize certain marking closures with it
In support of eventually supporting a generational version of Shenandoah, we introduce a ShenandoahGenerationType enum which currently has a single NON_GEN value for Shenandoah. The generational extension of Shenandoah will introduce additional enum values when GenShen is integrated. These will be used to specialize certain marking closures via templatization, such that suitable variations of the marking (and in the future other) closures can be used for the generational and non-generational variants of the collector while minimizing interference between the two variants while maximizing code-sharing without affecting correctness or performance. This ticket introduces the new enum type and templatizes certain existing marking closures. In effect, this should be semantically a no-op for current (non-generational) Shenandoah and ideally completely performance-neutral (to be established via measurements). **Testing:** - [x] jtreg hotspot_gc - [x] github actions - [ ] codepipeline perf & stress: in progress **Performance:** - [ ] specjbb w/shenandoah - [ ] codepipeline perf: in progress Reviewed-by: kdnilsen, shade
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp27
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp7
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahGenerationType.hpp42
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahMark.cpp39
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahMark.hpp15
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp10
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp11
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp8
-rw-r--r--src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp15
9 files changed, 121 insertions, 53 deletions
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
index f3c72dfc0b1..fa37fcbcfd3 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
@@ -44,6 +44,7 @@
#include "runtime/continuation.hpp"
#include "runtime/threads.hpp"
+template <ShenandoahGenerationType GENERATION>
class ShenandoahConcurrentMarkingTask : public WorkerTask {
private:
ShenandoahConcurrentMark* const _cm;
@@ -61,8 +62,7 @@ public:
ShenandoahReferenceProcessor* rp = heap->ref_processor();
assert(rp != nullptr, "need reference processor");
StringDedup::Requests requests;
- _cm->mark_loop(worker_id, _terminator, rp,
- true /*cancellable*/,
+ _cm->mark_loop(worker_id, _terminator, rp, GENERATION, true /*cancellable*/,
ShenandoahStringDedup::is_enabled() ? ENQUEUE_DEDUP : NO_DEDUP,
&requests);
}
@@ -90,6 +90,7 @@ public:
}
};
+template <ShenandoahGenerationType GENERATION>
class ShenandoahFinalMarkingTask : public WorkerTask {
private:
ShenandoahConcurrentMark* _cm;
@@ -112,18 +113,17 @@ public:
{
ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
- ShenandoahSATBBufferClosure cl(q);
+ ShenandoahSATBBufferClosure<GENERATION> cl(q);
SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
while (satb_mq_set.apply_closure_to_completed_buffer(&cl)) {}
assert(!heap->has_forwarded_objects(), "Not expected");
- ShenandoahMarkRefsClosure mark_cl(q, rp);
+ ShenandoahMarkRefsClosure<GENERATION> mark_cl(q, rp);
ShenandoahSATBAndRemarkThreadsClosure tc(satb_mq_set,
ShenandoahIUBarrier ? &mark_cl : nullptr);
Threads::possibly_parallel_threads_do(true /* is_par */, &tc);
}
- _cm->mark_loop(worker_id, _terminator, rp,
- false /*not cancellable*/,
+ _cm->mark_loop(worker_id, _terminator, rp, GENERATION, false /*not cancellable*/,
_dedup_string ? ENQUEUE_DEDUP : NO_DEDUP,
&requests);
assert(_cm->task_queues()->is_empty(), "Should be empty");
@@ -134,6 +134,7 @@ ShenandoahConcurrentMark::ShenandoahConcurrentMark() :
ShenandoahMark() {}
// Mark concurrent roots during concurrent phases
+template <ShenandoahGenerationType GENERATION>
class ShenandoahMarkConcurrentRootsTask : public WorkerTask {
private:
SuspendibleThreadSetJoiner _sts_joiner;
@@ -149,7 +150,8 @@ public:
void work(uint worker_id);
};
-ShenandoahMarkConcurrentRootsTask::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs,
+template <ShenandoahGenerationType GENERATION>
+ShenandoahMarkConcurrentRootsTask<GENERATION>::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs,
ShenandoahReferenceProcessor* rp,
ShenandoahPhaseTimings::Phase phase,
uint nworkers) :
@@ -160,10 +162,11 @@ ShenandoahMarkConcurrentRootsTask::ShenandoahMarkConcurrentRootsTask(ShenandoahO
assert(!ShenandoahHeap::heap()->has_forwarded_objects(), "Not expected");
}
-void ShenandoahMarkConcurrentRootsTask::work(uint worker_id) {
+template <ShenandoahGenerationType GENERATION>
+void ShenandoahMarkConcurrentRootsTask<GENERATION>::work(uint worker_id) {
ShenandoahConcurrentWorkerSession worker_session(worker_id);
ShenandoahObjToScanQueue* q = _queue_set->queue(worker_id);
- ShenandoahMarkRefsClosure cl(q, _rp);
+ ShenandoahMarkRefsClosure<GENERATION> cl(q, _rp);
_root_scanner.roots_do(&cl, worker_id);
}
@@ -176,7 +179,7 @@ void ShenandoahConcurrentMark::mark_concurrent_roots() {
WorkerThreads* workers = heap->workers();
ShenandoahReferenceProcessor* rp = heap->ref_processor();
task_queues()->reserve(workers->active_workers());
- ShenandoahMarkConcurrentRootsTask task(task_queues(), rp, ShenandoahPhaseTimings::conc_mark_roots, workers->active_workers());
+ ShenandoahMarkConcurrentRootsTask<NON_GEN> task(task_queues(), rp, ShenandoahPhaseTimings::conc_mark_roots, workers->active_workers());
workers->run_task(&task);
}
@@ -204,7 +207,7 @@ void ShenandoahConcurrentMark::concurrent_mark() {
ShenandoahFlushSATBHandshakeClosure flush_satb(qset);
for (uint flushes = 0; flushes < ShenandoahMaxSATBBufferFlushes; flushes++) {
TaskTerminator terminator(nworkers, task_queues());
- ShenandoahConcurrentMarkingTask task(this, &terminator);
+ ShenandoahConcurrentMarkingTask<NON_GEN> task(this, &terminator);
workers->run_task(&task);
if (heap->cancelled_gc()) {
@@ -254,7 +257,7 @@ void ShenandoahConcurrentMark::finish_mark_work() {
StrongRootsScope scope(nworkers);
TaskTerminator terminator(nworkers, task_queues());
- ShenandoahFinalMarkingTask task(this, &terminator, ShenandoahStringDedup::is_enabled());
+ ShenandoahFinalMarkingTask<NON_GEN> task(this, &terminator, ShenandoahStringDedup::is_enabled());
heap->workers()->run_task(&task);
assert(task_queues()->is_empty(), "Should be empty");
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp
index fbcd075117a..b658e42dfb8 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp
@@ -25,14 +25,17 @@
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHCONCURRENTMARK_HPP
+#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahMark.hpp"
+template <ShenandoahGenerationType GENERATION>
class ShenandoahConcurrentMarkingTask;
+template <ShenandoahGenerationType GENERATION>
class ShenandoahFinalMarkingTask;
class ShenandoahConcurrentMark: public ShenandoahMark {
- friend class ShenandoahConcurrentMarkingTask;
- friend class ShenandoahFinalMarkingTask;
+ template <ShenandoahGenerationType GENERATION> friend class ShenandoahConcurrentMarkingTask;
+ template <ShenandoahGenerationType GENERATION> friend class ShenandoahFinalMarkingTask;
public:
ShenandoahConcurrentMark();
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationType.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationType.hpp
new file mode 100644
index 00000000000..1132fd5eb4d
--- /dev/null
+++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationType.hpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * 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_SHENANDOAHGENERATIONTYPE_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONTYPE_HPP
+
+enum ShenandoahGenerationType {
+ NON_GEN // non-generational
+};
+
+inline const char* shenandoah_generation_name(ShenandoahGenerationType mode) {
+ switch (mode) {
+ case NON_GEN:
+ return "Non-Generational";
+ default:
+ ShouldNotReachHere();
+ return "Unknown";
+ }
+}
+
+#endif // SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONTYPE_HPP
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp
index 4725b8c3dfa..4c45f4a7659 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.cpp
@@ -66,7 +66,7 @@ void ShenandoahMark::clear() {
ShenandoahBarrierSet::satb_mark_queue_set().abandon_partial_marking();
}
-template <bool CANCELLABLE, StringDedupMode STRING_DEDUP>
+template <ShenandoahGenerationType GENERATION, bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void ShenandoahMark::mark_loop_prework(uint w, TaskTerminator *t, ShenandoahReferenceProcessor *rp, StringDedup::Requests* const req) {
ShenandoahObjToScanQueue* q = get_queue(w);
@@ -76,48 +76,55 @@ void ShenandoahMark::mark_loop_prework(uint w, TaskTerminator *t, ShenandoahRefe
// TODO: We can clean up this if we figure out how to do templated oop closures that
// play nice with specialized_oop_iterators.
if (heap->has_forwarded_objects()) {
- using Closure = ShenandoahMarkUpdateRefsClosure;
+ using Closure = ShenandoahMarkUpdateRefsClosure<GENERATION>;
Closure cl(q, rp);
- mark_loop_work<Closure, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
+ mark_loop_work<Closure, GENERATION, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
} else {
- using Closure = ShenandoahMarkRefsClosure;
+ using Closure = ShenandoahMarkRefsClosure<GENERATION>;
Closure cl(q, rp);
- mark_loop_work<Closure, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
+ mark_loop_work<Closure, GENERATION, CANCELLABLE, STRING_DEDUP>(&cl, ld, w, t, req);
}
heap->flush_liveness_cache(w);
}
+template<bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void ShenandoahMark::mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
- bool cancellable, StringDedupMode dedup_mode, StringDedup::Requests* const req) {
+ ShenandoahGenerationType generation, StringDedup::Requests* const req) {
+ mark_loop_prework<NON_GEN, CANCELLABLE, STRING_DEDUP>(worker_id, terminator, rp, req);
+}
+
+void ShenandoahMark::mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
+ ShenandoahGenerationType generation, bool cancellable, StringDedupMode dedup_mode,
+ StringDedup::Requests* const req) {
if (cancellable) {
switch(dedup_mode) {
case NO_DEDUP:
- mark_loop_prework<true, NO_DEDUP>(worker_id, terminator, rp, req);
+ mark_loop<true, NO_DEDUP>(worker_id, terminator, rp, generation, req);
break;
case ENQUEUE_DEDUP:
- mark_loop_prework<true, ENQUEUE_DEDUP>(worker_id, terminator, rp, req);
+ mark_loop<true, ENQUEUE_DEDUP>(worker_id, terminator, rp, generation, req);
break;
case ALWAYS_DEDUP:
- mark_loop_prework<true, ALWAYS_DEDUP>(worker_id, terminator, rp, req);
+ mark_loop<true, ALWAYS_DEDUP>(worker_id, terminator, rp, generation, req);
break;
}
} else {
switch(dedup_mode) {
case NO_DEDUP:
- mark_loop_prework<false, NO_DEDUP>(worker_id, terminator, rp, req);
+ mark_loop<false, NO_DEDUP>(worker_id, terminator, rp, generation, req);
break;
case ENQUEUE_DEDUP:
- mark_loop_prework<false, ENQUEUE_DEDUP>(worker_id, terminator, rp, req);
+ mark_loop<false, ENQUEUE_DEDUP>(worker_id, terminator, rp, generation, req);
break;
case ALWAYS_DEDUP:
- mark_loop_prework<false, ALWAYS_DEDUP>(worker_id, terminator, rp, req);
+ mark_loop<false, ALWAYS_DEDUP>(worker_id, terminator, rp, generation, req);
break;
}
}
}
-template <class T, bool CANCELLABLE, StringDedupMode STRING_DEDUP>
+template <class T, ShenandoahGenerationType GENERATION, bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *terminator, StringDedup::Requests* const req) {
uintx stride = ShenandoahMarkLoopStride;
@@ -146,7 +153,7 @@ void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint w
for (uint i = 0; i < stride; i++) {
if (q->pop(t)) {
- do_task<T, STRING_DEDUP>(q, cl, live_data, req, &t);
+ do_task<T, GENERATION, STRING_DEDUP>(q, cl, live_data, req, &t);
} else {
assert(q->is_empty(), "Must be empty");
q = queues->claim_next();
@@ -156,7 +163,7 @@ void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint w
}
q = get_queue(worker_id);
- ShenandoahSATBBufferClosure drain_satb(q);
+ ShenandoahSATBBufferClosure<GENERATION> drain_satb(q);
SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
/*
@@ -175,7 +182,7 @@ void ShenandoahMark::mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint w
for (uint i = 0; i < stride; i++) {
if (q->pop(t) ||
queues->steal(worker_id, t)) {
- do_task<T, STRING_DEDUP>(q, cl, live_data, req, &t);
+ do_task<T, GENERATION, STRING_DEDUP>(q, cl, live_data, req, &t);
work++;
} else {
break;
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.hpp
index 8731aa7a068..fab913bfd94 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahMark.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.hpp
@@ -27,6 +27,7 @@
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shared/taskTerminator.hpp"
+#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahTaskqueue.hpp"
@@ -50,7 +51,7 @@ protected:
ShenandoahMark();
public:
- template<class T>
+ template<class T, ShenandoahGenerationType GENERATION>
static inline void mark_through_ref(T* p, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context, bool weak);
static void clear();
@@ -65,7 +66,7 @@ public:
// ---------- Marking loop and tasks
private:
- template <class T, StringDedupMode STRING_DEDUP>
+ template <class T, ShenandoahGenerationType GENERATION, StringDedupMode STRING_DEDUP>
inline void do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, StringDedup::Requests* const req, ShenandoahMarkTask* task);
template <class T>
@@ -74,19 +75,23 @@ private:
template <class T>
inline void do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop array, int chunk, int pow, bool weak);
+ template <ShenandoahGenerationType GENERATION>
inline void count_liveness(ShenandoahLiveData* live_data, oop obj);
- template <class T, bool CANCELLABLE,StringDedupMode STRING_DEDUP>
+ template <class T, ShenandoahGenerationType GENERATION, bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *t, StringDedup::Requests* const req);
- template <bool CANCELLABLE, StringDedupMode STRING_DEDUP>
+ template <ShenandoahGenerationType GENERATION, bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void mark_loop_prework(uint worker_id, TaskTerminator *terminator, ShenandoahReferenceProcessor *rp, StringDedup::Requests* const req);
template <StringDedupMode STRING_DEDUP>
inline void dedup_string(oop obj, StringDedup::Requests* const req);
protected:
+ template<bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
- bool cancellable, StringDedupMode dedup_mode, StringDedup::Requests* const req);
+ ShenandoahGenerationType generation, StringDedup::Requests* const req);
+ void mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
+ ShenandoahGenerationType generation, bool cancellable, StringDedupMode dedup_mode, StringDedup::Requests* const req);
};
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHMARK_HPP
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
index 9ca7272815f..99995c469eb 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
@@ -57,7 +57,7 @@ void ShenandoahMark::dedup_string(oop obj, StringDedup::Requests* const req) {
}
}
-template <class T, StringDedupMode STRING_DEDUP>
+template <class T, ShenandoahGenerationType GENERATION, StringDedupMode STRING_DEDUP>
void ShenandoahMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, StringDedup::Requests* const req, ShenandoahMarkTask* task) {
oop obj = task->obj();
@@ -95,7 +95,7 @@ void ShenandoahMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveD
// Avoid double-counting objects that are visited twice due to upgrade
// from final- to strong mark.
if (task->count_liveness()) {
- count_liveness(live_data, obj);
+ count_liveness<GENERATION>(live_data, obj);
}
} else {
// Case 4: Array chunk, has sensible chunk id. Process it.
@@ -103,6 +103,7 @@ void ShenandoahMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveD
}
}
+template <ShenandoahGenerationType GENERATION>
inline void ShenandoahMark::count_liveness(ShenandoahLiveData* live_data, oop obj) {
ShenandoahHeap* const heap = ShenandoahHeap::heap();
size_t region_idx = heap->heap_region_index_containing(obj);
@@ -230,6 +231,7 @@ inline void ShenandoahMark::do_chunked_array(ShenandoahObjToScanQueue* q, T* cl,
array->oop_iterate_range(cl, from, to);
}
+template <ShenandoahGenerationType GENERATION>
class ShenandoahSATBBufferClosure : public SATBBufferClosure {
private:
ShenandoahObjToScanQueue* _queue;
@@ -247,12 +249,12 @@ public:
assert(size == 0 || !_heap->has_forwarded_objects(), "Forwarded objects are not expected here");
for (size_t i = 0; i < size; ++i) {
oop *p = (oop *) &buffer[i];
- ShenandoahMark::mark_through_ref<oop>(p, _queue, _mark_context, false);
+ ShenandoahMark::mark_through_ref<oop, GENERATION>(p, _queue, _mark_context, false);
}
}
};
-template<class T>
+template<class T, ShenandoahGenerationType GENERATION>
inline void ShenandoahMark::mark_through_ref(T* p, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context, bool weak) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp
index d8aad6ab6f0..e433c2910c8 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp
@@ -27,6 +27,7 @@
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
+#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahTaskqueue.hpp"
#include "gc/shenandoah/shenandoahUtils.hpp"
@@ -40,7 +41,7 @@ private:
bool _weak;
protected:
- template <class T>
+ template <class T, ShenandoahGenerationType GENERATION>
void work(T *p);
public:
@@ -64,7 +65,7 @@ class ShenandoahMarkUpdateRefsSuperClosure : public ShenandoahMarkRefsSuperClosu
protected:
ShenandoahHeap* const _heap;
- template <class T>
+ template <class T, ShenandoahGenerationType GENERATION>
inline void work(T* p);
public:
@@ -75,10 +76,11 @@ public:
};
};
+template <ShenandoahGenerationType GENERATION>
class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkUpdateRefsSuperClosure {
private:
template <class T>
- inline void do_oop_work(T* p) { work<T>(p); }
+ inline void do_oop_work(T* p) { work<T, GENERATION>(p); }
public:
ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) :
@@ -88,10 +90,11 @@ public:
virtual void do_oop(oop* p) { do_oop_work(p); }
};
+template <ShenandoahGenerationType GENERATION>
class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
private:
template <class T>
- inline void do_oop_work(T* p) { work<T>(p); }
+ inline void do_oop_work(T* p) { work<T, GENERATION>(p); }
public:
ShenandoahMarkRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) :
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp
index 1812b4e8f05..70d7e94fb50 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.inline.hpp
@@ -30,18 +30,18 @@
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahMark.inline.hpp"
-template<class T>
+template<class T, ShenandoahGenerationType GENERATION>
inline void ShenandoahMarkRefsSuperClosure::work(T* p) {
- ShenandoahMark::mark_through_ref<T>(p, _queue, _mark_context, _weak);
+ ShenandoahMark::mark_through_ref<T, GENERATION>(p, _queue, _mark_context, _weak);
}
-template<class T>
+template<class T, ShenandoahGenerationType GENERATION>
inline void ShenandoahMarkUpdateRefsSuperClosure::work(T* p) {
// Update the location
_heap->update_with_forwarded(p);
// ...then do the usual thing
- ShenandoahMarkRefsSuperClosure::work<T>(p);
+ ShenandoahMarkRefsSuperClosure::work<T, GENERATION>(p);
}
template<class T>
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp
index d9ca5e0a042..05cd8ef66b9 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp
@@ -29,6 +29,7 @@
#include "gc/shared/taskTerminator.hpp"
#include "gc/shared/workerThread.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
+#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahMark.inline.hpp"
#include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
#include "gc/shenandoah/shenandoahReferenceProcessor.hpp"
@@ -36,6 +37,7 @@
#include "gc/shenandoah/shenandoahSTWMark.hpp"
#include "gc/shenandoah/shenandoahVerifier.hpp"
+template<ShenandoahGenerationType GENERATION>
class ShenandoahInitMarkRootsClosure : public OopClosure {
private:
ShenandoahObjToScanQueue* const _queue;
@@ -50,14 +52,16 @@ public:
void do_oop(oop* p) { do_oop_work(p); }
};
-ShenandoahInitMarkRootsClosure::ShenandoahInitMarkRootsClosure(ShenandoahObjToScanQueue* q) :
+template <ShenandoahGenerationType GENERATION>
+ShenandoahInitMarkRootsClosure<GENERATION>::ShenandoahInitMarkRootsClosure(ShenandoahObjToScanQueue* q) :
_queue(q),
_mark_context(ShenandoahHeap::heap()->marking_context()) {
}
+template <ShenandoahGenerationType GENERATION>
template <class T>
-void ShenandoahInitMarkRootsClosure::do_oop_work(T* p) {
- ShenandoahMark::mark_through_ref<T>(p, _queue, _mark_context, false);
+void ShenandoahInitMarkRootsClosure<GENERATION>::do_oop_work(T* p) {
+ ShenandoahMark::mark_through_ref<T, GENERATION>(p, _queue, _mark_context, false);
}
class ShenandoahSTWMarkTask : public WorkerTask {
@@ -134,7 +138,7 @@ void ShenandoahSTWMark::mark() {
}
void ShenandoahSTWMark::mark_roots(uint worker_id) {
- ShenandoahInitMarkRootsClosure init_mark(task_queues()->queue(worker_id));
+ ShenandoahInitMarkRootsClosure<NON_GEN> init_mark(task_queues()->queue(worker_id));
_root_scanner.roots_do(&init_mark, worker_id);
}
@@ -144,7 +148,6 @@ void ShenandoahSTWMark::finish_mark(uint worker_id) {
ShenandoahReferenceProcessor* rp = ShenandoahHeap::heap()->ref_processor();
StringDedup::Requests requests;
- mark_loop(worker_id, &_terminator, rp,
- false /* not cancellable */,
+ mark_loop(worker_id, &_terminator, rp, NON_GEN, false /* not cancellable */,
ShenandoahStringDedup::is_enabled() ? ALWAYS_DEDUP : NO_DEDUP, &requests);
}