diff a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp --- a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp @@ -25,22 +25,21 @@ #include "precompiled.hpp" #include "aot/aotLoader.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/stringTable.hpp" #include "gc/shared/oopStorage.inline.hpp" -#include "gc/shared/oopStorageSet.hpp" +#include "gc/shared/oopStorageSet.inline.hpp" #include "gc/shared/strongRootsScope.hpp" #include "jfr/leakprofiler/chains/bfsClosure.hpp" #include "jfr/leakprofiler/chains/dfsClosure.hpp" #include "jfr/leakprofiler/chains/edgeQueue.hpp" #include "jfr/leakprofiler/chains/rootSetClosure.hpp" #include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp" #include "memory/universe.hpp" #include "oops/access.inline.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" -#include "runtime/jniHandles.inline.hpp" #include "runtime/synchronizer.hpp" #include "runtime/thread.hpp" #include "services/management.hpp" #include "utilities/align.hpp" @@ -74,13 +73,12 @@ ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure); // We don't follow code blob oops, because they have misaligned oops. Threads::oops_do(this, NULL); ObjectSynchronizer::oops_do(this); Universe::oops_do(this); - JNIHandles::oops_do(this); JvmtiExport::oops_do(this); - OopStorageSet::vm_global()->oops_do(this); + OopStorageSet::strong_oops_do(this); Management::oops_do(this); AOTLoader::oops_do(this); } template class RootSetClosure; diff a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp @@ -96,13 +96,12 @@ bool _complete; bool do_cldg_roots(); bool do_object_synchronizer_roots(); bool do_universe_roots(); - bool do_jni_handle_roots(); + bool do_oop_storage_roots(); bool do_jvmti_roots(); - bool do_vm_global_roots(); bool do_management_roots(); bool do_string_table_roots(); bool do_aot_loader_roots(); bool do_roots(); @@ -146,31 +145,35 @@ ReferenceLocateClosure rlc(_callback, OldObjectRoot::_universe, OldObjectRoot::_type_undetermined, NULL); Universe::oops_do(&rlc); return rlc.complete(); } -bool ReferenceToRootClosure::do_jni_handle_roots() { - assert(!complete(), "invariant"); - ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL); - JNIHandles::oops_do(&rlc); - return rlc.complete(); +bool ReferenceToRootClosure::do_oop_storage_roots() { + int i = 0; + for (OopStorageSet::Iterator it = OopStorageSet::strong_iterator(); !it.is_end(); ++it, ++i) { + assert(!complete(), "invariant"); + OopStorage* oop_storage = *it; + OldObjectRoot::Type type = oop_storage == OopStorageSet::jni_global() ? + OldObjectRoot::_global_jni_handle : + OldObjectRoot::_global_oop_handle; + OldObjectRoot::System system = OldObjectRoot::System(OldObjectRoot::_strong_oop_storage_set_first + i); + ReferenceLocateClosure rlc(_callback, system, type, NULL); + oop_storage->oops_do(&rlc); + if (rlc.complete()) { + return true; + } + } + return false; } bool ReferenceToRootClosure::do_jvmti_roots() { assert(!complete(), "invariant"); ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL); JvmtiExport::oops_do(&rlc); return rlc.complete(); } -bool ReferenceToRootClosure::do_vm_global_roots() { - assert(!complete(), "invariant"); - ReferenceLocateClosure rlc(_callback, OldObjectRoot::_vm_global, OldObjectRoot::_type_undetermined, NULL); - OopStorageSet::vm_global()->oops_do(&rlc); - return rlc.complete(); -} - bool ReferenceToRootClosure::do_management_roots() { assert(!complete(), "invariant"); ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL); Management::oops_do(&rlc); return rlc.complete(); @@ -201,25 +204,20 @@ if (do_universe_roots()) { _complete = true; return true; } - if (do_jni_handle_roots()) { + if (do_oop_storage_roots()) { _complete = true; return true; } if (do_jvmti_roots()) { _complete = true; return true; } - if (do_vm_global_roots()) { - _complete = true; - return true; - } - if (do_management_roots()) { _complete = true; return true; } diff a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp --- /dev/null +++ b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/shared/oopStorage.hpp" +#include "gc/shared/oopStorageSet.hpp" +#include "jfr/leakprofiler/utilities/rootType.hpp" +#include "utilities/debug.hpp" + +OopStorage* OldObjectRoot::system_oop_storage(System system) { + int val = int(system); + if (val >= _strong_oop_storage_set_first && val <= _strong_oop_storage_set_last) { + int index = val - _strong_oop_storage_set_first; + int i = 0; + for (OopStorageSet::Iterator it = OopStorageSet::strong_iterator(); !it.is_end(); ++it, ++i) { + if (i == index) { + return *it; + } + } + } + return NULL; +} + +const char* OldObjectRoot::system_description(System system) { + OopStorage* oop_storage = system_oop_storage(system); + if (oop_storage != NULL) { + return oop_storage->name(); + } + switch (system) { + case _system_undetermined: + return ""; + case _universe: + return "Universe"; + case _threads: + return "Threads"; + case _object_synchronizer: + return "Object Monitor"; + case _class_loader_data: + return "Class Loader Data"; + case _management: + return "Management"; + case _jvmti: + return "JVMTI"; + case _code_cache: + return "Code Cache"; + case _aot: + return "AOT"; +#if INCLUDE_JVMCI + case _jvmci: + return "JVMCI"; +#endif + default: + ShouldNotReachHere(); + } + return NULL; +} + +const char* OldObjectRoot::type_description(Type type) { + switch (type) { + case _type_undetermined: + return ""; + case _stack_variable: + return "Stack Variable"; + case _local_jni_handle: + return "Local JNI Handle"; + case _global_jni_handle: + return "Global JNI Handle"; + case _global_oop_handle: + return "Global Object Handle"; + case _handle_area: + return "Handle Area"; + default: + ShouldNotReachHere(); + } + return NULL; +} diff a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp --- a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp @@ -23,22 +23,22 @@ */ #ifndef SHARE_JFR_LEAKPROFILER_UTILITIES_ROOTTYPE_HPP #define SHARE_JFR_LEAKPROFILER_UTILITIES_ROOTTYPE_HPP +#include "gc/shared/oopStorageSet.hpp" #include "memory/allocation.hpp" -#include "utilities/debug.hpp" class OldObjectRoot : public AllStatic { public: enum System { _system_undetermined, _universe, - _global_jni_handles, _threads, + _strong_oop_storage_set_first, + _strong_oop_storage_set_last = _strong_oop_storage_set_first + OopStorageSet::strong_count - 1, _object_synchronizer, - _vm_global, _class_loader_data, _management, _jvmti, _code_cache, _aot, @@ -49,63 +49,16 @@ enum Type { _type_undetermined, _stack_variable, _local_jni_handle, _global_jni_handle, + _global_oop_handle, _handle_area, _number_of_types }; - static const char* system_description(System system) { - switch (system) { - case _system_undetermined: - return ""; - case _universe: - return "Universe"; - case _global_jni_handles: - return "Global JNI Handles"; - case _threads: - return "Threads"; - case _object_synchronizer: - return "Object Monitor"; - case _vm_global: - return "VM Global"; - case _class_loader_data: - return "Class Loader Data"; - case _management: - return "Management"; - case _jvmti: - return "JVMTI"; - case _code_cache: - return "Code Cache"; - case _aot: - return "AOT"; -#if INCLUDE_JVMCI - case _jvmci: - return "JVMCI"; -#endif - default: - ShouldNotReachHere(); - } - return NULL; - } - - static const char* type_description(Type type) { - switch (type) { - case _type_undetermined: - return ""; - case _stack_variable: - return "Stack Variable"; - case _local_jni_handle: - return "Local JNI Handle"; - case _global_jni_handle: - return "Global JNI Handle"; - case _handle_area: - return "Handle Area"; - default: - ShouldNotReachHere(); - } - return NULL; - } + static OopStorage* system_oop_storage(System system); + static const char* system_description(System system); + static const char* type_description(Type type); }; #endif // SHARE_JFR_LEAKPROFILER_UTILITIES_ROOTTYPE_HPP