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 }