Skip to content

Commit

Permalink
Introduce ShenandoahGenerationType and templatize most closures with it.
Browse files Browse the repository at this point in the history
The template expands for only the NON_GEN type for the non-generational
version of Shenandoah currently, and will in the future accomodate
Generational Shenandoah.
  • Loading branch information
ysramakrishna committed Feb 10, 2024
1 parent 729ae1d commit 9c86856
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 51 deletions.
25 changes: 15 additions & 10 deletions src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "runtime/continuation.hpp"
#include "runtime/threads.hpp"

template <ShenandoahGenerationType GENERATION>
class ShenandoahConcurrentMarkingTask : public WorkerTask {
private:
ShenandoahConcurrentMark* const _cm;
Expand All @@ -61,7 +62,7 @@ class ShenandoahConcurrentMarkingTask : public WorkerTask {
ShenandoahReferenceProcessor* rp = heap->ref_processor();
assert(rp != nullptr, "need reference processor");
StringDedup::Requests requests;
_cm->mark_loop(worker_id, _terminator, rp,
_cm->mark_loop(GENERATION, worker_id, _terminator, rp,
true /*cancellable*/,
ShenandoahStringDedup::is_enabled() ? ENQUEUE_DEDUP : NO_DEDUP,
&requests);
Expand Down Expand Up @@ -90,6 +91,7 @@ class ShenandoahSATBAndRemarkThreadsClosure : public ThreadClosure {
}
};

template <ShenandoahGenerationType GENERATION>
class ShenandoahFinalMarkingTask : public WorkerTask {
private:
ShenandoahConcurrentMark* _cm;
Expand All @@ -112,17 +114,17 @@ class ShenandoahFinalMarkingTask : public WorkerTask {
{
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,
_cm->mark_loop(GENERATION, worker_id, _terminator, rp,
false /*not cancellable*/,
_dedup_string ? ENQUEUE_DEDUP : NO_DEDUP,
&requests);
Expand All @@ -134,6 +136,7 @@ ShenandoahConcurrentMark::ShenandoahConcurrentMark() :
ShenandoahMark() {}

// Mark concurrent roots during concurrent phases
template <ShenandoahGenerationType GENERATION>
class ShenandoahMarkConcurrentRootsTask : public WorkerTask {
private:
SuspendibleThreadSetJoiner _sts_joiner;
Expand All @@ -149,7 +152,8 @@ class ShenandoahMarkConcurrentRootsTask : public WorkerTask {
void work(uint worker_id);
};

ShenandoahMarkConcurrentRootsTask::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs,
template <ShenandoahGenerationType GENERATION>
ShenandoahMarkConcurrentRootsTask<GENERATION>::ShenandoahMarkConcurrentRootsTask(ShenandoahObjToScanQueueSet* qs,
ShenandoahReferenceProcessor* rp,
ShenandoahPhaseTimings::Phase phase,
uint nworkers) :
Expand All @@ -160,10 +164,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);
}

Expand All @@ -176,7 +181,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);
}
Expand Down Expand Up @@ -204,7 +209,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()) {
Expand Down Expand Up @@ -254,7 +259,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");
Expand Down
6 changes: 4 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@

#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();
Expand Down
42 changes: 42 additions & 0 deletions src/hotspot/share/gc/shenandoah/shenandoahGenerationType.hpp
Original file line number Diff line number Diff line change
@@ -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
39 changes: 22 additions & 17 deletions src/hotspot/share/gc/shenandoah/shenandoahMark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -76,48 +76,53 @@ 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);
}

void ShenandoahMark::mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
bool cancellable, StringDedupMode dedup_mode, StringDedup::Requests* const req) {
template<bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void ShenandoahMark::mark_loop(ShenandoahGenerationType generation /* ignored */, uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp, StringDedup::Requests* const req) {
mark_loop_prework<NON_GEN, CANCELLABLE, STRING_DEDUP>(worker_id, terminator, rp, req);
}

void ShenandoahMark::mark_loop(ShenandoahGenerationType generation, uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
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>(generation, worker_id, terminator, rp, req);
break;
case ENQUEUE_DEDUP:
mark_loop_prework<true, ENQUEUE_DEDUP>(worker_id, terminator, rp, req);
mark_loop<true, ENQUEUE_DEDUP>(generation, worker_id, terminator, rp, req);
break;
case ALWAYS_DEDUP:
mark_loop_prework<true, ALWAYS_DEDUP>(worker_id, terminator, rp, req);
mark_loop<true, ALWAYS_DEDUP>(generation, worker_id, terminator, rp, 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>(generation, worker_id, terminator, rp, req);
break;
case ENQUEUE_DEDUP:
mark_loop_prework<false, ENQUEUE_DEDUP>(worker_id, terminator, rp, req);
mark_loop<false, ENQUEUE_DEDUP>(generation, worker_id, terminator, rp, req);
break;
case ALWAYS_DEDUP:
mark_loop_prework<false, ALWAYS_DEDUP>(worker_id, terminator, rp, req);
mark_loop<false, ALWAYS_DEDUP>(generation, worker_id, terminator, rp, 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;

Expand Down Expand Up @@ -146,7 +151,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();
Expand All @@ -156,7 +161,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();

/*
Expand All @@ -175,7 +180,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;
Expand Down
15 changes: 10 additions & 5 deletions src/hotspot/share/gc/shenandoah/shenandoahMark.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shared/taskTerminator.hpp"
#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahOopClosures.hpp"
#include "gc/shenandoah/shenandoahTaskqueue.hpp"

Expand All @@ -41,7 +42,7 @@ class ShenandoahMark: public StackObj {
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();
Expand All @@ -56,7 +57,7 @@ class ShenandoahMark: public StackObj {

// ---------- 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>
Expand All @@ -65,18 +66,22 @@ class ShenandoahMark: public StackObj {
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:
void mark_loop(uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
template<bool CANCELLABLE, StringDedupMode STRING_DEDUP>
void mark_loop(ShenandoahGenerationType generation, uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
StringDedup::Requests* const req);
void mark_loop(ShenandoahGenerationType generation, uint worker_id, TaskTerminator* terminator, ShenandoahReferenceProcessor *rp,
bool cancellable, StringDedupMode dedup_mode, StringDedup::Requests* const req);
};

Expand Down
10 changes: 6 additions & 4 deletions src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,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();

Expand Down Expand Up @@ -94,14 +94,15 @@ 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.
do_chunked_array<T>(q, cl, obj, task->chunk(), task->pow(), weak);
}
}

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);
Expand Down Expand Up @@ -229,6 +230,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;
Expand All @@ -246,12 +248,12 @@ class ShenandoahSATBBufferClosure : public SATBBufferClosure {
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)) {
Expand Down
Loading

0 comments on commit 9c86856

Please sign in to comment.