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/classLoaderDataGraph.hpp" 28 #include "classfile/stringTable.hpp" 29 #include "gc/shared/strongRootsScope.hpp" 30 #include "jfr/leakprofiler/utilities/unifiedOop.hpp" 31 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp" 32 #include "memory/iterator.hpp" 33 #include "oops/klass.hpp" 34 #include "oops/markOop.hpp" 35 #include "oops/oop.hpp" 36 #include "prims/jvmtiThreadState.hpp" 37 #include "prims/privilegedStack.hpp" 38 #include "runtime/frame.inline.hpp" 39 #include "runtime/mutexLocker.hpp" 40 #include "runtime/threadSMR.inline.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(const void* 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(const void* ref) { 76 assert(ref != NULL, "invariant"); 77 if (!_complete) { 78 _info._high = ref; 79 _complete = _callback.process(_info); 80 } 81 } 82 83 void ReferenceLocateClosure::do_oop(oop* ref) { 84 do_oop_shared(ref); 85 } 86 87 void ReferenceLocateClosure::do_oop(narrowOop* ref) { 88 do_oop_shared(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_universe_roots(); 100 bool do_jni_handle_roots(); 101 bool do_jvmti_roots(); 102 bool do_system_dictionary_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_strong); 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_jni_handle_roots() { 151 assert(!complete(), "invariant"); 152 ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL); 153 JNIHandles::oops_do(&rlc); 154 return rlc.complete(); 155 } 156 157 bool ReferenceToRootClosure::do_jvmti_roots() { 158 assert(!complete(), "invariant"); 159 ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL); 160 JvmtiExport::oops_do(&rlc); 161 return rlc.complete(); 162 } 163 164 bool ReferenceToRootClosure::do_system_dictionary_roots() { 165 assert(!complete(), "invariant"); 166 ReferenceLocateClosure rlc(_callback, OldObjectRoot::_system_dictionary, OldObjectRoot::_type_undetermined, NULL); 167 SystemDictionary::oops_do(&rlc); 168 return rlc.complete(); 169 } 170 171 bool ReferenceToRootClosure::do_management_roots() { 172 assert(!complete(), "invariant"); 173 ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL); 174 Management::oops_do(&rlc); 175 return rlc.complete(); 176 } 177 178 bool ReferenceToRootClosure::do_string_table_roots() { 179 assert(!complete(), "invariant"); 180 ReferenceLocateClosure rlc(_callback, OldObjectRoot::_string_table, OldObjectRoot::_type_undetermined, NULL); 181 StringTable::oops_do(&rlc); 182 return rlc.complete(); 183 } 184 185 bool ReferenceToRootClosure::do_aot_loader_roots() { 186 assert(!complete(), "invariant"); 187 ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL); 188 AOTLoader::oops_do(&rcl); 189 return rcl.complete(); 190 } 191 192 bool ReferenceToRootClosure::do_roots() { 193 assert(!complete(), "invariant"); 194 assert(OldObjectRoot::_system_undetermined == _info._system, "invariant"); 195 assert(OldObjectRoot::_type_undetermined == _info._type, "invariant"); 196 197 if (do_cldg_roots()) { 198 _complete = true; 199 return true; 200 } 201 202 if (do_object_synchronizer_roots()) { 203 _complete = true; 204 return true; 205 } 206 207 if (do_universe_roots()) { 208 _complete = true; 209 return true; 210 } 211 212 if (do_jni_handle_roots()) { 213 _complete = true; 214 return true; 215 } 216 217 if (do_jvmti_roots()) { 218 _complete = true; 219 return true; 220 } 221 222 if (do_system_dictionary_roots()) { 223 _complete = true; 224 return true; 225 } 226 227 if (do_management_roots()) { 228 _complete = true; 229 return true; 230 } 231 232 if (do_string_table_roots()) { 233 _complete = true; 234 return true; 235 } 236 237 if (do_aot_loader_roots()) { 238 _complete = true; 239 return true; 240 } 241 242 return false; 243 } 244 245 class ReferenceToThreadRootClosure : public StackObj { 246 private: 247 RootCallback& _callback; 248 bool _complete; 249 250 bool do_java_threads_oops(JavaThread* jt); 251 bool do_thread_roots(JavaThread* jt); 252 bool do_thread_stack_fast(JavaThread* jt); 253 bool do_thread_stack_detailed(JavaThread* jt); 254 bool do_thread_jni_handles(JavaThread* jt); 255 bool do_thread_handle_area(JavaThread* jt); 256 257 public: 258 ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) { 259 assert_locked_or_safepoint(Threads_lock); 260 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { 261 if (do_thread_roots(jt)) { 262 return; 263 } 264 } 265 } 266 267 bool complete() const { 268 return _complete; 269 } 270 }; 271 272 bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) { 273 assert(jt != NULL, "invariant"); 274 assert(!complete(), "invariant"); 275 ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt); 276 jt->handle_area()->oops_do(&rcl); 277 return rcl.complete(); 278 } 279 280 bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) { 281 assert(jt != NULL, "invariant"); 282 assert(!complete(), "invariant"); 283 284 ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt); 285 jt->active_handles()->oops_do(&rcl); 286 return rcl.complete(); 287 } 288 289 bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) { 290 assert(jt != NULL, "invariant"); 291 assert(!complete(), "invariant"); 292 293 if (_callback.entries() == 0) { 294 _complete = true; 295 return true; 296 } 297 298 RootCallbackInfo info; 299 info._high = NULL; 300 info._low = NULL; 301 info._context = jt; 302 info._system = OldObjectRoot::_threads; 303 info._type = OldObjectRoot::_stack_variable; 304 305 for (int i = 0; i < _callback.entries(); ++i) { 306 const address adr = (address)_callback.at(i); 307 if (jt->is_in_usable_stack(adr)) { 308 info._high = adr; 309 _complete = _callback.process(info); 310 if (_complete) { 311 return true; 312 } 313 } 314 } 315 assert(!complete(), "invariant"); 316 return false; 317 } 318 319 bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) { 320 assert(jt != NULL, "invariant"); 321 assert(!complete(), "invariant"); 322 323 ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt); 324 325 if (jt->has_last_Java_frame()) { 326 PrivilegedElement* const pelem = jt->privileged_stack_top(); 327 if (pelem != NULL) { 328 pelem->oops_do(&rcl); 329 if (rcl.complete()) { 330 return true; 331 } 332 } 333 334 // traverse the registered growable array gc_array 335 // can't do this as it is not reachable from outside 336 337 // Traverse the monitor chunks 338 MonitorChunk* chunk = jt->monitor_chunks(); 339 for (; chunk != NULL; chunk = chunk->next()) { 340 chunk->oops_do(&rcl); 341 } 342 343 if (rcl.complete()) { 344 return true; 345 } 346 347 // Traverse the execution stack 348 for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) { 349 fst.current()->oops_do(&rcl, NULL, fst.register_map()); 350 } 351 352 } // last java frame 353 354 if (rcl.complete()) { 355 return true; 356 } 357 358 GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = jt->deferred_locals(); 359 if (list != NULL) { 360 for (int i = 0; i < list->length(); i++) { 361 list->at(i)->oops_do(&rcl); 362 } 363 } 364 365 if (rcl.complete()) { 366 return true; 367 } 368 369 // Traverse instance variables at the end since the GC may be moving things 370 // around using this function 371 /* 372 * // can't reach these oop* from the outside 373 f->do_oop((oop*) &_threadObj); 374 f->do_oop((oop*) &_vm_result); 375 f->do_oop((oop*) &_exception_oop); 376 f->do_oop((oop*) &_pending_async_exception); 377 */ 378 379 JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state(); 380 if (jvmti_thread_state != NULL) { 381 jvmti_thread_state->oops_do(&rcl); 382 } 383 384 return rcl.complete(); 385 } 386 387 bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) { 388 assert(jt != NULL, "invariant"); 389 assert(!complete(), "invariant"); 390 391 ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt); 392 jt->oops_do(&rcl, NULL); 393 return rcl.complete(); 394 } 395 396 bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) { 397 assert(jt != NULL, "invariant"); 398 399 if (do_thread_stack_fast(jt)) { 400 _complete = true; 401 return true; 402 } 403 404 if (do_thread_jni_handles(jt)) { 405 _complete = true; 406 return true; 407 } 408 409 if (do_thread_handle_area(jt)) { 410 _complete = true; 411 return true; 412 } 413 414 if (do_thread_stack_detailed(jt)) { 415 _complete = true; 416 return true; 417 } 418 419 return false; 420 } 421 422 class RootResolverMarkScope : public MarkScope { 423 }; 424 425 void RootResolver::resolve(RootCallback& callback) { 426 427 // Need to clear cld claim bit before starting 428 ClassLoaderDataGraph::clear_claimed_marks(); 429 RootResolverMarkScope mark_scope; 430 431 // thread local roots 432 ReferenceToThreadRootClosure rtrc(callback); 433 if (rtrc.complete()) { 434 return; 435 } 436 // system global roots 437 ReferenceToRootClosure rrc(callback); 438 }