Path: blob/master/src/hotspot/share/gc/parallel/psClosure.inline.hpp
41149 views
/*1* Copyright (c) 2018, 2020, 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 = *p;93oop new_obj;94if (o->is_forwarded()) {95new_obj = o->forwardee();96} else {97new_obj = _pm->copy_to_survivor_space</*promote_immediately=*/false>(o);98}99RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);100101if (PSScavenge::is_obj_in_young(new_obj)) {102do_cld_barrier();103}104}105}106107void set_scanned_cld(ClassLoaderData* cld) {108assert(_scanned_cld == NULL || cld == NULL, "Should always only handling one cld at a time");109_scanned_cld = cld;110}111112private:113void do_cld_barrier() {114assert(_scanned_cld != NULL, "Should not be called without having a scanned cld");115_scanned_cld->record_modified_oops();116}117};118119// Scavenges the oop in a ClassLoaderData.120class PSScavengeCLDClosure: public CLDClosure {121private:122PSScavengeFromCLDClosure _oop_closure;123public:124PSScavengeCLDClosure(PSPromotionManager* pm) : _oop_closure(pm) { }125void do_cld(ClassLoaderData* cld) {126// If the cld has not been dirtied we know that there's127// no references into the young gen and we can skip it.128129if (cld->has_modified_oops()) {130// Setup the promotion manager to redirty this cld131// if references are left in the young gen.132_oop_closure.set_scanned_cld(cld);133134// Clean the cld since we're going to scavenge all the metadata.135cld->oops_do(&_oop_closure, false, /*clear_modified_oops*/true);136137_oop_closure.set_scanned_cld(NULL);138}139}140};141142#endif // SHARE_GC_PARALLEL_PSCLOSURE_INLINE_HPP143144145