Path: blob/master/src/hotspot/share/memory/metaspaceClosure.cpp
40949 views
/*1* Copyright (c) 2017, 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#include "precompiled.hpp"25#include "memory/metaspaceClosure.hpp"2627// Update the reference to point to new_loc.28void MetaspaceClosure::Ref::update(address new_loc) const {29log_trace(cds)("Ref: [" PTR_FORMAT "] -> " PTR_FORMAT " => " PTR_FORMAT,30p2i(mpp()), p2i(obj()), p2i(new_loc));31uintx p = (uintx)new_loc;32p |= flag_bits(); // Make sure the flag bits are copied to the new pointer.33*(address*)mpp() = (address)p;34}3536void MetaspaceClosure::push_impl(MetaspaceClosure::Ref* ref) {37if (_nest_level < MAX_NEST_LEVEL) {38do_push(ref);39if (!ref->keep_after_pushing()) {40delete ref;41}42} else {43do_pending_ref(ref);44ref->set_next(_pending_refs);45_pending_refs = ref;46}47}4849void MetaspaceClosure::do_push(MetaspaceClosure::Ref* ref) {50if (ref->not_null()) {51bool read_only;52Writability w = ref->writability();53switch (w) {54case _writable:55read_only = false;56break;57case _not_writable:58read_only = true;59break;60default:61assert(w == _default, "must be");62read_only = ref->is_read_only_by_default();63}64if (_nest_level == 0) {65assert(_enclosing_ref == NULL, "must be");66}67_nest_level ++;68if (do_ref(ref, read_only)) { // true means we want to iterate the embedded pointer in <ref>69Ref* saved = _enclosing_ref;70_enclosing_ref = ref;71ref->metaspace_pointers_do(this);72_enclosing_ref = saved;73}74_nest_level --;75}76}7778void MetaspaceClosure::finish() {79assert(_nest_level == 0, "must be");80while (_pending_refs != NULL) {81Ref* ref = _pending_refs;82_pending_refs = _pending_refs->next();83do_push(ref);84if (!ref->keep_after_pushing()) {85delete ref;86}87}88}8990MetaspaceClosure::~MetaspaceClosure() {91assert(_pending_refs == NULL,92"you must explicitly call MetaspaceClosure::finish() to process all refs!");93}9495bool UniqueMetaspaceClosure::do_ref(MetaspaceClosure::Ref* ref, bool read_only) {96bool created;97_has_been_visited.add_if_absent(ref->obj(), read_only, &created);98if (!created) {99return false; // Already visited: no need to iterate embedded pointers.100} else {101if (_has_been_visited.maybe_grow(MAX_TABLE_SIZE)) {102log_info(cds, hashtables)("Expanded _has_been_visited table to %d", _has_been_visited.table_size());103}104return do_unique_ref(ref, read_only);105}106}107108109