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/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 ZSubPhasePauseRootsJNIHandles("Pause Roots JNIHandles"); 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 ZSubPhasePauseRootsClassLoaderDataGraph("Pause Roots ClassLoaderDataGraph"); 62 static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads"); 63 static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache"); 64 65 static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup"); 66 static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots"); 67 static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown"); 68 static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport"); 69 static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak"); 70 71 static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots"); 72 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles"); 73 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles"); 74 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable"); 75 76 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 77 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) : 78 _iter(iter), 79 _claimed(false) {} 80 81 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 82 void ZSerialOopsDo<T, F>::oops_do(ZRootsIteratorClosure* cl) { 83 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) { 84 (_iter->*F)(cl); 85 } 86 } 87 88 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 89 ZParallelOopsDo<T, F>::ZParallelOopsDo(T* iter) : 90 _iter(iter), 91 _completed(false) {} 92 93 template <typename T, void (T::*F)(ZRootsIteratorClosure*)> 94 void ZParallelOopsDo<T, F>::oops_do(ZRootsIteratorClosure* cl) { 95 if (!_completed) { 96 (_iter->*F)(cl); 97 if (!_completed) { 98 _completed = true; 99 } 100 } 101 } 102 103 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 104 ZSerialWeakOopsDo<T, F>::ZSerialWeakOopsDo(T* iter) : 105 _iter(iter), 106 _claimed(false) {} 107 108 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 109 void ZSerialWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 110 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) { 111 (_iter->*F)(is_alive, cl); 112 } 113 } 114 115 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 116 ZParallelWeakOopsDo<T, F>::ZParallelWeakOopsDo(T* iter) : 117 _iter(iter), 118 _completed(false) {} 119 120 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)> 121 void ZParallelWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 122 if (!_completed) { 123 (_iter->*F)(is_alive, cl); 124 if (!_completed) { 125 _completed = true; 126 } 127 } 128 } 129 130 ZRootsIterator::ZRootsIterator() : 131 _jni_handles_iter(JNIHandles::global_handles()), 132 _universe(this), 133 _object_synchronizer(this), 134 _management(this), 135 _jvmti_export(this), 136 _jvmti_weak_export(this), 137 _system_dictionary(this), 138 _jni_handles(this), 139 _class_loader_data_graph(this), 140 _threads(this), 141 _code_cache(this) { 142 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 143 ZStatTimer timer(ZSubPhasePauseRootsSetup); 144 Threads::change_thread_claim_parity(); 145 ClassLoaderDataGraph::clear_claimed_marks(); 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(ZRootsIteratorClosure* cl) { 162 ZStatTimer timer(ZSubPhasePauseRootsUniverse); 163 Universe::oops_do(cl); 164 } 165 166 void ZRootsIterator::do_jni_handles(ZRootsIteratorClosure* cl) { 167 ZStatTimer timer(ZSubPhasePauseRootsJNIHandles); 168 _jni_handles_iter.oops_do(cl); 169 } 170 171 void ZRootsIterator::do_object_synchronizer(ZRootsIteratorClosure* cl) { 172 ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer); 173 ObjectSynchronizer::oops_do(cl); 174 } 175 176 void ZRootsIterator::do_management(ZRootsIteratorClosure* cl) { 177 ZStatTimer timer(ZSubPhasePauseRootsManagement); 178 Management::oops_do(cl); 179 } 180 181 void ZRootsIterator::do_jvmti_export(ZRootsIteratorClosure* cl) { 182 ZStatTimer timer(ZSubPhasePauseRootsJVMTIExport); 183 JvmtiExport::oops_do(cl); 184 } 185 186 void ZRootsIterator::do_jvmti_weak_export(ZRootsIteratorClosure* cl) { 187 ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport); 188 AlwaysTrueClosure always_alive; 189 JvmtiExport::weak_oops_do(&always_alive, cl); 190 } 191 192 void ZRootsIterator::do_system_dictionary(ZRootsIteratorClosure* cl) { 193 ZStatTimer timer(ZSubPhasePauseRootsSystemDictionary); 194 SystemDictionary::oops_do(cl); 195 } 196 197 void ZRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) { 198 ZStatTimer timer(ZSubPhasePauseRootsClassLoaderDataGraph); 199 CLDToOopClosure cld_cl(cl); 200 ClassLoaderDataGraph::cld_do(&cld_cl); 201 } 202 203 void ZRootsIterator::do_threads(ZRootsIteratorClosure* cl) { 204 ZStatTimer timer(ZSubPhasePauseRootsThreads); 205 ResourceMark rm; 206 Threads::possibly_parallel_threads_do(true, cl); 207 } 208 209 void ZRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) { 210 ZStatTimer timer(ZSubPhasePauseRootsCodeCache); 211 ZNMethodTable::oops_do(cl); 212 } 213 214 void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl, bool visit_jvmti_weak_export) { 215 ZStatTimer timer(ZSubPhasePauseRoots); 216 _universe.oops_do(cl); 217 _object_synchronizer.oops_do(cl); 218 _management.oops_do(cl); 219 _jvmti_export.oops_do(cl); 220 _system_dictionary.oops_do(cl); 221 _jni_handles.oops_do(cl); 222 _class_loader_data_graph.oops_do(cl); 223 _threads.oops_do(cl); 224 _code_cache.oops_do(cl); 225 if (visit_jvmti_weak_export) { 226 _jvmti_weak_export.oops_do(cl); 227 } 228 } 229 230 ZWeakRootsIterator::ZWeakRootsIterator() : 231 _jvmti_weak_export(this), 232 _jfr_weak(this) { 233 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 234 ZStatTimer timer(ZSubPhasePauseWeakRootsSetup); 235 } 236 237 ZWeakRootsIterator::~ZWeakRootsIterator() { 238 ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown); 239 } 240 241 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 242 ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport); 243 JvmtiExport::weak_oops_do(is_alive, cl); 244 } 245 246 void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 247 #if INCLUDE_JFR 248 ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak); 249 Jfr::weak_oops_do(is_alive, cl); 250 #endif 251 } 252 253 void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) { 254 ZStatTimer timer(ZSubPhasePauseWeakRoots); 255 _jvmti_weak_export.weak_oops_do(is_alive, cl); 256 _jfr_weak.weak_oops_do(is_alive, cl); 257 } 258 259 void ZWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 260 AlwaysTrueClosure always_alive; 261 weak_oops_do(&always_alive, cl); 262 } 263 264 ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() : 265 _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()), 266 _jni_weak_handles_iter(JNIHandles::weak_global_handles()), 267 _string_table_iter(StringTable::weak_storage()), 268 _vm_weak_handles(this), 269 _jni_weak_handles(this), 270 _string_table(this) { 271 StringTable::reset_dead_counter(); 272 } 273 274 ZConcurrentWeakRootsIterator::~ZConcurrentWeakRootsIterator() { 275 StringTable::finish_dead_counter(); 276 } 277 278 void ZConcurrentWeakRootsIterator::do_vm_weak_handles(ZRootsIteratorClosure* cl) { 279 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsVMWeakHandles); 280 _vm_weak_handles_iter.oops_do(cl); 281 } 282 283 void ZConcurrentWeakRootsIterator::do_jni_weak_handles(ZRootsIteratorClosure* cl) { 284 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsJNIWeakHandles); 285 _jni_weak_handles_iter.oops_do(cl); 286 } 287 288 class ZStringTableDeadCounterClosure : public ZRootsIteratorClosure { 289 private: 290 ZRootsIteratorClosure* const _cl; 291 size_t _ndead; 292 293 public: 294 ZStringTableDeadCounterClosure(ZRootsIteratorClosure* cl) : 295 _cl(cl), 296 _ndead(0) {} 297 298 ~ZStringTableDeadCounterClosure() { 299 StringTable::inc_dead_counter(_ndead); 300 } 301 302 virtual void do_oop(oop* p) { 303 _cl->do_oop(p); 304 if (*p == NULL) { 305 _ndead++; 306 } 307 } 308 309 virtual void do_oop(narrowOop* p) { 310 ShouldNotReachHere(); 311 } 312 }; 313 314 void ZConcurrentWeakRootsIterator::do_string_table(ZRootsIteratorClosure* cl) { 315 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable); 316 ZStringTableDeadCounterClosure counter_cl(cl); 317 _string_table_iter.oops_do(&counter_cl); 318 } 319 320 void ZConcurrentWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 321 ZStatTimer timer(ZSubPhaseConcurrentWeakRoots); 322 _vm_weak_handles.oops_do(cl); 323 _jni_weak_handles.oops_do(cl); 324 _string_table.oops_do(cl); 325 } 326 327 ZThreadRootsIterator::ZThreadRootsIterator() : 328 _threads(this) { 329 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 330 ZStatTimer timer(ZSubPhasePauseRootsSetup); 331 Threads::change_thread_claim_parity(); 332 } 333 334 ZThreadRootsIterator::~ZThreadRootsIterator() { 335 ZStatTimer timer(ZSubPhasePauseRootsTeardown); 336 Threads::assert_all_threads_claimed(); 337 } 338 339 void ZThreadRootsIterator::do_threads(ZRootsIteratorClosure* cl) { 340 ZStatTimer timer(ZSubPhasePauseRootsThreads); 341 ResourceMark rm; 342 Threads::possibly_parallel_oops_do(true, cl, NULL); 343 } 344 345 void ZThreadRootsIterator::oops_do(ZRootsIteratorClosure* cl) { 346 ZStatTimer timer(ZSubPhasePauseRoots); 347 _threads.oops_do(cl); 348 }