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