Path: blob/master/src/hotspot/share/gc/parallel/psClosure.inline.hpp
66644 views
/*1* Copyright (c) 2018, 2021, Oracle and/or its affiliates. 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*/2324#ifndef SHARE_GC_PARALLEL_PSCLOSURE_INLINE_HPP25#define SHARE_GC_PARALLEL_PSCLOSURE_INLINE_HPP2627// No psClosure.hpp2829#include "gc/parallel/psPromotionManager.inline.hpp"30#include "gc/parallel/psScavenge.inline.hpp"31#include "memory/iterator.hpp"32#include "oops/access.inline.hpp"33#include "oops/oop.inline.hpp"34#include "utilities/globalDefinitions.hpp"3536class PSAdjustWeakRootsClosure final: public OopClosure {37public:38virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); }3940virtual void do_oop(oop* p) {41if (PSScavenge::should_scavenge(p)) {42oop o = RawAccess<IS_NOT_NULL>::oop_load(p);43assert(o->is_forwarded(), "Objects are already forwarded before weak processing");44oop new_obj = o->forwardee();45if (log_develop_is_enabled(Trace, gc, scavenge)) {46ResourceMark rm; // required by internal_name()47log_develop_trace(gc, scavenge)("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",48"forwarding",49new_obj->klass()->internal_name(), p2i((void *)o), p2i((void *)new_obj), new_obj->size());50}51RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);52}53}54};5556template <bool promote_immediately>57class PSRootsClosure: public OopClosure {58private:59PSPromotionManager* _promotion_manager;6061template <class T> void do_oop_work(T *p) {62if (PSScavenge::should_scavenge(p)) {63// We never card mark roots, maybe call a func without test?64_promotion_manager->copy_and_push_safe_barrier<promote_immediately>(p);65}66}67public:68PSRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }69void do_oop(oop* p) { PSRootsClosure::do_oop_work(p); }70void do_oop(narrowOop* p) { PSRootsClosure::do_oop_work(p); }71};7273typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;74typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;7576// Scavenges a single oop in a ClassLoaderData.77class PSScavengeFromCLDClosure: public OopClosure {78private:79PSPromotionManager* _pm;80// Used to redirty a scanned cld if it has oops81// pointing to the young generation after being scanned.82ClassLoaderData* _scanned_cld;83public:84PSScavengeFromCLDClosure(PSPromotionManager* pm) : _pm(pm), _scanned_cld(NULL) { }85void do_oop(narrowOop* p) { ShouldNotReachHere(); }86void do_oop(oop* p) {87ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();88assert(!psh->is_in_reserved(p), "GC barrier needed");89if (PSScavenge::should_scavenge(p)) {90assert(PSScavenge::should_scavenge(p, true), "revisiting object?");9192oop o = RawAccess<IS_NOT_NULL>::oop_load(p);93oop new_obj = _pm->copy_to_survivor_space</*promote_immediately=*/false>(o);94RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);9596if (PSScavenge::is_obj_in_young(new_obj)) {97do_cld_barrier();98}99}100}101102void set_scanned_cld(ClassLoaderData* cld) {103assert(_scanned_cld == NULL || cld == NULL, "Should always only handling one cld at a time");104_scanned_cld = cld;105}106107private:108void do_cld_barrier() {109assert(_scanned_cld != NULL, "Should not be called without having a scanned cld");110_scanned_cld->record_modified_oops();111}112};113114// Scavenges the oop in a ClassLoaderData.115class PSScavengeCLDClosure: public CLDClosure {116private:117PSScavengeFromCLDClosure _oop_closure;118public:119PSScavengeCLDClosure(PSPromotionManager* pm) : _oop_closure(pm) { }120void do_cld(ClassLoaderData* cld) {121// If the cld has not been dirtied we know that there's122// no references into the young gen and we can skip it.123124if (cld->has_modified_oops()) {125// Setup the promotion manager to redirty this cld126// if references are left in the young gen.127_oop_closure.set_scanned_cld(cld);128129// Clean the cld since we're going to scavenge all the metadata.130cld->oops_do(&_oop_closure, false, /*clear_modified_oops*/true);131132_oop_closure.set_scanned_cld(NULL);133}134}135};136137#endif // SHARE_GC_PARALLEL_PSCLOSURE_INLINE_HPP138139140