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