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