From f62f2adbc3ec3cf8a9a59d3d766c60d11ebd77e2 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Sat, 2 Mar 2024 02:02:09 +0000 Subject: [PATCH] 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 --- .../shenandoah/shenandoahConcurrentMark.cpp | 27 ++++++------ .../shenandoah/shenandoahConcurrentMark.hpp | 7 +++- .../shenandoah/shenandoahGenerationType.hpp | 42 +++++++++++++++++++ .../share/gc/shenandoah/shenandoahMark.cpp | 39 ++++++++++------- .../share/gc/shenandoah/shenandoahMark.hpp | 15 ++++--- .../gc/shenandoah/shenandoahMark.inline.hpp | 10 +++-- .../gc/shenandoah/shenandoahOopClosures.hpp | 11 +++-- .../shenandoahOopClosures.inline.hpp | 8 ++-- .../share/gc/shenandoah/shenandoahSTWMark.cpp | 15 ++++--- 9 files changed, 121 insertions(+), 53 deletions(-) create mode 100644 src/hotspot/share/gc/shenandoah/shenandoahGenerationType.hpp 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 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 class ShenandoahFinalMarkingTask : public WorkerTask { private: ShenandoahConcurrentMark* _cm; @@ -112,18 +113,17 @@ public: { ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id); - ShenandoahSATBBufferClosure cl(q); + ShenandoahSATBBufferClosure 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 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 class ShenandoahMarkConcurrentRootsTask : public WorkerTask { private: SuspendibleThreadSetJoiner _sts_joiner; @@ -149,7 +150,8 @@ public: void work(uint worker_id); }; -ShenandoahMarkConcurrentRootsTask::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs, +template +ShenandoahMarkConcurrentRootsTask::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 +void ShenandoahMarkConcurrentRootsTask::work(uint worker_id) { ShenandoahConcurrentWorkerSession worker_session(worker_id); ShenandoahObjToScanQueue* q = _queue_set->queue(worker_id); - ShenandoahMarkRefsClosure cl(q, _rp); + ShenandoahMarkRefsClosure 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 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 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 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 class ShenandoahConcurrentMarkingTask; +template class ShenandoahFinalMarkingTask; class ShenandoahConcurrentMark: public ShenandoahMark { - friend class ShenandoahConcurrentMarkingTask; - friend class ShenandoahFinalMarkingTask; + template friend class ShenandoahConcurrentMarkingTask; + template 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 +template 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; Closure cl(q, rp); - mark_loop_work(&cl, ld, w, t, req); + mark_loop_work(&cl, ld, w, t, req); } else { - using Closure = ShenandoahMarkRefsClosure; + using Closure = ShenandoahMarkRefsClosure; Closure cl(q, rp); - mark_loop_work(&cl, ld, w, t, req); + mark_loop_work(&cl, ld, w, t, req); } heap->flush_liveness_cache(w); } +template 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(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(worker_id, terminator, rp, req); + mark_loop(worker_id, terminator, rp, generation, req); break; case ENQUEUE_DEDUP: - mark_loop_prework(worker_id, terminator, rp, req); + mark_loop(worker_id, terminator, rp, generation, req); break; case ALWAYS_DEDUP: - mark_loop_prework(worker_id, terminator, rp, req); + mark_loop(worker_id, terminator, rp, generation, req); break; } } else { switch(dedup_mode) { case NO_DEDUP: - mark_loop_prework(worker_id, terminator, rp, req); + mark_loop(worker_id, terminator, rp, generation, req); break; case ENQUEUE_DEDUP: - mark_loop_prework(worker_id, terminator, rp, req); + mark_loop(worker_id, terminator, rp, generation, req); break; case ALWAYS_DEDUP: - mark_loop_prework(worker_id, terminator, rp, req); + mark_loop(worker_id, terminator, rp, generation, req); break; } } } -template +template 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(q, cl, live_data, req, &t); + do_task(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 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(q, cl, live_data, req, &t); + do_task(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 + template 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 + template inline void do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveData* live_data, StringDedup::Requests* const req, ShenandoahMarkTask* task); template @@ -74,19 +75,23 @@ private: template inline void do_chunked_array(ShenandoahObjToScanQueue* q, T* cl, oop array, int chunk, int pow, bool weak); + template inline void count_liveness(ShenandoahLiveData* live_data, oop obj); - template + template void mark_loop_work(T* cl, ShenandoahLiveData* live_data, uint worker_id, TaskTerminator *t, StringDedup::Requests* const req); - template + template void mark_loop_prework(uint worker_id, TaskTerminator *terminator, ShenandoahReferenceProcessor *rp, StringDedup::Requests* const req); template inline void dedup_string(oop obj, StringDedup::Requests* const req); protected: + template 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 +template 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(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 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 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(p, _queue, _mark_context, false); + ShenandoahMark::mark_through_ref(p, _queue, _mark_context, false); } } }; -template +template 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 + template void work(T *p); public: @@ -64,7 +65,7 @@ class ShenandoahMarkUpdateRefsSuperClosure : public ShenandoahMarkRefsSuperClosu protected: ShenandoahHeap* const _heap; - template + template inline void work(T* p); public: @@ -75,10 +76,11 @@ public: }; }; +template class ShenandoahMarkUpdateRefsClosure : public ShenandoahMarkUpdateRefsSuperClosure { private: template - inline void do_oop_work(T* p) { work(p); } + inline void do_oop_work(T* p) { work(p); } public: ShenandoahMarkUpdateRefsClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp) : @@ -88,10 +90,11 @@ public: virtual void do_oop(oop* p) { do_oop_work(p); } }; +template class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure { private: template - inline void do_oop_work(T* p) { work(p); } + inline void do_oop_work(T* p) { work(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 +template inline void ShenandoahMarkRefsSuperClosure::work(T* p) { - ShenandoahMark::mark_through_ref(p, _queue, _mark_context, _weak); + ShenandoahMark::mark_through_ref(p, _queue, _mark_context, _weak); } -template +template inline void ShenandoahMarkUpdateRefsSuperClosure::work(T* p) { // Update the location _heap->update_with_forwarded(p); // ...then do the usual thing - ShenandoahMarkRefsSuperClosure::work(p); + ShenandoahMarkRefsSuperClosure::work(p); } template 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 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 +ShenandoahInitMarkRootsClosure::ShenandoahInitMarkRootsClosure(ShenandoahObjToScanQueue* q) : _queue(q), _mark_context(ShenandoahHeap::heap()->marking_context()) { } +template template -void ShenandoahInitMarkRootsClosure::do_oop_work(T* p) { - ShenandoahMark::mark_through_ref(p, _queue, _mark_context, false); +void ShenandoahInitMarkRootsClosure::do_oop_work(T* p) { + ShenandoahMark::mark_through_ref(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 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); }