1 /* 2 * Copyright (c) 2015, 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 #include "precompiled.hpp" 25 #include "classfile/classLoaderDataGraph.hpp" 26 #include "classfile/stringTable.hpp" 27 #include "code/codeCache.hpp" 28 #include "compiler/oopMap.hpp" 29 #include "gc/shared/barrierSet.hpp" 30 #include "gc/shared/barrierSetNMethod.hpp" 31 #include "gc/shared/oopStorageSet.hpp" 32 #include "gc/shared/oopStorageParState.inline.hpp" 33 #include "gc/shared/oopStorageSetParState.inline.hpp" 34 #include "gc/shared/suspendibleThreadSet.hpp" 35 #include "gc/z/zBarrierSetNMethod.hpp" 36 #include "gc/z/zGlobals.hpp" 37 #include "gc/z/zNMethod.hpp" 38 #include "gc/z/zOopClosures.inline.hpp" 39 #include "gc/z/zRootsIterator.hpp" 40 #include "gc/z/zStat.hpp" 41 #include "gc/z/zThreadLocalData.hpp" 42 #include "memory/iterator.hpp" 43 #include "memory/resourceArea.hpp" 44 #include "memory/universe.hpp" 45 #include "prims/jvmtiExport.hpp" 46 #include "prims/resolvedMethodTable.hpp" 47 #include "runtime/atomic.hpp" 48 #include "runtime/safepoint.hpp" 49 #include "runtime/synchronizer.hpp" 50 #include "runtime/thread.hpp" 51 #include "runtime/vmThread.hpp" 52 #include "services/management.hpp" 53 #include "utilities/debug.hpp" 54 #if INCLUDE_JFR 55 #include "jfr/jfr.hpp" 56 #endif 57 58 static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup"); 59 static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots"); 60 static const ZStatSubPhase ZSubPhasePauseRootsTeardown("Pause Roots Teardown"); 61 static const ZStatSubPhase ZSubPhasePauseRootsUniverse("Pause Roots Universe"); 62 static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer"); 63 static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management"); 64 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport"); 65 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport"); 66 static const ZStatSubPhase ZSubPhasePauseRootsVMThread("Pause Roots VM Thread"); 67 static const ZStatSubPhase ZSubPhasePauseRootsJavaThreads("Pause Roots Java Threads"); 68 static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache"); 69 70 static const ZStatSubPhase ZSubPhaseConcurrentRootsSetup("Concurrent Roots Setup"); 71 static const ZStatSubPhase ZSubPhaseConcurrentRoots("Concurrent Roots"); 72 static const ZStatSubPhase ZSubPhaseConcurrentRootsTeardown("Concurrent Roots Teardown"); 73 static const ZStatSubPhase ZSubPhaseConcurrentRootsOopStorageSet("Concurrent Roots OopStorageSet"); 74 static const ZStatSubPhase ZSubPhaseConcurrentRootsClassLoaderDataGraph("Concurrent Roots ClassLoaderDataGraph"); 75 76 static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup"); 77 static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots"); 78 static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown"); 79 static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport"); 80 static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak"); 81 82 static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots"); 83 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles"); 84 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles"); 85 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable"); 86 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsResolvedMethodTable("Concurrent Weak Roots ResolvedMethodTable"); 87 88 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 89 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) : 90 _iter(iter), 91 _claimed(false) {} 92 93 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 94 void ZSerialOopsDo<T, F>::oops_do(ZRootsIteratorClosure* cl) { 95 if (!_claimed && Atomic::cmpxchg(&_claimed, false, true) == false) { 96 (_iter->*F)(cl); 97 } 98 } 99 100 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 101 ZParallelOopsDo<T, F>::ZParallelOopsDo(T* iter) : 102 _iter(iter), 103 _completed(false) {} 104 105 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 106 void ZParallelOopsDo<T, F>::oops_do(ZRootsIteratorClosure* cl) { 107 if (!_completed) { 108 (_iter->*F)(cl); 109 if (!_completed) { 110 _completed = true; 111 } 112 } 113 } 114 115 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 116 ZSerialWeakOopsDo<T, F>::ZSerialWeakOopsDo(T* iter) : 117 _iter(iter), 118 _claimed(false) {} 119 120 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 121 void ZSerialWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 122 if (!_claimed && Atomic::cmpxchg(&_claimed, false, true) == false) { 123 (_iter->*F)(is_alive, cl); 124 } 125 } 126 127 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 128 ZParallelWeakOopsDo<T, F>::ZParallelWeakOopsDo(T* iter) : 129 _iter(iter), 130 _completed(false) {} 131 132 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 133 void ZParallelWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 134 if (!_completed) { 135 (_iter->*F)(is_alive, cl); 136 if (!_completed) { 137 _completed = true; 138 } 139 } 140 } 141 142 class ZRootsIteratorCodeBlobClosure : public CodeBlobClosure { 143 private: 144 ZRootsIteratorClosure* const _cl; 145 const bool _should_disarm_nmethods; 146 147 public: 148 ZRootsIteratorCodeBlobClosure(ZRootsIteratorClosure* cl) : 149 _cl(cl), 150 _should_disarm_nmethods(cl->should_disarm_nmethods()) {} 151 152 virtual void do_code_blob(CodeBlob* cb) { 153 nmethod* const nm = cb->as_nmethod_or_null(); 154 if (nm != NULL && nm->oops_do_try_claim()) { 155 ZNMethod::nmethod_oops_do(nm, _cl); 156 assert(!ZNMethod::supports_entry_barrier(nm) || 157 ZNMethod::is_armed(nm) == _should_disarm_nmethods, "Invalid state"); 158 if (_should_disarm_nmethods) { 159 ZNMethod::disarm(nm); 160 } 161 } 162 } 163 }; 164 165 class ZRootsIteratorThreadClosure : public ThreadClosure { 166 private: 167 ZRootsIteratorClosure* const _cl; 168 ResourceMark _rm; 169 170 public: 171 ZRootsIteratorThreadClosure(ZRootsIteratorClosure* cl) : 172 _cl(cl) {} 173 174 virtual void do_thread(Thread* thread) { 175 ZRootsIteratorCodeBlobClosure code_cl(_cl); 176 thread->oops_do(_cl, ClassUnloading ? &code_cl : NULL); 177 _cl->do_thread(thread); 178 } 179 }; 180 181 ZJavaThreadsIterator::ZJavaThreadsIterator() : 182 _threads(), 183 _claimed(0) {} 184 185 uint ZJavaThreadsIterator::claim() { 186 return Atomic::fetch_and_add(&_claimed, 1u); 187 } 188 189 void ZJavaThreadsIterator::threads_do(ThreadClosure* cl) { 190 for (uint i = claim(); i < _threads.length(); i = claim()) { 191 cl->do_thread(_threads.thread_at(i)); 192 } 193 } 194 195 ZRootsIterator::ZRootsIterator(bool visit_jvmti_weak_export) : 196 _visit_jvmti_weak_export(visit_jvmti_weak_export), 197 _java_threads_iter(), 198 _universe(this), 199 _object_synchronizer(this), 200 _management(this), 201 _jvmti_export(this), 202 _jvmti_weak_export(this), 203 _vm_thread(this), 204 _java_threads(this), 205 _code_cache(this) { 206 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 207 ZStatTimer timer(ZSubPhasePauseRootsSetup); 208 COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::clear()); 209 if (ClassUnloading) { 210 nmethod::oops_do_marking_prologue(); 211 } else { 212 ZNMethod::oops_do_begin(); 213 } 214 } 215 216 ZRootsIterator::~ZRootsIterator() { 217 ZStatTimer timer(ZSubPhasePauseRootsTeardown); 218 ResourceMark rm; 219 if (ClassUnloading) { 220 nmethod::oops_do_marking_epilogue(); 221 } else { 222 ZNMethod::oops_do_end(); 223 } 224 225 COMPILER2_OR_JVMCI_PRESENT(DerivedPointerTable::update_pointers()); 226 } 227 228 void ZRootsIterator::do_universe(ZRootsIteratorClosure* cl) { 229 ZStatTimer timer(ZSubPhasePauseRootsUniverse); 230 Universe::oops_do(cl); 231 } 232 233 void ZRootsIterator::do_object_synchronizer(ZRootsIteratorClosure* cl) { 234 ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer); 235 ObjectSynchronizer::oops_do(cl); 236 } 237 238 void ZRootsIterator::do_management(ZRootsIteratorClosure* cl) { 239 ZStatTimer timer(ZSubPhasePauseRootsManagement); 240 Management::oops_do(cl); 241 } 242 243 void ZRootsIterator::do_jvmti_export(ZRootsIteratorClosure* cl) { 244 ZStatTimer timer(ZSubPhasePauseRootsJVMTIExport); 245 JvmtiExport::oops_do(cl); 246 } 247 248 void ZRootsIterator::do_jvmti_weak_export(ZRootsIteratorClosure* cl) { 249 ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport); 250 AlwaysTrueClosure always_alive; 251 JvmtiExport::weak_oops_do(&always_alive, cl); 252 } 253 254 void ZRootsIterator::do_vm_thread(ZRootsIteratorClosure* cl) { 255 ZStatTimer timer(ZSubPhasePauseRootsVMThread); 256 ZRootsIteratorThreadClosure thread_cl(cl); 257 thread_cl.do_thread(VMThread::vm_thread()); 258 } 259 260 void ZRootsIterator::do_java_threads(ZRootsIteratorClosure* cl) { 261 ZStatTimer timer(ZSubPhasePauseRootsJavaThreads); 262 ZRootsIteratorThreadClosure thread_cl(cl); 263 _java_threads_iter.threads_do(&thread_cl); 264 } 265 266 void ZRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) { 267 ZStatTimer timer(ZSubPhasePauseRootsCodeCache); 268 ZNMethod::oops_do(cl); 269 } 270 271 void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 272 ZStatTimer timer(ZSubPhasePauseRoots); 273 _universe.oops_do(cl); 274 _object_synchronizer.oops_do(cl); 275 _management.oops_do(cl); 276 _jvmti_export.oops_do(cl); 277 _vm_thread.oops_do(cl); 278 _java_threads.oops_do(cl); 279 if (!ClassUnloading) { 280 _code_cache.oops_do(cl); 281 } 282 if (_visit_jvmti_weak_export) { 283 _jvmti_weak_export.oops_do(cl); 284 } 285 } 286 287 ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) : 288 _oop_storage_set_iter(), 289 _cld_claim(cld_claim), 290 _oop_storage_set(this), 291 _class_loader_data_graph(this) { 292 ZStatTimer timer(ZSubPhaseConcurrentRootsSetup); 293 ClassLoaderDataGraph::clear_claimed_marks(cld_claim); 294 } 295 296 ZConcurrentRootsIterator::~ZConcurrentRootsIterator() { 297 ZStatTimer timer(ZSubPhaseConcurrentRootsTeardown); 298 } 299 300 void ZConcurrentRootsIterator::do_oop_storage_set(ZRootsIteratorClosure* cl) { 301 ZStatTimer timer(ZSubPhaseConcurrentRootsOopStorageSet); 302 _oop_storage_set_iter.oops_do(cl); 303 } 304 305 void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) { 306 ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph); 307 CLDToOopClosure cld_cl(cl, _cld_claim); 308 ClassLoaderDataGraph::always_strong_cld_do(&cld_cl); 309 } 310 311 void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 312 ZStatTimer timer(ZSubPhaseConcurrentRoots); 313 _oop_storage_set.oops_do(cl); 314 _class_loader_data_graph.oops_do(cl); 315 } 316 317 ZWeakRootsIterator::ZWeakRootsIterator() : 318 _jvmti_weak_export(this), 319 _jfr_weak(this) { 320 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 321 ZStatTimer timer(ZSubPhasePauseWeakRootsSetup); 322 } 323 324 ZWeakRootsIterator::~ZWeakRootsIterator() { 325 ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown); 326 } 327 328 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 329 ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport); 330 JvmtiExport::weak_oops_do(is_alive, cl); 331 } 332 333 void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 334 #if INCLUDE_JFR 335 ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak); 336 Jfr::weak_oops_do(is_alive, cl); 337 #endif 338 } 339 340 void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 341 ZStatTimer timer(ZSubPhasePauseWeakRoots); 342 _jvmti_weak_export.weak_oops_do(is_alive, cl); 343 _jfr_weak.weak_oops_do(is_alive, cl); 344 } 345 346 void ZWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 347 AlwaysTrueClosure always_alive; 348 weak_oops_do(&always_alive, cl); 349 } 350 351 ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() : 352 _vm_weak_handles_iter(OopStorageSet::vm_weak()), 353 _jni_weak_handles_iter(OopStorageSet::jni_weak()), 354 _string_table_iter(OopStorageSet::string_table_weak()), 355 _resolved_method_table_iter(OopStorageSet::resolved_method_table_weak()), 356 _vm_weak_handles(this), 357 _jni_weak_handles(this), 358 _string_table(this), 359 _resolved_method_table(this) { 360 StringTable::reset_dead_counter(); 361 ResolvedMethodTable::reset_dead_counter(); 362 } 363 364 ZConcurrentWeakRootsIterator::~ZConcurrentWeakRootsIterator() { 365 StringTable::finish_dead_counter(); 366 ResolvedMethodTable::finish_dead_counter(); 367 } 368 369 void ZConcurrentWeakRootsIterator::do_vm_weak_handles(ZRootsIteratorClosure* cl) { 370 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsVMWeakHandles); 371 _vm_weak_handles_iter.oops_do(cl); 372 } 373 374 void ZConcurrentWeakRootsIterator::do_jni_weak_handles(ZRootsIteratorClosure* cl) { 375 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsJNIWeakHandles); 376 _jni_weak_handles_iter.oops_do(cl); 377 } 378 379 template <class Container> 380 class ZDeadCounterClosure : public ZRootsIteratorClosure { 381 private: 382 ZRootsIteratorClosure* const _cl; 383 size_t _ndead; 384 385 public: 386 ZDeadCounterClosure(ZRootsIteratorClosure* cl) : 387 _cl(cl), 388 _ndead(0) {} 389 390 ~ZDeadCounterClosure() { 391 Container::inc_dead_counter(_ndead); 392 } 393 394 virtual void do_oop(oop* p) { 395 _cl->do_oop(p); 396 if (*p == NULL) { 397 _ndead++; 398 } 399 } 400 401 virtual void do_oop(narrowOop* p) { 402 ShouldNotReachHere(); 403 } 404 }; 405 406 void ZConcurrentWeakRootsIterator::do_string_table(ZRootsIteratorClosure* cl) { 407 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable); 408 ZDeadCounterClosure<StringTable> counter_cl(cl); 409 _string_table_iter.oops_do(&counter_cl); 410 } 411 412 void ZConcurrentWeakRootsIterator::do_resolved_method_table(ZRootsIteratorClosure* cl) { 413 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsResolvedMethodTable); 414 ZDeadCounterClosure<ResolvedMethodTable> counter_cl(cl); 415 _resolved_method_table_iter.oops_do(&counter_cl); 416 } 417 418 void ZConcurrentWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 419 ZStatTimer timer(ZSubPhaseConcurrentWeakRoots); 420 _vm_weak_handles.oops_do(cl); 421 _jni_weak_handles.oops_do(cl); 422 _string_table.oops_do(cl); 423 _resolved_method_table.oops_do(cl); 424 }