Skip to content
Permalink
Browse files

8234974: Shenandoah: Do concurrent roots even when no evacuation is n…

…ecessary

Reviewed-by: zgu
  • Loading branch information
rkennke committed Dec 12, 2019
1 parent e4c332c commit 8a54d97a4d78f7b9e2ab942159c8b1913957d905
@@ -264,7 +264,7 @@ oop ShenandoahBarrierSet::load_reference_barrier_native_impl(oop obj, T* load_ad
}

ShenandoahMarkingContext* const marking_context = _heap->marking_context();
if (_heap->is_evacuation_in_progress() && !marking_context->is_marked(obj)) {
if (_heap->is_concurrent_root_in_progress() && !marking_context->is_marked(obj)) {
Thread* thr = Thread::current();
if (thr->is_Java_thread()) {
return NULL;
@@ -111,12 +111,13 @@ ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() :

template <class T>
void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress");

T o = RawAccess<>::oop_load(p);
if (! CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
if (_heap->in_collection_set(obj)) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
shenandoah_assert_marked(p, obj);
oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
if (resolved == obj) {
@@ -139,11 +140,12 @@ ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsC
}

void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress");

oop obj = RawAccess<>::oop_load(p);
if (! CompressedOops::is_null(obj)) {
if (_heap->in_collection_set(obj)) {
assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");
shenandoah_assert_marked(p, obj);
oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
if (resolved == obj) {
@@ -155,7 +155,7 @@ void ShenandoahCodeRoots::flush_nmethod(nmethod* nm) {
}
}

void ShenandoahCodeRoots::prepare_concurrent_unloading() {
void ShenandoahCodeRoots::arm_nmethods() {
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
_disarmed_value ++;
// 0 is reserved for new nmethod
@@ -224,7 +224,9 @@ class ShenandoahNMethodUnlinkClosure : public NMethodClosure {

// Heal oops and disarm
ShenandoahEvacOOMScope evac_scope;
ShenandoahNMethod::heal_nmethod(nm);
if (_heap->is_evacuation_in_progress()) {
ShenandoahNMethod::heal_nmethod(nm);
}
ShenandoahNMethod::disarm_nmethod(nm);

// Clear compiled ICs and exception caches
@@ -109,7 +109,7 @@ class ShenandoahCodeRoots : public AllStatic {
// Concurrent nmethod unloading support
static void unlink(WorkGang* workers, bool unloading_occurred);
static void purge(WorkGang* workers);
static void prepare_concurrent_unloading();
static void arm_nmethods();
static int disarmed_value() { return _disarmed_value; }
static int* disarmed_value_address() { return &_disarmed_value; }

@@ -542,6 +542,7 @@ void ShenandoahHeap::print_on(outputStream* st) const {
if (is_degenerated_gc_in_progress()) st->print("degenerated gc, ");
if (is_full_gc_in_progress()) st->print("full gc, ");
if (is_full_gc_move_in_progress()) st->print("full gc move, ");
if (is_concurrent_root_in_progress()) st->print("concurrent roots, ");

if (cancelled_gc()) {
st->print("cancelled");
@@ -1540,6 +1541,11 @@ void ShenandoahHeap::op_final_mark() {
_free_set->rebuild();
}

if (!is_degenerated_gc_in_progress()) {
prepare_concurrent_roots();
prepare_concurrent_unloading();
}

// If collection set has candidates, start evacuation.
// Otherwise, bypass the rest of the cycle.
if (!collection_set()->is_empty()) {
@@ -1554,8 +1560,9 @@ void ShenandoahHeap::op_final_mark() {
set_has_forwarded_objects(true);

if (!is_degenerated_gc_in_progress()) {
prepare_concurrent_roots();
prepare_concurrent_unloading();
if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
ShenandoahCodeRoots::arm_nmethods();
}
evacuate_and_update_roots();
}

@@ -1669,7 +1676,7 @@ class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
};

void ShenandoahHeap::op_roots() {
if (is_evacuation_in_progress()) {
if (is_concurrent_root_in_progress()) {
if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
_unloader.unload();
}
@@ -2235,7 +2242,6 @@ void ShenandoahHeap::prepare_concurrent_roots() {
void ShenandoahHeap::prepare_concurrent_unloading() {
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) {
ShenandoahCodeRoots::prepare_concurrent_unloading();
_unloader.prepare();
}
}
@@ -79,7 +79,7 @@ class ShenandoahIsUnloadingBehaviour : public IsUnloadingBehaviour {
public:
virtual bool is_unloading(CompiledMethod* method) const {
nmethod* const nm = method->as_nmethod();
guarantee(ShenandoahHeap::heap()->is_evacuation_in_progress(), "Only this phase");
guarantee(ShenandoahHeap::heap()->is_concurrent_root_in_progress(), "Only this phase");
ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
ShenandoahReentrantLocker locker(data->lock());
ShenandoahIsUnloadingOopClosure cl;
@@ -166,7 +166,7 @@ class ShenandoahUnloadRendezvousClosure : public HandshakeClosure {

void ShenandoahUnload::unload() {
assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?");
if (!ShenandoahHeap::heap()->is_evacuation_in_progress()) {
if (!ShenandoahHeap::heap()->is_concurrent_root_in_progress()) {
return;
}

0 comments on commit 8a54d97

Please sign in to comment.
You can’t perform that action at this time.