8234974: Shenandoah: Do concurrent roots even when no evacuation is necessary

Reviewed-by: zgu
This commit is contained in:
Roman Kennke 2019-12-12 18:34:30 +01:00
parent be6b4aab40
commit 450b97f593
6 changed files with 22 additions and 12 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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 @@ public:
// 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

View File

@ -109,7 +109,7 @@ public:
// 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; }

View File

@ -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 @@ public:
};
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();
}
}

View File

@ -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 @@ public:
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;
}