< prev index next > src/hotspot/share/gc/shenandoah/shenandoahSTWMark.cpp
Print this page
#include "gc/shared/strongRootsScope.hpp"
#include "gc/shared/taskTerminator.hpp"
#include "gc/shared/workerThread.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
+ #include "gc/shenandoah/shenandoahGeneration.hpp"
#include "gc/shenandoah/shenandoahMark.inline.hpp"
#include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
#include "gc/shenandoah/shenandoahReferenceProcessor.hpp"
#include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
#include "gc/shenandoah/shenandoahSTWMark.hpp"
#include "gc/shenandoah/shenandoahVerifier.hpp"
+ template<GenerationMode GENERATION>
class ShenandoahInitMarkRootsClosure : public OopClosure {
- private:
+ private:
ShenandoahObjToScanQueue* const _queue;
ShenandoahMarkingContext* const _mark_context;
template <class T>
- inline void do_oop_work(T* p);
- public:
+ inline void do_oop_work(T* p);
+
+ public:
ShenandoahInitMarkRootsClosure(ShenandoahObjToScanQueue* q);
void do_oop(narrowOop* p) { do_oop_work(p); }
void do_oop(oop* p) { do_oop_work(p); }
};
- ShenandoahInitMarkRootsClosure::ShenandoahInitMarkRootsClosure(ShenandoahObjToScanQueue* q) :
- _queue(q),
- _mark_context(ShenandoahHeap::heap()->marking_context()) {
+ template<GenerationMode GENERATION>
+ ShenandoahInitMarkRootsClosure<GENERATION>::ShenandoahInitMarkRootsClosure(ShenandoahObjToScanQueue* q) :
+ _queue(q),
+ _mark_context(ShenandoahHeap::heap()->marking_context()) {
}
+ template <GenerationMode 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) {
+ // Only called from STW mark, should not be used to bootstrap old generation marking.
+ ShenandoahMark::mark_through_ref<T, GENERATION>(p, _queue, nullptr, _mark_context, false);
}
class ShenandoahSTWMarkTask : public WorkerTask {
private:
ShenandoahSTWMark* const _mark;
ShenandoahParallelWorkerSession worker_session(worker_id);
_mark->mark_roots(worker_id);
_mark->finish_mark(worker_id);
}
- ShenandoahSTWMark::ShenandoahSTWMark(bool full_gc) :
- ShenandoahMark(),
+ ShenandoahSTWMark::ShenandoahSTWMark(ShenandoahGeneration* generation, bool full_gc) :
+ ShenandoahMark(generation),
_root_scanner(full_gc ? ShenandoahPhaseTimings::full_gc_mark : ShenandoahPhaseTimings::degen_gc_stw_mark),
- _terminator(ShenandoahHeap::heap()->workers()->active_workers(), ShenandoahHeap::heap()->marking_context()->task_queues()),
+ _terminator(ShenandoahHeap::heap()->workers()->active_workers(), task_queues()),
_full_gc(full_gc) {
assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at a Shenandoah safepoint");
}
void ShenandoahSTWMark::mark() {
// Weak reference processing
ShenandoahHeap* const heap = ShenandoahHeap::heap();
- ShenandoahReferenceProcessor* rp = heap->ref_processor();
+ ShenandoahReferenceProcessor* rp = heap->active_generation()->ref_processor();
rp->reset_thread_locals();
rp->set_soft_reference_policy(heap->soft_ref_policy()->should_clear_all_soft_refs());
// Init mark, do not expect forwarded pointers in roots
if (ShenandoahVerify) {
TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
{
// Mark
+ if (_generation->generation_mode() == YOUNG) {
+ // But only scan the remembered set for young generation.
+ _generation->scan_remembered_set(false /* is_concurrent */);
+ }
+
StrongRootsScope scope(nworkers);
ShenandoahSTWMarkTask task(this);
heap->workers()->run_task(&task);
assert(task_queues()->is_empty(), "Should be empty");
}
- heap->mark_complete_marking_context();
+ _generation->set_mark_complete();
end_mark();
assert(task_queues()->is_empty(), "Should be empty");
TASKQUEUE_STATS_ONLY(task_queues()->print_taskqueue_stats());
TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
}
void ShenandoahSTWMark::mark_roots(uint worker_id) {
- ShenandoahInitMarkRootsClosure init_mark(task_queues()->queue(worker_id));
- _root_scanner.roots_do(&init_mark, worker_id);
+ switch (_generation->generation_mode()) {
+ case GLOBAL: {
+ ShenandoahInitMarkRootsClosure<GLOBAL> init_mark(task_queues()->queue(worker_id));
+ _root_scanner.roots_do(&init_mark, worker_id);
+ break;
+ }
+ case YOUNG: {
+ ShenandoahInitMarkRootsClosure<YOUNG> init_mark(task_queues()->queue(worker_id));
+ _root_scanner.roots_do(&init_mark, worker_id);
+ break;
+ }
+ default:
+ ShouldNotReachHere();
+ }
}
void ShenandoahSTWMark::finish_mark(uint worker_id) {
ShenandoahPhaseTimings::Phase phase = _full_gc ? ShenandoahPhaseTimings::full_gc_mark : ShenandoahPhaseTimings::degen_gc_stw_mark;
ShenandoahWorkerTimingsTracker timer(phase, ShenandoahPhaseTimings::ParallelMark, worker_id);
- ShenandoahReferenceProcessor* rp = ShenandoahHeap::heap()->ref_processor();
+ ShenandoahReferenceProcessor* rp = ShenandoahHeap::heap()->active_generation()->ref_processor();
StringDedup::Requests requests;
- mark_loop(worker_id, &_terminator, rp,
+ mark_loop(_generation->generation_mode(),
+ worker_id, &_terminator, rp,
false /* not cancellable */,
ShenandoahStringDedup::is_enabled() ? ALWAYS_DEDUP : NO_DEDUP, &requests);
}
< prev index next >