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