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