Path: blob/master/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp
40961 views
/*1* Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/23#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP24#define SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_INLINE_HPP2526#include "gc/shenandoah/shenandoahClosures.hpp"2728#include "gc/shared/barrierSetNMethod.hpp"29#include "gc/shenandoah/shenandoahAsserts.hpp"30#include "gc/shenandoah/shenandoahBarrierSet.hpp"31#include "gc/shenandoah/shenandoahEvacOOMHandler.inline.hpp"32#include "gc/shenandoah/shenandoahHeap.inline.hpp"33#include "gc/shenandoah/shenandoahNMethod.inline.hpp"34#include "oops/compressedOops.inline.hpp"35#include "runtime/atomic.hpp"36#include "runtime/thread.hpp"3738ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :39_mark_context(ShenandoahHeap::heap()->marking_context()) {40}4142bool ShenandoahForwardedIsAliveClosure::do_object_b(oop obj) {43if (CompressedOops::is_null(obj)) {44return false;45}46obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);47shenandoah_assert_not_forwarded_if(NULL, obj, ShenandoahHeap::heap()->is_concurrent_mark_in_progress());48return _mark_context->is_marked(obj);49}5051ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() :52_mark_context(ShenandoahHeap::heap()->marking_context()) {53}5455bool ShenandoahIsAliveClosure::do_object_b(oop obj) {56if (CompressedOops::is_null(obj)) {57return false;58}59shenandoah_assert_not_forwarded(NULL, obj);60return _mark_context->is_marked(obj);61}6263BoolObjectClosure* ShenandoahIsAliveSelector::is_alive_closure() {64return ShenandoahHeap::heap()->has_forwarded_objects() ?65reinterpret_cast<BoolObjectClosure*>(&_fwd_alive_cl) :66reinterpret_cast<BoolObjectClosure*>(&_alive_cl);67}6869ShenandoahKeepAliveClosure::ShenandoahKeepAliveClosure() :70_bs(static_cast<ShenandoahBarrierSet*>(BarrierSet::barrier_set())) {71}7273void ShenandoahKeepAliveClosure::do_oop(oop* p) {74do_oop_work(p);75}7677void ShenandoahKeepAliveClosure::do_oop(narrowOop* p) {78do_oop_work(p);79}8081template <typename T>82void ShenandoahKeepAliveClosure::do_oop_work(T* p) {83assert(ShenandoahHeap::heap()->is_concurrent_mark_in_progress(), "Only for concurrent marking phase");84assert(!ShenandoahHeap::heap()->has_forwarded_objects(), "Not expected");8586T o = RawAccess<>::oop_load(p);87if (!CompressedOops::is_null(o)) {88oop obj = CompressedOops::decode_not_null(o);89_bs->enqueue(obj);90}91}9293ShenandoahUpdateRefsClosure::ShenandoahUpdateRefsClosure() :94_heap(ShenandoahHeap::heap()) {95}9697template <class T>98void ShenandoahUpdateRefsClosure::do_oop_work(T* p) {99_heap->update_with_forwarded(p);100}101102void ShenandoahUpdateRefsClosure::do_oop(oop* p) { do_oop_work(p); }103void ShenandoahUpdateRefsClosure::do_oop(narrowOop* p) { do_oop_work(p); }104105template <DecoratorSet MO>106ShenandoahEvacuateUpdateMetadataClosure<MO>::ShenandoahEvacuateUpdateMetadataClosure() :107_heap(ShenandoahHeap::heap()), _thread(Thread::current()) {108}109110template <DecoratorSet MO>111template <class T>112void ShenandoahEvacuateUpdateMetadataClosure<MO>::do_oop_work(T* p) {113assert(_heap->is_concurrent_weak_root_in_progress() ||114_heap->is_concurrent_strong_root_in_progress(),115"Only do this in root processing phase");116assert(_thread == Thread::current(), "Wrong thread");117118T o = RawAccess<>::oop_load(p);119if (! CompressedOops::is_null(o)) {120oop obj = CompressedOops::decode_not_null(o);121if (_heap->in_collection_set(obj)) {122assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");123shenandoah_assert_marked(p, obj);124oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);125if (resolved == obj) {126resolved = _heap->evacuate_object(obj, _thread);127}128RawAccess<IS_NOT_NULL | MO>::oop_store(p, resolved);129}130}131}132template <DecoratorSet MO>133void ShenandoahEvacuateUpdateMetadataClosure<MO>::do_oop(oop* p) {134do_oop_work(p);135}136137template <DecoratorSet MO>138void ShenandoahEvacuateUpdateMetadataClosure<MO>::do_oop(narrowOop* p) {139do_oop_work(p);140}141142ShenandoahEvacuateUpdateRootsClosure::ShenandoahEvacuateUpdateRootsClosure() :143_heap(ShenandoahHeap::heap()) {144}145146template <typename T>147void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p, Thread* t) {148assert(_heap->is_concurrent_weak_root_in_progress() ||149_heap->is_concurrent_strong_root_in_progress(),150"Only do this in root processing phase");151assert(t == Thread::current(), "Wrong thread");152153T o = RawAccess<>::oop_load(p);154if (!CompressedOops::is_null(o)) {155oop obj = CompressedOops::decode_not_null(o);156if (_heap->in_collection_set(obj)) {157assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress");158shenandoah_assert_marked(p, obj);159oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);160if (resolved == obj) {161resolved = _heap->evacuate_object(obj, t);162}163_heap->cas_oop(resolved, p, o);164}165}166}167168void ShenandoahEvacuateUpdateRootsClosure::do_oop(oop* p) {169ShenandoahEvacOOMScope scope;170do_oop_work(p, Thread::current());171}172173void ShenandoahEvacuateUpdateRootsClosure::do_oop(narrowOop* p) {174ShenandoahEvacOOMScope scope;175do_oop_work(p, Thread::current());176}177178ShenandoahContextEvacuateUpdateRootsClosure::ShenandoahContextEvacuateUpdateRootsClosure() :179ShenandoahEvacuateUpdateRootsClosure(),180_thread(Thread::current()) {181}182183void ShenandoahContextEvacuateUpdateRootsClosure::do_oop(oop* p) {184ShenandoahEvacOOMScope scope;185do_oop_work(p, _thread);186}187188void ShenandoahContextEvacuateUpdateRootsClosure::do_oop(narrowOop* p) {189ShenandoahEvacOOMScope scope;190do_oop_work(p, _thread);191}192193template <bool CONCURRENT, typename IsAlive, typename KeepAlive>194ShenandoahCleanUpdateWeakOopsClosure<CONCURRENT, IsAlive, KeepAlive>::ShenandoahCleanUpdateWeakOopsClosure(IsAlive* is_alive, KeepAlive* keep_alive) :195_is_alive(is_alive), _keep_alive(keep_alive) {196if (!CONCURRENT) {197assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");198}199}200201template <bool CONCURRENT, typename IsAlive, typename KeepAlive>202void ShenandoahCleanUpdateWeakOopsClosure<CONCURRENT, IsAlive, KeepAlive>::do_oop(oop* p) {203oop obj = RawAccess<>::oop_load(p);204if (!CompressedOops::is_null(obj)) {205if (_is_alive->do_object_b(obj)) {206_keep_alive->do_oop(p);207} else {208if (CONCURRENT) {209Atomic::cmpxchg(p, obj, oop());210} else {211RawAccess<IS_NOT_NULL>::oop_store(p, oop());212}213}214}215}216217template <bool CONCURRENT, typename IsAlive, typename KeepAlive>218void ShenandoahCleanUpdateWeakOopsClosure<CONCURRENT, IsAlive, KeepAlive>::do_oop(narrowOop* p) {219ShouldNotReachHere();220}221222ShenandoahCodeBlobAndDisarmClosure::ShenandoahCodeBlobAndDisarmClosure(OopClosure* cl) :223CodeBlobToOopClosure(cl, true /* fix_relocations */),224_bs(BarrierSet::barrier_set()->barrier_set_nmethod()) {225}226227void ShenandoahCodeBlobAndDisarmClosure::do_code_blob(CodeBlob* cb) {228nmethod* const nm = cb->as_nmethod_or_null();229if (nm != NULL && nm->oops_do_try_claim()) {230assert(!ShenandoahNMethod::gc_data(nm)->is_unregistered(), "Should not be here");231CodeBlobToOopClosure::do_code_blob(cb);232_bs->disarm(nm);233}234}235236#ifdef ASSERT237template <class T>238void ShenandoahAssertNotForwardedClosure::do_oop_work(T* p) {239T o = RawAccess<>::oop_load(p);240if (!CompressedOops::is_null(o)) {241oop obj = CompressedOops::decode_not_null(o);242shenandoah_assert_not_forwarded(p, obj);243}244}245246void ShenandoahAssertNotForwardedClosure::do_oop(narrowOop* p) { do_oop_work(p); }247void ShenandoahAssertNotForwardedClosure::do_oop(oop* p) { do_oop_work(p); }248#endif249250#endif // SHARE_GC_SHENANDOAH_SHENANDOAHCLOSURES_HPP251252253