1 /*
   2  * Copyright (c) 2014, 2020, 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/classLoaderDataGraph.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "gc/shared/oopStorage.inline.hpp"
  30 #include "gc/shared/oopStorageSet.hpp"
  31 #include "gc/shared/strongRootsScope.hpp"
  32 #include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
  33 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp"
  34 #include "jfr/utilities/jfrThreadIterator.hpp"
  35 #include "memory/iterator.hpp"
  36 #include "oops/klass.hpp"
  37 #include "oops/oop.hpp"
  38 #include "prims/jvmtiThreadState.hpp"
  39 #include "runtime/frame.inline.hpp"
  40 #include "runtime/mutexLocker.hpp"
  41 #include "runtime/vframe_hp.hpp"
  42 #include "services/management.hpp"
  43 #include "utilities/growableArray.hpp"
  44 
  45 class ReferenceLocateClosure : public OopClosure {
  46  protected:
  47   RootCallback& _callback;
  48   RootCallbackInfo _info;
  49   bool _complete;
  50 
  51   void do_oop_shared(UnifiedOopRef ref);
  52 
  53  public:
  54   ReferenceLocateClosure(RootCallback& callback,
  55                          OldObjectRoot::System system,
  56                          OldObjectRoot::Type type,
  57                          const void* context) : _callback(callback),
  58                                                 _info(),
  59                                                 _complete(false) {
  60     _info._high = NULL;
  61     _info._low = NULL;
  62     _info._system = system;
  63     _info._type = type;
  64     _info._context = context;
  65   }
  66 
  67   virtual void do_oop(oop* ref);
  68   virtual void do_oop(narrowOop* ref);
  69 
  70   bool complete() const {
  71     return _complete;
  72   }
  73 };
  74 
  75 void ReferenceLocateClosure::do_oop_shared(UnifiedOopRef ref) {
  76   assert(!ref.is_null(), "invariant");
  77   if (!_complete) {
  78     _info._high = ref.addr<address>();
  79     _complete = _callback.process(_info);
  80   }
  81 }
  82 
  83 void ReferenceLocateClosure::do_oop(oop* ref) {
  84   do_oop_shared(UnifiedOopRef::encode_in_native(ref));
  85 }
  86 
  87 void ReferenceLocateClosure::do_oop(narrowOop* ref) {
  88   do_oop_shared(UnifiedOopRef::encode_in_native(ref));
  89 }
  90 
  91 class ReferenceToRootClosure : public StackObj {
  92  private:
  93   RootCallback& _callback;
  94   RootCallbackInfo _info;
  95   bool _complete;
  96 
  97   bool do_cldg_roots();
  98   bool do_object_synchronizer_roots();
  99   bool do_oop_storage_roots();
 100   bool do_string_table_roots();
 101   bool do_aot_loader_roots();
 102 
 103   bool do_roots();
 104 
 105  public:
 106   ReferenceToRootClosure(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;
 114 
 115     assert_locked_or_safepoint(Threads_lock);
 116     do_roots();
 117   }
 118 
 119   bool complete() const {
 120     return _complete;
 121   }
 122 };
 123 
 124 bool ReferenceToRootClosure::do_cldg_roots() {
 125   assert(!complete(), "invariant");
 126   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);
 127   CLDToOopClosure cldt_closure(&rlc, ClassLoaderData::_claim_none);
 128   ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
 129   return rlc.complete();
 130 }
 131 
 132 bool ReferenceToRootClosure::do_object_synchronizer_roots() {
 133   assert(!complete(), "invariant");
 134   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_object_synchronizer, OldObjectRoot::_type_undetermined, NULL);
 135   ObjectSynchronizer::oops_do(&rlc);
 136   return rlc.complete();
 137 }
 138 
 139 bool ReferenceToRootClosure::do_oop_storage_roots() {
 140   int i = 0;
 141   for (OopStorageSet::Iterator it = OopStorageSet::strong_iterator(); !it.is_end(); ++it, ++i) {
 142     assert(!complete(), "invariant");
 143     OopStorage* oop_storage = *it;
 144     OldObjectRoot::Type type = JNIHandles::is_global_storage(oop_storage) ?
 145                                OldObjectRoot::_global_jni_handle :
 146                                OldObjectRoot::_global_oop_handle;
 147     OldObjectRoot::System system = OldObjectRoot::System(OldObjectRoot::_strong_oop_storage_set_first + i);
 148     ReferenceLocateClosure rlc(_callback, system, type, NULL);
 149     oop_storage->oops_do(&rlc);
 150     if (rlc.complete()) {
 151       return true;
 152     }
 153   }
 154   return false;
 155 }
 156 
 157 bool ReferenceToRootClosure::do_aot_loader_roots() {
 158   assert(!complete(), "invariant");
 159   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL);
 160   AOTLoader::oops_do(&rcl);
 161   return rcl.complete();
 162 }
 163 
 164 bool ReferenceToRootClosure::do_roots() {
 165   assert(!complete(), "invariant");
 166   assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
 167   assert(OldObjectRoot::_type_undetermined == _info._type, "invariant");
 168 
 169   if (do_cldg_roots()) {
 170     _complete = true;
 171     return true;
 172   }
 173 
 174   if (do_object_synchronizer_roots()) {
 175    _complete = true;
 176     return true;
 177   }
 178 
 179   if (do_oop_storage_roots()) {
 180    _complete = true;
 181     return true;
 182   }
 183 
 184   if (do_aot_loader_roots()) {
 185    _complete = true;
 186     return true;
 187   }
 188 
 189   return false;
 190 }
 191 
 192 class ReferenceToThreadRootClosure : public StackObj {
 193  private:
 194   RootCallback& _callback;
 195   bool _complete;
 196 
 197   bool do_java_threads_oops(JavaThread* jt);
 198   bool do_thread_roots(JavaThread* jt);
 199   bool do_thread_stack_fast(JavaThread* jt);
 200   bool do_thread_stack_detailed(JavaThread* jt);
 201   bool do_thread_jni_handles(JavaThread* jt);
 202   bool do_thread_handle_area(JavaThread* jt);
 203 
 204  public:
 205   ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) {
 206     assert_locked_or_safepoint(Threads_lock);
 207     JfrJavaThreadIterator iter;
 208     while (iter.has_next()) {
 209       if (do_thread_roots(iter.next())) {
 210         return;
 211       }
 212     }
 213   }
 214 
 215   bool complete() const {
 216     return _complete;
 217   }
 218 };
 219 
 220 bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) {
 221   assert(jt != NULL, "invariant");
 222   assert(!complete(), "invariant");
 223   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt);
 224   jt->handle_area()->oops_do(&rcl);
 225   return rcl.complete();
 226 }
 227 
 228 bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) {
 229   assert(jt != NULL, "invariant");
 230   assert(!complete(), "invariant");
 231 
 232   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt);
 233   jt->active_handles()->oops_do(&rcl);
 234   return rcl.complete();
 235 }
 236 
 237 bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) {
 238   assert(jt != NULL, "invariant");
 239   assert(!complete(), "invariant");
 240 
 241   if (_callback.entries() == 0) {
 242     _complete = true;
 243     return true;
 244   }
 245 
 246   RootCallbackInfo info;
 247   info._high = NULL;
 248   info._low = NULL;
 249   info._context = jt;
 250   info._system = OldObjectRoot::_threads;
 251   info._type = OldObjectRoot::_stack_variable;
 252 
 253   for (int i = 0; i < _callback.entries(); ++i) {
 254     const address adr = _callback.at(i).addr<address>();
 255     if (jt->is_in_usable_stack(adr)) {
 256       info._high = adr;
 257       _complete = _callback.process(info);
 258       if (_complete) {
 259         return true;
 260       }
 261     }
 262   }
 263   assert(!complete(), "invariant");
 264   return false;
 265 }
 266 
 267 bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) {
 268   assert(jt != NULL, "invariant");
 269   assert(!complete(), "invariant");
 270 
 271   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt);
 272 
 273   if (jt->has_last_Java_frame()) {
 274     // traverse the registered growable array gc_array
 275     // can't do this as it is not reachable from outside
 276 
 277     // Traverse the monitor chunks
 278     MonitorChunk* chunk = jt->monitor_chunks();
 279     for (; chunk != NULL; chunk = chunk->next()) {
 280       chunk->oops_do(&rcl);
 281     }
 282 
 283     if (rcl.complete()) {
 284       return true;
 285     }
 286 
 287     // Traverse the execution stack
 288     for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) {
 289       fst.current()->oops_do(&rcl, NULL, fst.register_map());
 290     }
 291 
 292   } // last java frame
 293 
 294   if (rcl.complete()) {
 295     return true;
 296   }
 297 
 298   GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = JvmtiDeferredUpdates::deferred_locals(jt);
 299   if (list != NULL) {
 300     for (int i = 0; i < list->length(); i++) {
 301       list->at(i)->oops_do(&rcl);
 302     }
 303   }
 304 
 305   if (rcl.complete()) {
 306     return true;
 307   }
 308 
 309   // Traverse instance variables at the end since the GC may be moving things
 310   // around using this function
 311   /*
 312   * // can't reach these oop* from the outside
 313   f->do_oop((oop*) &_threadObj);
 314   f->do_oop((oop*) &_vm_result);
 315   f->do_oop((oop*) &_exception_oop);
 316   f->do_oop((oop*) &_pending_async_exception);
 317   */
 318 
 319   JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state();
 320   if (jvmti_thread_state != NULL) {
 321     jvmti_thread_state->oops_do(&rcl, NULL);
 322   }
 323 
 324   return rcl.complete();
 325 }
 326 
 327 bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) {
 328   assert(jt != NULL, "invariant");
 329   assert(!complete(), "invariant");
 330 
 331   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt);
 332   jt->oops_do(&rcl, NULL);
 333   return rcl.complete();
 334 }
 335 
 336 bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) {
 337   assert(jt != NULL, "invariant");
 338 
 339   if (do_thread_stack_fast(jt)) {
 340     _complete = true;
 341     return true;
 342   }
 343 
 344   if (do_thread_jni_handles(jt)) {
 345     _complete = true;
 346     return true;
 347   }
 348 
 349   if (do_thread_handle_area(jt)) {
 350     _complete = true;
 351     return true;
 352   }
 353 
 354   if (do_thread_stack_detailed(jt)) {
 355     _complete = true;
 356     return true;
 357   }
 358 
 359   return false;
 360 }
 361 
 362 class RootResolverMarkScope : public MarkScope {
 363 };
 364 
 365 void RootResolver::resolve(RootCallback& callback) {
 366   RootResolverMarkScope mark_scope;
 367 
 368   // thread local roots
 369   ReferenceToThreadRootClosure rtrc(callback);
 370   if (rtrc.complete()) {
 371     return;
 372   }
 373   // system global roots
 374   ReferenceToRootClosure rrc(callback);
 375 }