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/symbolTable.hpp" 28 #include "classfile/systemDictionary.hpp" 29 #include "code/codeCache.hpp" 30 #include "compiler/oopMap.hpp" 31 #include "gc/shared/oopStorageParState.inline.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 "memory/universe.hpp" 37 #include "prims/jvmtiExport.hpp" 38 #include "runtime/atomic.hpp" 39 #include "runtime/jniHandles.hpp" 40 #include "runtime/thread.hpp" 41 #include "runtime/safepoint.hpp" 42 #include "runtime/synchronizer.hpp" 43 #include "services/management.hpp" 44 #include "trace/traceMacros.hpp" 45 #include "utilities/debug.hpp" 46 47 static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup"); 48 static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots"); 49 static const ZStatSubPhase ZSubPhasePauseRootsTeardown("Pause Roots Teardown"); 50 static const ZStatSubPhase ZSubPhasePauseRootsUniverse("Pause Roots Universe"); 51 static const ZStatSubPhase ZSubPhasePauseRootsJNIHandles("Pause Roots JNIHandles"); 52 static const ZStatSubPhase ZSubPhasePauseRootsJNIWeakHandles("Pause Roots JNIWeakHandles"); 53 static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer"); 54 static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management"); 55 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport"); 56 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport"); 57 static const ZStatSubPhase ZSubPhasePauseRootsTrace("Pause Roots Trace"); 58 static const ZStatSubPhase ZSubPhasePauseRootsSystemDictionary("Pause Roots SystemDictionary"); 59 static const ZStatSubPhase ZSubPhasePauseRootsClassLoaderDataGraph("Pause Roots ClassLoaderDataGraph"); 60 static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads"); 61 static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache"); 62 static const ZStatSubPhase ZSubPhasePauseRootsStringTable("Pause Roots StringTable"); 63 64 static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup"); 65 static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots"); 66 static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown"); 67 static const ZStatSubPhase ZSubPhasePauseWeakRootsJNIWeakHandles("Pause Weak Roots JNIWeakHandles"); 68 static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport"); 69 static const ZStatSubPhase ZSubPhasePauseWeakRootsTrace("Pause Weak Roots Trace"); 70 static const ZStatSubPhase ZSubPhasePauseWeakRootsSymbolTable("Pause Weak Roots SymbolTable"); 71 static const ZStatSubPhase ZSubPhasePauseWeakRootsStringTable("Pause Weak Roots StringTable"); 72 73 static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots"); 74 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles"); 75 76 template <typename T, void (T::*F)(OopClosure*)> 77 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) : 78 _iter(iter), 79 _claimed(false) {} 80 81 template <typename T, void (T::*F)(OopClosure*)> 82 void ZSerialOopsDo<T, F>::oops_do(OopClosure* cl) { 83 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) { 84 (_iter->*F)(cl); 85 } 86 } 87 88 template <typename T, void (T::*F)(OopClosure*)> 89 ZParallelOopsDo<T, F>::ZParallelOopsDo(T* iter) : 90 _iter(iter), 91 _completed(false) {} 92 93 template <typename T, void (T::*F)(OopClosure*)> 94 void ZParallelOopsDo<T, F>::oops_do(OopClosure* 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*, OopClosure*)> 104 ZSerialUnlinkOrOopsDo<T, F>::ZSerialUnlinkOrOopsDo(T* iter) : 105 _iter(iter), 106 _claimed(false) {} 107 108 template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)> 109 void ZSerialUnlinkOrOopsDo<T, F>::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* 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*, OopClosure*)> 116 ZParallelUnlinkOrOopsDo<T, F>::ZParallelUnlinkOrOopsDo(T* iter) : 117 _iter(iter), 118 _completed(false) {} 119 120 template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)> 121 void ZParallelUnlinkOrOopsDo<T, F>::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) { 122 if (!_completed) { 123 (_iter->*F)(is_alive, cl); 124 if (!_completed) { 125 _completed = true; 126 } 127 } 128 } 129 130 ZRootsIterator::ZRootsIterator() : 131 _universe(this), 132 _jni_handles(this), 133 _jni_weak_handles(this), 134 _object_synchronizer(this), 135 _management(this), 136 _jvmti_export(this), 137 _jvmti_weak_export(this), 138 _trace(this), 139 _system_dictionary(this), 140 _class_loader_data_graph(this), 141 _threads(this), 142 _code_cache(this), 143 _string_table(this) { 144 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 145 ZStatTimer timer(ZSubPhasePauseRootsSetup); 146 Threads::change_thread_claim_parity(); 147 StringTable::clear_parallel_claimed_index(); 148 ClassLoaderDataGraph::clear_claimed_marks(); 149 COMPILER2_PRESENT(DerivedPointerTable::clear()); 150 CodeCache::gc_prologue(); 151 ZNMethodTable::gc_prologue(); 152 } 153 154 ZRootsIterator::~ZRootsIterator() { 155 ZStatTimer timer(ZSubPhasePauseRootsTeardown); 156 ResourceMark rm; 157 ZNMethodTable::gc_epilogue(); 158 CodeCache::gc_epilogue(); 159 JvmtiExport::gc_epilogue(); 160 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); 161 Threads::assert_all_threads_claimed(); 162 } 163 164 void ZRootsIterator::do_universe(OopClosure* cl) { 165 ZStatTimer timer(ZSubPhasePauseRootsUniverse); 166 Universe::oops_do(cl); 167 } 168 169 void ZRootsIterator::do_jni_handles(OopClosure* cl) { 170 ZStatTimer timer(ZSubPhasePauseRootsJNIHandles); 171 JNIHandles::oops_do(cl); 172 } 173 174 void ZRootsIterator::do_jni_weak_handles(OopClosure* cl) { 175 ZStatTimer timer(ZSubPhasePauseRootsJNIWeakHandles); 176 JNIHandles::weak_oops_do(cl); 177 } 178 179 void ZRootsIterator::do_object_synchronizer(OopClosure* cl) { 180 ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer); 181 ObjectSynchronizer::oops_do(cl); 182 } 183 184 void ZRootsIterator::do_management(OopClosure* cl) { 185 ZStatTimer timer(ZSubPhasePauseRootsManagement); 186 Management::oops_do(cl); 187 } 188 189 void ZRootsIterator::do_jvmti_export(OopClosure* cl) { 190 ZStatTimer timer(ZSubPhasePauseRootsJVMTIExport); 191 JvmtiExport::oops_do(cl); 192 } 193 194 void ZRootsIterator::do_jvmti_weak_export(OopClosure* cl) { 195 ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport); 196 AlwaysTrueClosure always_alive; 197 JvmtiExport::weak_oops_do(&always_alive, cl); 198 } 199 200 void ZRootsIterator::do_trace(OopClosure* cl) { 201 ZStatTimer timer(ZSubPhasePauseRootsTrace); 202 AlwaysTrueClosure always_alive; 203 TRACE_WEAK_OOPS_DO(&always_alive, cl); 204 } 205 206 void ZRootsIterator::do_system_dictionary(OopClosure* cl) { 207 ZStatTimer timer(ZSubPhasePauseRootsSystemDictionary); 208 SystemDictionary::oops_do(cl); 209 } 210 211 void ZRootsIterator::do_class_loader_data_graph(OopClosure* cl) { 212 ZStatTimer timer(ZSubPhasePauseRootsClassLoaderDataGraph); 213 CLDToOopClosure cld_cl(cl); 214 ClassLoaderDataGraph::cld_do(&cld_cl); 215 } 216 217 void ZRootsIterator::do_threads(OopClosure* cl) { 218 ZStatTimer timer(ZSubPhasePauseRootsThreads); 219 ResourceMark rm; 220 Threads::possibly_parallel_oops_do(true, cl, NULL); 221 } 222 223 void ZRootsIterator::do_code_cache(OopClosure* cl) { 224 ZStatTimer timer(ZSubPhasePauseRootsCodeCache); 225 ZNMethodTable::oops_do(cl); 226 } 227 228 void ZRootsIterator::do_string_table(OopClosure* cl) { 229 ZStatTimer timer(ZSubPhasePauseRootsStringTable); 230 StringTable::possibly_parallel_oops_do(cl); 231 } 232 233 void ZRootsIterator::oops_do(OopClosure* cl, bool visit_jvmti_weak_export) { 234 ZStatTimer timer(ZSubPhasePauseRoots); 235 _universe.oops_do(cl); 236 _jni_handles.oops_do(cl); 237 _object_synchronizer.oops_do(cl); 238 _management.oops_do(cl); 239 _jvmti_export.oops_do(cl); 240 _system_dictionary.oops_do(cl); 241 _class_loader_data_graph.oops_do(cl); 242 _threads.oops_do(cl); 243 _code_cache.oops_do(cl); 244 if (!ZWeakRoots) { 245 _jni_weak_handles.oops_do(cl); 246 _jvmti_weak_export.oops_do(cl); 247 _trace.oops_do(cl); 248 _string_table.oops_do(cl); 249 } else { 250 if (visit_jvmti_weak_export) { 251 _jvmti_weak_export.oops_do(cl); 252 } 253 } 254 } 255 256 ZWeakRootsIterator::ZWeakRootsIterator() : 257 _jni_weak_handles(this), 258 _jvmti_weak_export(this), 259 _trace(this), 260 _symbol_table(this), 261 _string_table(this) { 262 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 263 ZStatTimer timer(ZSubPhasePauseWeakRootsSetup); 264 SymbolTable::clear_parallel_claimed_index(); 265 StringTable::clear_parallel_claimed_index(); 266 } 267 268 ZWeakRootsIterator::~ZWeakRootsIterator() { 269 ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown); 270 } 271 272 void ZWeakRootsIterator::do_jni_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) { 273 ZStatTimer timer(ZSubPhasePauseWeakRootsJNIWeakHandles); 274 JNIHandles::weak_oops_do(is_alive, cl); 275 } 276 277 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl) { 278 ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport); 279 JvmtiExport::weak_oops_do(is_alive, cl); 280 } 281 282 void ZWeakRootsIterator::do_trace(BoolObjectClosure* is_alive, OopClosure* cl) { 283 ZStatTimer timer(ZSubPhasePauseWeakRootsTrace); 284 TRACE_WEAK_OOPS_DO(is_alive, cl); 285 } 286 287 void ZWeakRootsIterator::do_symbol_table(BoolObjectClosure* is_alive, OopClosure* cl) { 288 ZStatTimer timer(ZSubPhasePauseWeakRootsSymbolTable); 289 int dummy; 290 SymbolTable::possibly_parallel_unlink(&dummy, &dummy); 291 } 292 293 void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) { 294 ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable); 295 int dummy; 296 StringTable::possibly_parallel_unlink_or_oops_do(is_alive, cl, &dummy, &dummy); 297 } 298 299 void ZWeakRootsIterator::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) { 300 ZStatTimer timer(ZSubPhasePauseWeakRoots); 301 _symbol_table.unlink_or_oops_do(is_alive, cl); 302 if (ZWeakRoots) { 303 if (!ZConcurrentJNIWeakGlobalHandles) { 304 _jni_weak_handles.unlink_or_oops_do(is_alive, cl); 305 } 306 _jvmti_weak_export.unlink_or_oops_do(is_alive, cl); 307 _trace.unlink_or_oops_do(is_alive, cl); 308 _string_table.unlink_or_oops_do(is_alive, cl); 309 } 310 } 311 312 void ZWeakRootsIterator::oops_do(OopClosure* cl) { 313 AlwaysTrueClosure always_alive; 314 unlink_or_oops_do(&always_alive, cl); 315 } 316 317 void ZConcurrentWeakRootsIterator::do_jni_weak_handles(OopClosure* cl) { 318 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsJNIWeakHandles); 319 _par_state.oops_do(cl); 320 } 321 322 ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() : 323 _par_state(JNIHandles::weak_global_handles()), 324 _jni_weak_handles(this) {} 325 326 void ZConcurrentWeakRootsIterator::oops_do(OopClosure* cl) { 327 ZStatTimer timer(ZSubPhaseConcurrentWeakRoots); 328 if (ZWeakRoots) { 329 if (ZConcurrentJNIWeakGlobalHandles) { 330 _jni_weak_handles.oops_do(cl); 331 } 332 } 333 } 334 335 ZThreadRootsIterator::ZThreadRootsIterator() : 336 _threads(this) { 337 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); 338 ZStatTimer timer(ZSubPhasePauseRootsSetup); 339 Threads::change_thread_claim_parity(); 340 } 341 342 ZThreadRootsIterator::~ZThreadRootsIterator() { 343 ZStatTimer timer(ZSubPhasePauseRootsTeardown); 344 Threads::assert_all_threads_claimed(); 345 } 346 347 void ZThreadRootsIterator::do_threads(OopClosure* cl) { 348 ZStatTimer timer(ZSubPhasePauseRootsThreads); 349 ResourceMark rm; 350 Threads::possibly_parallel_oops_do(true, cl, NULL); 351 } 352 353 void ZThreadRootsIterator::oops_do(OopClosure* cl) { 354 ZStatTimer timer(ZSubPhasePauseRoots); 355 _threads.oops_do(cl); 356 }