Path: blob/master/src/hotspot/share/oops/instanceRefKlass.inline.hpp
40951 views
/*1* Copyright (c) 2015, 2019, 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_OOPS_INSTANCEREFKLASS_INLINE_HPP25#define SHARE_OOPS_INSTANCEREFKLASS_INLINE_HPP2627#include "oops/instanceRefKlass.hpp"2829#include "classfile/javaClasses.inline.hpp"30#include "gc/shared/referenceProcessor.hpp"31#include "logging/log.hpp"32#include "oops/access.inline.hpp"33#include "oops/instanceKlass.inline.hpp"34#include "oops/oop.inline.hpp"35#include "utilities/debug.hpp"36#include "utilities/globalDefinitions.hpp"37#include "utilities/macros.hpp"3839template <typename T, class OopClosureType, class Contains>40void InstanceRefKlass::do_referent(oop obj, OopClosureType* closure, Contains& contains) {41T* referent_addr = (T*)java_lang_ref_Reference::referent_addr_raw(obj);42if (contains(referent_addr)) {43Devirtualizer::do_oop(closure, referent_addr);44}45}4647template <typename T, class OopClosureType, class Contains>48void InstanceRefKlass::do_discovered(oop obj, OopClosureType* closure, Contains& contains) {49T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr_raw(obj);50if (contains(discovered_addr)) {51Devirtualizer::do_oop(closure, discovered_addr);52}53}5455static inline oop load_referent(oop obj, ReferenceType type) {56if (type == REF_PHANTOM) {57return HeapAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(java_lang_ref_Reference::referent_addr_raw(obj));58} else {59return HeapAccess<ON_WEAK_OOP_REF | AS_NO_KEEPALIVE>::oop_load(java_lang_ref_Reference::referent_addr_raw(obj));60}61}6263template <typename T, class OopClosureType>64bool InstanceRefKlass::try_discover(oop obj, ReferenceType type, OopClosureType* closure) {65ReferenceDiscoverer* rd = closure->ref_discoverer();66if (rd != NULL) {67oop referent = load_referent(obj, type);68if (referent != NULL) {69if (!referent->is_gc_marked()) {70// Only try to discover if not yet marked.71return rd->discover_reference(obj, type);72}73}74}75return false;76}7778template <typename T, class OopClosureType, class Contains>79void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {80// Try to discover reference and return if it succeeds.81if (try_discover<T>(obj, type, closure)) {82return;83}8485// Treat referent and discovered as normal oops.86do_referent<T>(obj, closure, contains);87do_discovered<T>(obj, closure, contains);88}8990template <typename T, class OopClosureType, class Contains>91void InstanceRefKlass::oop_oop_iterate_discovered_and_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) {92// Explicitly apply closure to the discovered field.93do_discovered<T>(obj, closure, contains);94// Then do normal reference processing with discovery.95oop_oop_iterate_discovery<T>(obj, type, closure, contains);96}9798template <typename T, class OopClosureType, class Contains>99void InstanceRefKlass::oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains) {100assert(closure->ref_discoverer() == NULL, "ReferenceDiscoverer should not be set");101do_referent<T>(obj, closure, contains);102do_discovered<T>(obj, closure, contains);103}104105template <typename T, class OopClosureType, class Contains>106void InstanceRefKlass::oop_oop_iterate_fields_except_referent(oop obj, OopClosureType* closure, Contains& contains) {107assert(closure->ref_discoverer() == NULL, "ReferenceDiscoverer should not be set");108do_discovered<T>(obj, closure, contains);109}110111template <typename T, class OopClosureType, class Contains>112void InstanceRefKlass::oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure, Contains& contains) {113switch (closure->reference_iteration_mode()) {114case OopIterateClosure::DO_DISCOVERY:115trace_reference_gc<T>("do_discovery", obj);116oop_oop_iterate_discovery<T>(obj, reference_type(), closure, contains);117break;118case OopIterateClosure::DO_DISCOVERED_AND_DISCOVERY:119trace_reference_gc<T>("do_discovered_and_discovery", obj);120oop_oop_iterate_discovered_and_discovery<T>(obj, reference_type(), closure, contains);121break;122case OopIterateClosure::DO_FIELDS:123trace_reference_gc<T>("do_fields", obj);124oop_oop_iterate_fields<T>(obj, closure, contains);125break;126case OopIterateClosure::DO_FIELDS_EXCEPT_REFERENT:127trace_reference_gc<T>("do_fields_except_referent", obj);128oop_oop_iterate_fields_except_referent<T>(obj, closure, contains);129break;130default:131ShouldNotReachHere();132}133}134135class AlwaysContains {136public:137template <typename T> bool operator()(T* p) const { return true; }138};139140template <typename T, class OopClosureType>141void InstanceRefKlass::oop_oop_iterate_ref_processing(oop obj, OopClosureType* closure) {142AlwaysContains always_contains;143oop_oop_iterate_ref_processing<T>(obj, closure, always_contains);144}145146class MrContains {147const MemRegion _mr;148public:149MrContains(MemRegion mr) : _mr(mr) {}150template <typename T> bool operator()(T* p) const { return _mr.contains(p); }151};152153template <typename T, class OopClosureType>154void InstanceRefKlass::oop_oop_iterate_ref_processing_bounded(oop obj, OopClosureType* closure, MemRegion mr) {155const MrContains contains(mr);156oop_oop_iterate_ref_processing<T>(obj, closure, contains);157}158159template <typename T, class OopClosureType>160void InstanceRefKlass::oop_oop_iterate(oop obj, OopClosureType* closure) {161InstanceKlass::oop_oop_iterate<T>(obj, closure);162163oop_oop_iterate_ref_processing<T>(obj, closure);164}165166template <typename T, class OopClosureType>167void InstanceRefKlass::oop_oop_iterate_reverse(oop obj, OopClosureType* closure) {168InstanceKlass::oop_oop_iterate_reverse<T>(obj, closure);169170oop_oop_iterate_ref_processing<T>(obj, closure);171}172173template <typename T, class OopClosureType>174void InstanceRefKlass::oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr) {175InstanceKlass::oop_oop_iterate_bounded<T>(obj, closure, mr);176177oop_oop_iterate_ref_processing_bounded<T>(obj, closure, mr);178}179180#ifdef ASSERT181template <typename T>182void InstanceRefKlass::trace_reference_gc(const char *s, oop obj) {183T* referent_addr = (T*) java_lang_ref_Reference::referent_addr_raw(obj);184T* discovered_addr = (T*) java_lang_ref_Reference::discovered_addr_raw(obj);185186log_develop_trace(gc, ref)("InstanceRefKlass %s for obj " PTR_FORMAT, s, p2i(obj));187if (java_lang_ref_Reference::is_phantom(obj)) {188log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,189p2i(referent_addr), p2i((oop)HeapAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(referent_addr)));190} else {191log_develop_trace(gc, ref)(" referent_addr/* " PTR_FORMAT " / " PTR_FORMAT,192p2i(referent_addr), p2i((oop)HeapAccess<ON_WEAK_OOP_REF | AS_NO_KEEPALIVE>::oop_load(referent_addr)));193}194log_develop_trace(gc, ref)(" discovered_addr/* " PTR_FORMAT " / " PTR_FORMAT,195p2i(discovered_addr), p2i((oop)HeapAccess<AS_NO_KEEPALIVE>::oop_load(discovered_addr)));196}197#endif198199#endif // SHARE_OOPS_INSTANCEREFKLASS_INLINE_HPP200201202