src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp
changeset 50113 caf115bb98ad
child 51959 db0c3952de52
child 56897 840ad2a9015a
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "aot/aotLoader.hpp"
       
    27 #include "classfile/stringTable.hpp"
       
    28 #include "gc/shared/strongRootsScope.hpp"
       
    29 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
       
    30 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp"
       
    31 #include "memory/iterator.hpp"
       
    32 #include "oops/klass.hpp"
       
    33 #include "oops/markOop.hpp"
       
    34 #include "oops/oop.hpp"
       
    35 #include "prims/jvmtiThreadState.hpp"
       
    36 #include "prims/privilegedStack.hpp"
       
    37 #include "runtime/frame.inline.hpp"
       
    38 #include "runtime/mutexLocker.hpp"
       
    39 #include "runtime/threadSMR.inline.hpp"
       
    40 #include "runtime/vframe_hp.hpp"
       
    41 #include "services/management.hpp"
       
    42 #include "utilities/growableArray.hpp"
       
    43 
       
    44 class ReferenceLocateClosure : public OopClosure {
       
    45  protected:
       
    46   RootCallback& _callback;
       
    47   RootCallbackInfo _info;
       
    48   bool _complete;
       
    49 
       
    50   void do_oop_shared(const void* ref);
       
    51 
       
    52  public:
       
    53   ReferenceLocateClosure(RootCallback& callback,
       
    54                          OldObjectRoot::System system,
       
    55                          OldObjectRoot::Type type,
       
    56                          const void* context) : _callback(callback),
       
    57                                                 _info(),
       
    58                                                 _complete(false) {
       
    59     _info._high = NULL;
       
    60     _info._low = NULL;
       
    61     _info._system = system;
       
    62     _info._type = type;
       
    63     _info._context = context;
       
    64   }
       
    65 
       
    66   virtual void do_oop(oop* ref);
       
    67   virtual void do_oop(narrowOop* ref);
       
    68 
       
    69   bool complete() const {
       
    70     return _complete;
       
    71   }
       
    72 };
       
    73 
       
    74 void ReferenceLocateClosure::do_oop_shared(const void* ref) {
       
    75   assert(ref != NULL, "invariant");
       
    76   if (!_complete) {
       
    77     _info._high = ref;
       
    78     _complete = _callback.process(_info);
       
    79   }
       
    80 }
       
    81 
       
    82 void ReferenceLocateClosure::do_oop(oop* ref) {
       
    83   do_oop_shared(ref);
       
    84 }
       
    85 
       
    86 void ReferenceLocateClosure::do_oop(narrowOop* ref) {
       
    87   do_oop_shared(ref);
       
    88 }
       
    89 
       
    90 class ReferenceToRootClosure : public StackObj {
       
    91  private:
       
    92   RootCallback& _callback;
       
    93   RootCallbackInfo _info;
       
    94   bool _complete;
       
    95 
       
    96   bool do_cldg_roots();
       
    97   bool do_object_synchronizer_roots();
       
    98   bool do_universe_roots();
       
    99   bool do_jni_handle_roots();
       
   100   bool do_jvmti_roots();
       
   101   bool do_system_dictionary_roots();
       
   102   bool do_management_roots();
       
   103   bool do_string_table_roots();
       
   104   bool do_aot_loader_roots();
       
   105 
       
   106   bool do_roots();
       
   107 
       
   108  public:
       
   109   ReferenceToRootClosure(RootCallback& callback) : _callback(callback),
       
   110                                                    _info(),
       
   111                                                    _complete(false) {
       
   112     _info._high = NULL;
       
   113     _info._low = NULL;
       
   114     _info._context = NULL;
       
   115     _info._system = OldObjectRoot::_system_undetermined;
       
   116     _info._type = OldObjectRoot::_type_undetermined;
       
   117 
       
   118     assert_locked_or_safepoint(Threads_lock);
       
   119     do_roots();
       
   120   }
       
   121 
       
   122   bool complete() const {
       
   123     return _complete;
       
   124   }
       
   125 };
       
   126 
       
   127 bool ReferenceToRootClosure::do_cldg_roots() {
       
   128   assert(!complete(), "invariant");
       
   129   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);
       
   130   CLDToOopClosure cldt_closure(&rlc);
       
   131   ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
       
   132   return rlc.complete();
       
   133 }
       
   134 
       
   135 bool ReferenceToRootClosure::do_object_synchronizer_roots() {
       
   136   assert(!complete(), "invariant");
       
   137   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_object_synchronizer, OldObjectRoot::_type_undetermined, NULL);
       
   138   ObjectSynchronizer::oops_do(&rlc);
       
   139   return rlc.complete();
       
   140 }
       
   141 
       
   142 bool ReferenceToRootClosure::do_universe_roots() {
       
   143   assert(!complete(), "invariant");
       
   144   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_universe, OldObjectRoot::_type_undetermined, NULL);
       
   145   Universe::oops_do(&rlc);
       
   146   return rlc.complete();
       
   147 }
       
   148 
       
   149 bool ReferenceToRootClosure::do_jni_handle_roots() {
       
   150   assert(!complete(), "invariant");
       
   151   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL);
       
   152   JNIHandles::oops_do(&rlc);
       
   153   return rlc.complete();
       
   154 }
       
   155 
       
   156 bool ReferenceToRootClosure::do_jvmti_roots() {
       
   157   assert(!complete(), "invariant");
       
   158   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL);
       
   159   JvmtiExport::oops_do(&rlc);
       
   160   return rlc.complete();
       
   161 }
       
   162 
       
   163 bool ReferenceToRootClosure::do_system_dictionary_roots() {
       
   164   assert(!complete(), "invariant");
       
   165   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_system_dictionary, OldObjectRoot::_type_undetermined, NULL);
       
   166   SystemDictionary::oops_do(&rlc);
       
   167   return rlc.complete();
       
   168 }
       
   169 
       
   170 bool ReferenceToRootClosure::do_management_roots() {
       
   171   assert(!complete(), "invariant");
       
   172   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL);
       
   173   Management::oops_do(&rlc);
       
   174   return rlc.complete();
       
   175 }
       
   176 
       
   177 bool ReferenceToRootClosure::do_string_table_roots() {
       
   178   assert(!complete(), "invariant");
       
   179   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_string_table, OldObjectRoot::_type_undetermined, NULL);
       
   180   StringTable::oops_do(&rlc);
       
   181   return rlc.complete();
       
   182 }
       
   183 
       
   184 bool ReferenceToRootClosure::do_aot_loader_roots() {
       
   185   assert(!complete(), "invariant");
       
   186   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL);
       
   187   AOTLoader::oops_do(&rcl);
       
   188   return rcl.complete();
       
   189 }
       
   190 
       
   191 bool ReferenceToRootClosure::do_roots() {
       
   192   assert(!complete(), "invariant");
       
   193   assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
       
   194   assert(OldObjectRoot::_type_undetermined == _info._type, "invariant");
       
   195 
       
   196   if (do_cldg_roots()) {
       
   197     _complete = true;
       
   198     return true;
       
   199   }
       
   200 
       
   201   if (do_object_synchronizer_roots()) {
       
   202    _complete = true;
       
   203     return true;
       
   204   }
       
   205 
       
   206   if (do_universe_roots()) {
       
   207    _complete = true;
       
   208     return true;
       
   209   }
       
   210 
       
   211   if (do_jni_handle_roots()) {
       
   212    _complete = true;
       
   213     return true;
       
   214   }
       
   215 
       
   216   if (do_jvmti_roots()) {
       
   217    _complete = true;
       
   218     return true;
       
   219   }
       
   220 
       
   221   if (do_system_dictionary_roots()) {
       
   222    _complete = true;
       
   223     return true;
       
   224   }
       
   225 
       
   226   if (do_management_roots()) {
       
   227    _complete = true;
       
   228     return true;
       
   229   }
       
   230 
       
   231   if (do_string_table_roots()) {
       
   232    _complete = true;
       
   233     return true;
       
   234   }
       
   235 
       
   236   if (do_aot_loader_roots()) {
       
   237    _complete = true;
       
   238     return true;
       
   239   }
       
   240 
       
   241   return false;
       
   242 }
       
   243 
       
   244 class ReferenceToThreadRootClosure : public StackObj {
       
   245  private:
       
   246   RootCallback& _callback;
       
   247   bool _complete;
       
   248 
       
   249   bool do_java_threads_oops(JavaThread* jt);
       
   250   bool do_thread_roots(JavaThread* jt);
       
   251   bool do_thread_stack_fast(JavaThread* jt);
       
   252   bool do_thread_stack_detailed(JavaThread* jt);
       
   253   bool do_thread_jni_handles(JavaThread* jt);
       
   254   bool do_thread_handle_area(JavaThread* jt);
       
   255 
       
   256  public:
       
   257   ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) {
       
   258     assert_locked_or_safepoint(Threads_lock);
       
   259     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
       
   260       if (do_thread_roots(jt)) {
       
   261         return;
       
   262       }
       
   263     }
       
   264   }
       
   265 
       
   266   bool complete() const {
       
   267     return _complete;
       
   268   }
       
   269 };
       
   270 
       
   271 bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) {
       
   272   assert(jt != NULL, "invariant");
       
   273   assert(!complete(), "invariant");
       
   274   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt);
       
   275   jt->handle_area()->oops_do(&rcl);
       
   276   return rcl.complete();
       
   277 }
       
   278 
       
   279 bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) {
       
   280   assert(jt != NULL, "invariant");
       
   281   assert(!complete(), "invariant");
       
   282 
       
   283   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt);
       
   284   jt->active_handles()->oops_do(&rcl);
       
   285   return rcl.complete();
       
   286 }
       
   287 
       
   288 bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) {
       
   289   assert(jt != NULL, "invariant");
       
   290   assert(!complete(), "invariant");
       
   291 
       
   292   if (_callback.entries() == 0) {
       
   293     _complete = true;
       
   294     return true;
       
   295   }
       
   296 
       
   297   RootCallbackInfo info;
       
   298   info._high = NULL;
       
   299   info._low = NULL;
       
   300   info._context = jt;
       
   301   info._system = OldObjectRoot::_threads;
       
   302   info._type = OldObjectRoot::_stack_variable;
       
   303 
       
   304   for (int i = 0; i < _callback.entries(); ++i) {
       
   305     const address adr = (address)_callback.at(i);
       
   306     if (jt->is_in_usable_stack(adr)) {
       
   307       info._high = adr;
       
   308       _complete = _callback.process(info);
       
   309       if (_complete) {
       
   310         return true;
       
   311       }
       
   312     }
       
   313   }
       
   314   assert(!complete(), "invariant");
       
   315   return false;
       
   316 }
       
   317 
       
   318 bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) {
       
   319   assert(jt != NULL, "invariant");
       
   320   assert(!complete(), "invariant");
       
   321 
       
   322   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt);
       
   323 
       
   324   if (jt->has_last_Java_frame()) {
       
   325     PrivilegedElement* const pelem = jt->privileged_stack_top();
       
   326     if (pelem != NULL) {
       
   327       pelem->oops_do(&rcl);
       
   328       if (rcl.complete()) {
       
   329         return true;
       
   330       }
       
   331     }
       
   332 
       
   333     // traverse the registered growable array gc_array
       
   334     // can't do this as it is not reachable from outside
       
   335 
       
   336     // Traverse the monitor chunks
       
   337     MonitorChunk* chunk = jt->monitor_chunks();
       
   338     for (; chunk != NULL; chunk = chunk->next()) {
       
   339       chunk->oops_do(&rcl);
       
   340     }
       
   341 
       
   342     if (rcl.complete()) {
       
   343       return true;
       
   344     }
       
   345 
       
   346     // Traverse the execution stack
       
   347     for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) {
       
   348       fst.current()->oops_do(&rcl, NULL, fst.register_map());
       
   349     }
       
   350 
       
   351   } // last java frame
       
   352 
       
   353   if (rcl.complete()) {
       
   354     return true;
       
   355   }
       
   356 
       
   357   GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = jt->deferred_locals();
       
   358   if (list != NULL) {
       
   359     for (int i = 0; i < list->length(); i++) {
       
   360       list->at(i)->oops_do(&rcl);
       
   361     }
       
   362   }
       
   363 
       
   364   if (rcl.complete()) {
       
   365     return true;
       
   366   }
       
   367 
       
   368   // Traverse instance variables at the end since the GC may be moving things
       
   369   // around using this function
       
   370   /*
       
   371   * // can't reach these oop* from the outside
       
   372   f->do_oop((oop*) &_threadObj);
       
   373   f->do_oop((oop*) &_vm_result);
       
   374   f->do_oop((oop*) &_exception_oop);
       
   375   f->do_oop((oop*) &_pending_async_exception);
       
   376   */
       
   377 
       
   378   JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state();
       
   379   if (jvmti_thread_state != NULL) {
       
   380     jvmti_thread_state->oops_do(&rcl);
       
   381   }
       
   382 
       
   383   return rcl.complete();
       
   384 }
       
   385 
       
   386 bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) {
       
   387   assert(jt != NULL, "invariant");
       
   388   assert(!complete(), "invariant");
       
   389 
       
   390   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt);
       
   391   jt->oops_do(&rcl, NULL);
       
   392   return rcl.complete();
       
   393 }
       
   394 
       
   395 bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) {
       
   396   assert(jt != NULL, "invariant");
       
   397 
       
   398   if (do_thread_stack_fast(jt)) {
       
   399     _complete = true;
       
   400     return true;
       
   401   }
       
   402 
       
   403   if (do_thread_jni_handles(jt)) {
       
   404     _complete = true;
       
   405     return true;
       
   406   }
       
   407 
       
   408   if (do_thread_handle_area(jt)) {
       
   409     _complete = true;
       
   410     return true;
       
   411   }
       
   412 
       
   413   if (do_thread_stack_detailed(jt)) {
       
   414     _complete = true;
       
   415     return true;
       
   416   }
       
   417 
       
   418   return false;
       
   419 }
       
   420 
       
   421 class RootResolverMarkScope : public MarkScope {
       
   422 };
       
   423 
       
   424 void RootResolver::resolve(RootCallback& callback) {
       
   425 
       
   426   // Need to clear cld claim bit before starting
       
   427   ClassLoaderDataGraph::clear_claimed_marks();
       
   428   RootResolverMarkScope mark_scope;
       
   429 
       
   430   // thread local roots
       
   431   ReferenceToThreadRootClosure rtrc(callback);
       
   432   if (rtrc.complete()) {
       
   433     return;
       
   434   }
       
   435   // system global roots
       
   436   ReferenceToRootClosure rrc(callback);
       
   437 }