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 template <typename T, void (T::*F)(OopClosure*)>
  73 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) :
  74     _iter(iter),
  75     _claimed(false) {}
  76 
  77 template <typename T, void (T::*F)(OopClosure*)>
  78 void ZSerialOopsDo<T, F>::oops_do(OopClosure* cl) {
  79   if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
  80     (_iter->*F)(cl);
  81   }
  82 }
  83 
  84 template <typename T, void (T::*F)(OopClosure*)>
  85 ZParallelOopsDo<T, F>::ZParallelOopsDo(T* iter) :
  86     _iter(iter),
  87     _completed(false) {}
  88 
  89 template <typename T, void (T::*F)(OopClosure*)>
  90 void ZParallelOopsDo<T, F>::oops_do(OopClosure* cl) {
  91   if (!_completed) {
  92     (_iter->*F)(cl);
  93     if (!_completed) {
  94       _completed = true;
  95     }
  96   }
  97 }
  98 
  99 template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
 100 ZSerialUnlinkOrOopsDo<T, F>::ZSerialUnlinkOrOopsDo(T* iter) :
 101     _iter(iter),
 102     _claimed(false) {}
 103 
 104 template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
 105 void ZSerialUnlinkOrOopsDo<T, F>::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
 106   if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
 107     (_iter->*F)(is_alive, cl);
 108   }
 109 }
 110 
 111 template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
 112 ZParallelUnlinkOrOopsDo<T, F>::ZParallelUnlinkOrOopsDo(T* iter) :
 113     _iter(iter),
 114     _completed(false) {}
 115 
 116 template <typename T, void (T::*F)(BoolObjectClosure*, OopClosure*)>
 117 void ZParallelUnlinkOrOopsDo<T, F>::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
 118   if (!_completed) {
 119     (_iter->*F)(is_alive, cl);
 120     if (!_completed) {
 121       _completed = true;
 122     }
 123   }
 124 }
 125 
 126 ZRootsIterator::ZRootsIterator() :
 127     _universe(this),
 128     _jni_handles(this),
 129     _jni_weak_handles(this),
 130     _object_synchronizer(this),
 131     _management(this),
 132     _jvmti_export(this),
 133     _jvmti_weak_export(this),
 134     _trace(this),
 135     _system_dictionary(this),
 136     _class_loader_data_graph(this),
 137     _threads(this),
 138     _code_cache(this),
 139     _string_table(this) {
 140   assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
 141   ZStatTimer timer(ZSubPhasePauseRootsSetup);
 142   Threads::change_thread_claim_parity();
 143   StringTable::clear_parallel_claimed_index();
 144   ClassLoaderDataGraph::clear_claimed_marks();
 145   COMPILER2_PRESENT(DerivedPointerTable::clear());
 146   CodeCache::gc_prologue();
 147   ZNMethodTable::gc_prologue();
 148 }
 149 
 150 ZRootsIterator::~ZRootsIterator() {
 151   ZStatTimer timer(ZSubPhasePauseRootsTeardown);
 152   ResourceMark rm;
 153   ZNMethodTable::gc_epilogue();
 154   CodeCache::gc_epilogue();
 155   JvmtiExport::gc_epilogue();
 156   COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
 157   Threads::assert_all_threads_claimed();
 158 }
 159 
 160 void ZRootsIterator::do_universe(OopClosure* cl) {
 161   ZStatTimer timer(ZSubPhasePauseRootsUniverse);
 162   Universe::oops_do(cl);
 163 }
 164 
 165 void ZRootsIterator::do_jni_handles(OopClosure* cl) {
 166   ZStatTimer timer(ZSubPhasePauseRootsJNIHandles);
 167   JNIHandles::oops_do(cl);
 168 }
 169 
 170 void ZRootsIterator::do_jni_weak_handles(OopClosure* cl) {
 171   ZStatTimer timer(ZSubPhasePauseRootsJNIWeakHandles);
 172   JNIHandles::weak_oops_do(cl);
 173 }
 174 
 175 void ZRootsIterator::do_object_synchronizer(OopClosure* cl) {
 176   ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer);
 177   ObjectSynchronizer::oops_do(cl);
 178 }
 179 
 180 void ZRootsIterator::do_management(OopClosure* cl) {
 181   ZStatTimer timer(ZSubPhasePauseRootsManagement);
 182   Management::oops_do(cl);
 183 }
 184 
 185 void ZRootsIterator::do_jvmti_export(OopClosure* cl) {
 186   ZStatTimer timer(ZSubPhasePauseRootsJVMTIExport);
 187   JvmtiExport::oops_do(cl);
 188 }
 189 
 190 void ZRootsIterator::do_jvmti_weak_export(OopClosure* cl) {
 191   ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport);
 192   AlwaysTrueClosure always_alive;
 193   JvmtiExport::weak_oops_do(&always_alive, cl);
 194 }
 195 
 196 void ZRootsIterator::do_trace(OopClosure* cl) {
 197   ZStatTimer timer(ZSubPhasePauseRootsTrace);
 198   AlwaysTrueClosure always_alive;
 199   TRACE_WEAK_OOPS_DO(&always_alive, cl);
 200 }
 201 
 202 void ZRootsIterator::do_system_dictionary(OopClosure* cl) {
 203   ZStatTimer timer(ZSubPhasePauseRootsSystemDictionary);
 204   SystemDictionary::oops_do(cl);
 205 }
 206 
 207 void ZRootsIterator::do_class_loader_data_graph(OopClosure* cl) {
 208   ZStatTimer timer(ZSubPhasePauseRootsClassLoaderDataGraph);
 209   CLDToOopClosure cld_cl(cl);
 210   ClassLoaderDataGraph::cld_do(&cld_cl);
 211 }
 212 
 213 void ZRootsIterator::do_threads(OopClosure* cl) {
 214   ZStatTimer timer(ZSubPhasePauseRootsThreads);
 215   ResourceMark rm;
 216   Threads::possibly_parallel_oops_do(true, cl, NULL);
 217 }
 218 
 219 void ZRootsIterator::do_code_cache(OopClosure* cl) {
 220   ZStatTimer timer(ZSubPhasePauseRootsCodeCache);
 221   ZNMethodTable::oops_do(cl);
 222 }
 223 
 224 void ZRootsIterator::do_string_table(OopClosure* cl) {
 225   ZStatTimer timer(ZSubPhasePauseRootsStringTable);
 226   StringTable::possibly_parallel_oops_do(cl);
 227 }
 228 
 229 void ZRootsIterator::oops_do(OopClosure* cl, bool visit_jvmti_weak_export) {
 230   ZStatTimer timer(ZSubPhasePauseRoots);
 231   _universe.oops_do(cl);
 232   _jni_handles.oops_do(cl);
 233   _object_synchronizer.oops_do(cl);
 234   _management.oops_do(cl);
 235   _jvmti_export.oops_do(cl);
 236   _system_dictionary.oops_do(cl);
 237   _class_loader_data_graph.oops_do(cl);
 238   _threads.oops_do(cl);
 239   _code_cache.oops_do(cl);
 240   if (!ZWeakRoots) {
 241     _jni_weak_handles.oops_do(cl);
 242     _jvmti_weak_export.oops_do(cl);
 243     _trace.oops_do(cl);
 244     _string_table.oops_do(cl);
 245   } else {
 246     if (visit_jvmti_weak_export) {
 247       _jvmti_weak_export.oops_do(cl);
 248     }
 249   }
 250 }
 251 
 252 ZWeakRootsIterator::ZWeakRootsIterator() :
 253     _jni_weak_handles(this),
 254     _jvmti_weak_export(this),
 255     _trace(this),
 256     _symbol_table(this),
 257     _string_table(this) {
 258   assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
 259   ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
 260   SymbolTable::clear_parallel_claimed_index();
 261   StringTable::clear_parallel_claimed_index();
 262 }
 263 
 264 ZWeakRootsIterator::~ZWeakRootsIterator() {
 265   ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown);
 266 }
 267 
 268 void ZWeakRootsIterator::do_jni_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
 269   ZStatTimer timer(ZSubPhasePauseWeakRootsJNIWeakHandles);
 270   JNIHandles::weak_oops_do(is_alive, cl);
 271 }
 272 
 273 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl) {
 274   ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport);
 275   JvmtiExport::weak_oops_do(is_alive, cl);
 276 }
 277 
 278 void ZWeakRootsIterator::do_trace(BoolObjectClosure* is_alive, OopClosure* cl) {
 279   ZStatTimer timer(ZSubPhasePauseWeakRootsTrace);
 280   TRACE_WEAK_OOPS_DO(is_alive, cl);
 281 }
 282 
 283 void ZWeakRootsIterator::do_symbol_table(BoolObjectClosure* is_alive, OopClosure* cl) {
 284   ZStatTimer timer(ZSubPhasePauseWeakRootsSymbolTable);
 285   int dummy;
 286   SymbolTable::possibly_parallel_unlink(&dummy, &dummy);
 287 }
 288 
 289 void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) {
 290   ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable);
 291   int dummy;
 292   StringTable::possibly_parallel_unlink_or_oops_do(is_alive, cl, &dummy, &dummy);
 293 }
 294 
 295 void ZWeakRootsIterator::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
 296   ZStatTimer timer(ZSubPhasePauseWeakRoots);
 297   _symbol_table.unlink_or_oops_do(is_alive, cl);
 298   if (ZWeakRoots) {
 299     _jni_weak_handles.unlink_or_oops_do(is_alive, cl);
 300     _jvmti_weak_export.unlink_or_oops_do(is_alive, cl);
 301     _trace.unlink_or_oops_do(is_alive, cl);
 302     _string_table.unlink_or_oops_do(is_alive, cl);
 303   }
 304 }
 305 
 306 void ZWeakRootsIterator::oops_do(OopClosure* cl) {
 307   AlwaysTrueClosure always_alive;
 308   unlink_or_oops_do(&always_alive, cl);
 309 }
 310 
 311 ZThreadRootsIterator::ZThreadRootsIterator() :
 312     _threads(this) {
 313   assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
 314   ZStatTimer timer(ZSubPhasePauseRootsSetup);
 315   Threads::change_thread_claim_parity();
 316 }
 317 
 318 ZThreadRootsIterator::~ZThreadRootsIterator() {
 319   ZStatTimer timer(ZSubPhasePauseRootsTeardown);
 320   Threads::assert_all_threads_claimed();
 321 }
 322 
 323 void ZThreadRootsIterator::do_threads(OopClosure* cl) {
 324   ZStatTimer timer(ZSubPhasePauseRootsThreads);
 325   ResourceMark rm;
 326   Threads::possibly_parallel_oops_do(true, cl, NULL);
 327 }
 328 
 329 void ZThreadRootsIterator::oops_do(OopClosure* cl) {
 330   ZStatTimer timer(ZSubPhasePauseRoots);
 331   _threads.oops_do(cl);
 332 }