Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/jfr/leakprofiler/checkpoint/rootResolver.cpp
48074 views
/*1* Copyright (c) 2014, 2018, 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 "classfile/stringTable.hpp"26//#include "gc_interface/strongRootsScope.hpp"27#include "jfr/leakprofiler/utilities/unifiedOop.hpp"28#include "jfr/leakprofiler/checkpoint/rootResolver.hpp"29#include "memory/iterator.hpp"30#include "oops/klass.hpp"31#include "oops/markOop.hpp"32#include "oops/oop.hpp"33#include "prims/jvmtiThreadState.hpp"34#include "prims/privilegedStack.hpp"35#include "runtime/frame.inline.hpp"36#include "runtime/mutexLocker.hpp"37#include "runtime/vframe_hp.hpp"38#include "services/management.hpp"39#include "utilities/growableArray.hpp"4041class ReferenceLocateClosure : public OopClosure {42protected:43RootCallback& _callback;44RootCallbackInfo _info;45bool _complete;4647void do_oop_shared(const void* ref);4849public:50ReferenceLocateClosure(RootCallback& callback,51OldObjectRoot::System system,52OldObjectRoot::Type type,53const void* context) : _callback(callback),54_info(),55_complete(false) {56_info._high = NULL;57_info._low = NULL;58_info._system = system;59_info._type = type;60_info._context = context;61}6263virtual void do_oop(oop* ref);64virtual void do_oop(narrowOop* ref);6566bool complete() const {67return _complete;68}69};7071void ReferenceLocateClosure::do_oop_shared(const void* ref) {72assert(ref != NULL, "invariant");73if (!_complete) {74_info._high = ref;75_complete = _callback.process(_info);76}77}7879void ReferenceLocateClosure::do_oop(oop* ref) {80do_oop_shared(ref);81}8283void ReferenceLocateClosure::do_oop(narrowOop* ref) {84do_oop_shared(ref);85}8687class ReferenceToRootClosure : public StackObj {88private:89RootCallback& _callback;90RootCallbackInfo _info;91bool _complete;9293bool do_cldg_roots();94bool do_object_synchronizer_roots();95bool do_universe_roots();96bool do_jni_handle_roots();97bool do_jvmti_roots();98bool do_system_dictionary_roots();99bool do_management_roots();100bool do_string_table_roots();101// bool do_aot_loader_roots();102103bool do_roots();104105public:106ReferenceToRootClosure(RootCallback& callback) : _callback(callback),107_info(),108_complete(false) {109_info._high = NULL;110_info._low = NULL;111_info._context = NULL;112_info._system = OldObjectRoot::_system_undetermined;113_info._type = OldObjectRoot::_type_undetermined;114115assert_locked_or_safepoint(Threads_lock);116do_roots();117}118119bool complete() const {120return _complete;121}122};123124bool ReferenceToRootClosure::do_cldg_roots() {125assert(!complete(), "invariant");126ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);127CLDToOopClosure cldt_closure(&rlc);128ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);129return rlc.complete();130}131132bool ReferenceToRootClosure::do_object_synchronizer_roots() {133assert(!complete(), "invariant");134ReferenceLocateClosure rlc(_callback, OldObjectRoot::_object_synchronizer, OldObjectRoot::_type_undetermined, NULL);135ObjectSynchronizer::oops_do(&rlc);136return rlc.complete();137}138139bool ReferenceToRootClosure::do_universe_roots() {140assert(!complete(), "invariant");141ReferenceLocateClosure rlc(_callback, OldObjectRoot::_universe, OldObjectRoot::_type_undetermined, NULL);142Universe::oops_do(&rlc);143return rlc.complete();144}145146bool ReferenceToRootClosure::do_jni_handle_roots() {147assert(!complete(), "invariant");148ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL);149JNIHandles::oops_do(&rlc);150return rlc.complete();151}152153bool ReferenceToRootClosure::do_jvmti_roots() {154assert(!complete(), "invariant");155ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL);156JvmtiExport::oops_do(&rlc);157return rlc.complete();158}159160bool ReferenceToRootClosure::do_system_dictionary_roots() {161assert(!complete(), "invariant");162ReferenceLocateClosure rlc(_callback, OldObjectRoot::_system_dictionary, OldObjectRoot::_type_undetermined, NULL);163SystemDictionary::oops_do(&rlc);164return rlc.complete();165}166167bool ReferenceToRootClosure::do_management_roots() {168assert(!complete(), "invariant");169ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL);170Management::oops_do(&rlc);171return rlc.complete();172}173174bool ReferenceToRootClosure::do_string_table_roots() {175assert(!complete(), "invariant");176ReferenceLocateClosure rlc(_callback, OldObjectRoot::_string_table, OldObjectRoot::_type_undetermined, NULL);177StringTable::oops_do(&rlc);178return rlc.complete();179}180181//bool ReferenceToRootClosure::do_aot_loader_roots() {182// assert(!complete(), "invariant");183// ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL);184// AOTLoader::oops_do(&rcl);185// return rcl.complete();186//}187188bool ReferenceToRootClosure::do_roots() {189assert(!complete(), "invariant");190assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");191assert(OldObjectRoot::_type_undetermined == _info._type, "invariant");192193if (do_cldg_roots()) {194_complete = true;195return true;196}197198if (do_object_synchronizer_roots()) {199_complete = true;200return true;201}202203if (do_universe_roots()) {204_complete = true;205return true;206}207208if (do_jni_handle_roots()) {209_complete = true;210return true;211}212213if (do_jvmti_roots()) {214_complete = true;215return true;216}217218if (do_system_dictionary_roots()) {219_complete = true;220return true;221}222223if (do_management_roots()) {224_complete = true;225return true;226}227228if (do_string_table_roots()) {229_complete = true;230return true;231}232233// if (do_aot_loader_roots()) {234// _complete = true;235// return true;236// }237238return false;239}240241class ReferenceToThreadRootClosure : public StackObj {242private:243RootCallback& _callback;244bool _complete;245246bool do_java_threads_oops(JavaThread* jt);247bool do_thread_roots(JavaThread* jt);248bool do_thread_stack_fast(JavaThread* jt);249bool do_thread_stack_detailed(JavaThread* jt);250bool do_thread_jni_handles(JavaThread* jt);251bool do_thread_handle_area(JavaThread* jt);252253public:254ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) {255assert_locked_or_safepoint(Threads_lock);256for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {257if (do_thread_roots(thread)) {258return;259}260}261}262263bool complete() const {264return _complete;265}266};267268bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) {269assert(jt != NULL, "invariant");270assert(!complete(), "invariant");271ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt);272jt->handle_area()->oops_do(&rcl);273return rcl.complete();274}275276bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) {277assert(jt != NULL, "invariant");278assert(!complete(), "invariant");279280ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt);281jt->active_handles()->oops_do(&rcl);282return rcl.complete();283}284285bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) {286assert(jt != NULL, "invariant");287assert(!complete(), "invariant");288289if (_callback.entries() == 0) {290_complete = true;291return true;292}293294RootCallbackInfo info;295info._high = NULL;296info._low = NULL;297info._context = jt;298info._system = OldObjectRoot::_threads;299info._type = OldObjectRoot::_stack_variable;300301for (int i = 0; i < _callback.entries(); ++i) {302const address adr = (address)_callback.at(i);303if (jt->is_in_usable_stack(adr)) {304info._high = adr;305_complete = _callback.process(info);306if (_complete) {307return true;308}309}310}311assert(!complete(), "invariant");312return false;313}314315bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) {316assert(jt != NULL, "invariant");317assert(!complete(), "invariant");318319ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt);320321if (jt->has_last_Java_frame()) {322PrivilegedElement* const pelem = jt->privileged_stack_top();323if (pelem != NULL) {324pelem->oops_do(&rcl);325if (rcl.complete()) {326return true;327}328}329330// traverse the registered growable array gc_array331// can't do this as it is not reachable from outside332333// Traverse the monitor chunks334MonitorChunk* chunk = jt->monitor_chunks();335for (; chunk != NULL; chunk = chunk->next()) {336chunk->oops_do(&rcl);337}338339if (rcl.complete()) {340return true;341}342343// Traverse the execution stack344for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) {345// XXX set CLDClosure to NULL346fst.current()->oops_do(&rcl, NULL, NULL, fst.register_map());347}348349} // last java frame350351if (rcl.complete()) {352return true;353}354355GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = jt->deferred_locals();356if (list != NULL) {357for (int i = 0; i < list->length(); i++) {358list->at(i)->oops_do(&rcl);359}360}361362if (rcl.complete()) {363return true;364}365366// Traverse instance variables at the end since the GC may be moving things367// around using this function368/*369* // can't reach these oop* from the outside370f->do_oop((oop*) &_threadObj);371f->do_oop((oop*) &_vm_result);372f->do_oop((oop*) &_exception_oop);373f->do_oop((oop*) &_pending_async_exception);374*/375376JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state();377if (jvmti_thread_state != NULL) {378jvmti_thread_state->oops_do(&rcl);379}380381return rcl.complete();382}383384bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) {385assert(jt != NULL, "invariant");386assert(!complete(), "invariant");387388ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt);389jt->oops_do(&rcl, NULL, NULL);390return rcl.complete();391}392393bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) {394assert(jt != NULL, "invariant");395396if (do_thread_stack_fast(jt)) {397_complete = true;398return true;399}400401if (do_thread_jni_handles(jt)) {402_complete = true;403return true;404}405406if (do_thread_handle_area(jt)) {407_complete = true;408return true;409}410411if (do_thread_stack_detailed(jt)) {412_complete = true;413return true;414}415416return false;417}418419class RootResolverMarkScope : public MarkingCodeBlobClosure::MarkScope {420};421422void RootResolver::resolve(RootCallback& callback) {423424// Need to clear cld claim bit before starting425ClassLoaderDataGraph::clear_claimed_marks();426RootResolverMarkScope mark_scope;427428// thread local roots429ReferenceToThreadRootClosure rtrc(callback);430if (rtrc.complete()) {431return;432}433// system global roots434ReferenceToRootClosure rrc(callback);435}436437438