1 /*
   2  * Copyright (c) 2015, 2020, Red Hat, Inc. 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 
  25 #include "precompiled.hpp"
  26 
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "code/codeCache.hpp"
  31 #include "code/nmethod.hpp"
  32 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
  33 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
  34 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
  35 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
  36 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  37 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  38 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  39 #include "jfr/jfr.hpp"
  40 #include "memory/iterator.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "memory/universe.hpp"
  43 #include "runtime/thread.hpp"
  44 #include "services/management.hpp"
  45 
  46 ShenandoahSerialRoot::ShenandoahSerialRoot(ShenandoahSerialRoot::OopsDo oops_do,
  47   ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase) :
  48   _oops_do(oops_do), _phase(phase), _par_phase(par_phase) {
  49 }
  50 
  51 void ShenandoahSerialRoot::oops_do(OopClosure* cl, uint worker_id) {
  52   if (_claimed.try_set()) {
  53     ShenandoahWorkerTimingsTracker timer(_phase, _par_phase, worker_id);
  54     _oops_do(cl);
  55   }
  56 }
  57 
  58 // Overwrite the second argument for SD::oops_do, don't include vm global oop storage.
  59 static void system_dictionary_oops_do(OopClosure* cl) {
  60   SystemDictionary::oops_do(cl, false);
  61 }
  62 
  63 ShenandoahSerialRoots::ShenandoahSerialRoots(ShenandoahPhaseTimings::Phase phase) :
  64   _universe_root(&Universe::oops_do, phase, ShenandoahPhaseTimings::UniverseRoots),
  65   _object_synchronizer_root(&ObjectSynchronizer::oops_do, phase, ShenandoahPhaseTimings::ObjectSynchronizerRoots),
  66   _management_root(&Management::oops_do, phase, ShenandoahPhaseTimings::ManagementRoots),
  67   _system_dictionary_root(&system_dictionary_oops_do, phase, ShenandoahPhaseTimings::SystemDictionaryRoots),
  68   _jvmti_root(&JvmtiExport::oops_do, phase, ShenandoahPhaseTimings::JVMTIRoots) {
  69 }
  70 
  71 void ShenandoahSerialRoots::oops_do(OopClosure* cl, uint worker_id) {
  72   _universe_root.oops_do(cl, worker_id);
  73   _object_synchronizer_root.oops_do(cl, worker_id);
  74   _management_root.oops_do(cl, worker_id);
  75   _system_dictionary_root.oops_do(cl, worker_id);
  76   _jvmti_root.oops_do(cl, worker_id);
  77 }
  78 
  79 ShenandoahWeakSerialRoot::ShenandoahWeakSerialRoot(ShenandoahWeakSerialRoot::WeakOopsDo weak_oops_do,
  80   ShenandoahPhaseTimings::Phase phase, ShenandoahPhaseTimings::ParPhase par_phase) :
  81   _weak_oops_do(weak_oops_do), _phase(phase), _par_phase(par_phase) {
  82 }
  83 
  84 void ShenandoahWeakSerialRoot::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
  85   if (_claimed.try_set()) {
  86     ShenandoahWorkerTimingsTracker timer(_phase, _par_phase, worker_id);
  87     _weak_oops_do(is_alive, keep_alive);
  88   }
  89 }
  90 
  91 #if INCLUDE_JVMTI
  92 ShenandoahJVMTIWeakRoot::ShenandoahJVMTIWeakRoot(ShenandoahPhaseTimings::Phase phase) :
  93   ShenandoahWeakSerialRoot(&JvmtiExport::weak_oops_do, phase, ShenandoahPhaseTimings::JVMTIWeakRoots) {
  94 }
  95 #endif // INCLUDE_JVMTI
  96 
  97 #if INCLUDE_JFR
  98 ShenandoahJFRWeakRoot::ShenandoahJFRWeakRoot(ShenandoahPhaseTimings::Phase phase) :
  99   ShenandoahWeakSerialRoot(&Jfr::weak_oops_do, phase, ShenandoahPhaseTimings::JFRWeakRoots) {
 100 }
 101 #endif // INCLUDE_JFR
 102 
 103 void ShenandoahSerialWeakRoots::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
 104   JVMTI_ONLY(_jvmti_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
 105   JFR_ONLY(_jfr_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
 106 }
 107 
 108 void ShenandoahSerialWeakRoots::weak_oops_do(OopClosure* cl, uint worker_id) {
 109   AlwaysTrueClosure always_true;
 110   weak_oops_do(&always_true, cl, worker_id);
 111 }
 112 
 113 ShenandoahThreadRoots::ShenandoahThreadRoots(ShenandoahPhaseTimings::Phase phase, bool is_par) :
 114   _phase(phase), _is_par(is_par) {
 115   Threads::change_thread_claim_token();
 116 }
 117 
 118 void ShenandoahThreadRoots::oops_do(OopClosure* oops_cl, CodeBlobClosure* code_cl, uint worker_id) {
 119   ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::ThreadRoots, worker_id);
 120   ResourceMark rm;
 121   Threads::possibly_parallel_oops_do(_is_par, oops_cl, code_cl);
 122 }
 123 
 124 void ShenandoahThreadRoots::threads_do(ThreadClosure* tc, uint worker_id) {
 125   ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::ThreadRoots, worker_id);
 126   ResourceMark rm;
 127   Threads::possibly_parallel_threads_do(_is_par, tc);
 128 }
 129 
 130 ShenandoahThreadRoots::~ShenandoahThreadRoots() {
 131   Threads::assert_all_threads_claimed();
 132 }
 133 
 134 ShenandoahStringDedupRoots::ShenandoahStringDedupRoots(ShenandoahPhaseTimings::Phase phase) : _phase(phase) {
 135   if (ShenandoahStringDedup::is_enabled()) {
 136     StringDedup::gc_prologue(false);
 137   }
 138 }
 139 
 140 ShenandoahStringDedupRoots::~ShenandoahStringDedupRoots() {
 141   if (ShenandoahStringDedup::is_enabled()) {
 142     StringDedup::gc_epilogue();
 143   }
 144 }
 145 
 146 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
 147   if (ShenandoahStringDedup::is_enabled()) {
 148     ShenandoahStringDedup::parallel_oops_do(_phase, is_alive, keep_alive, worker_id);
 149   }
 150 }
 151 
 152 ShenandoahConcurrentStringDedupRoots::ShenandoahConcurrentStringDedupRoots() {
 153   if (ShenandoahStringDedup::is_enabled()) {
 154     StringDedupTable_lock->lock_without_safepoint_check();
 155     StringDedupQueue_lock->lock_without_safepoint_check();
 156     StringDedup::gc_prologue(true);
 157   }
 158 }
 159 
 160 ShenandoahConcurrentStringDedupRoots::~ShenandoahConcurrentStringDedupRoots() {
 161   if (ShenandoahStringDedup::is_enabled()) {
 162     StringDedup::gc_epilogue();
 163     StringDedupQueue_lock->unlock();
 164     StringDedupTable_lock->unlock();
 165   }
 166 }
 167 
 168 void ShenandoahConcurrentStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
 169   if (ShenandoahStringDedup::is_enabled()) {
 170     assert_locked_or_safepoint_weak(StringDedupQueue_lock);
 171     assert_locked_or_safepoint_weak(StringDedupTable_lock);
 172 
 173     StringDedupUnlinkOrOopsDoClosure sd_cl(is_alive, keep_alive);
 174     StringDedupQueue::unlink_or_oops_do(&sd_cl);
 175     StringDedupTable::unlink_or_oops_do(&sd_cl, worker_id);
 176   }
 177 }
 178 
 179 ShenandoahCodeCacheRoots::ShenandoahCodeCacheRoots(ShenandoahPhaseTimings::Phase phase) : _phase(phase) {
 180   nmethod::oops_do_marking_prologue();
 181 }
 182 
 183 void ShenandoahCodeCacheRoots::code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id) {
 184   ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
 185   _coderoots_iterator.possibly_parallel_blobs_do(blob_cl);
 186 }
 187 
 188 ShenandoahCodeCacheRoots::~ShenandoahCodeCacheRoots() {
 189   nmethod::oops_do_marking_epilogue();
 190 }
 191 
 192 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
 193   _heap(ShenandoahHeap::heap()),
 194   _phase(phase),
 195   _worker_phase(phase) {
 196   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 197 }
 198 
 199 ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 200   ShenandoahRootProcessor(phase),
 201   _serial_roots(phase),
 202   _thread_roots(phase, n_workers > 1),
 203   _dedup_roots(phase) {
 204   nmethod::oops_do_marking_prologue();
 205 }
 206 
 207 ShenandoahRootScanner::~ShenandoahRootScanner() {
 208   nmethod::oops_do_marking_epilogue();
 209 }
 210 
 211 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) {
 212   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 213   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 214   roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 215 }
 216 
 217 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops) {
 218   CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
 219   MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
 220   strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
 221 }
 222 
 223 void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
 224   assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint() ||
 225          !ShenandoahHeap::heap()->unload_classes(),
 226           "Expect class unloading when Shenandoah cycle is running");
 227   ResourceMark rm;
 228 
 229   _serial_roots.oops_do(oops, worker_id);
 230   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 231   _thread_roots.threads_do(&tc_cl, worker_id);
 232 
 233   AlwaysTrueClosure always_true;
 234   _dedup_roots.oops_do(&always_true, oops, worker_id);
 235 }
 236 
 237 void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
 238   assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
 239   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 240   ResourceMark rm;
 241 
 242   _serial_roots.oops_do(oops, worker_id);
 243   _thread_roots.threads_do(&tc_cl, worker_id);
 244 }
 245 
 246 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers,
 247                                                  ShenandoahPhaseTimings::Phase phase,
 248                                                  bool stw_roots_processing,
 249                                                  bool stw_class_unloading) :
 250   ShenandoahRootProcessor(phase),
 251   _serial_roots(phase),
 252   _vm_roots(phase),
 253   _cld_roots(phase),
 254   _thread_roots(phase, n_workers > 1),
 255   _serial_weak_roots(phase),
 256   _weak_roots(phase),
 257   _dedup_roots(phase),
 258   _code_roots(phase),
 259   _stw_roots_processing(stw_roots_processing),
 260   _stw_class_unloading(stw_class_unloading) {
 261 }
 262 
 263 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
 264   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
 265   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 266   CodeBlobToOopClosure* codes_cl = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 267                                    static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 268                                    static_cast<CodeBlobToOopClosure*>(&blobsCl);
 269   AlwaysTrueClosure always_true;
 270 
 271   _serial_roots.oops_do(oops, worker_id);
 272   _serial_weak_roots.weak_oops_do(oops, worker_id);
 273   if (_stw_roots_processing) {
 274     _vm_roots.oops_do<OopClosure>(oops, worker_id);
 275     _weak_roots.oops_do<OopClosure>(oops, worker_id);
 276     _dedup_roots.oops_do(&always_true, oops, worker_id);
 277   }
 278 
 279   if (_stw_class_unloading) {
 280     CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
 281     _cld_roots.cld_do(&clds, worker_id);
 282     _code_roots.code_blobs_do(codes_cl, worker_id);
 283     _thread_roots.oops_do(oops, NULL, worker_id);
 284   } else {
 285     _thread_roots.oops_do(oops, codes_cl, worker_id);
 286   }
 287 }
 288 
 289 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 290   ShenandoahRootProcessor(phase),
 291   _serial_roots(phase),
 292   _vm_roots(phase),
 293   _cld_roots(phase),
 294   _thread_roots(phase, n_workers > 1),
 295   _serial_weak_roots(phase),
 296   _weak_roots(phase),
 297   _dedup_roots(phase),
 298   _code_roots(phase) {
 299 }
 300 
 301 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
 302   ShenandoahRootProcessor(phase),
 303   _serial_roots(phase),
 304   _vm_roots(phase),
 305   _cld_roots(phase),
 306   _thread_roots(phase, n_workers > 1),
 307   _serial_weak_roots(phase),
 308   _weak_roots(phase),
 309   _dedup_roots(phase),
 310   _code_roots(phase) {
 311   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
 312 }
 313 
 314 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
 315   CodeBlobToOopClosure code_blob_cl(oops, CodeBlobToOopClosure::FixRelocations);
 316   ShenandoahCodeBlobAndDisarmClosure blobs_and_disarm_Cl(oops);
 317   CodeBlobToOopClosure* adjust_code_closure = ShenandoahConcurrentRoots::can_do_concurrent_class_unloading() ?
 318                                               static_cast<CodeBlobToOopClosure*>(&blobs_and_disarm_Cl) :
 319                                               static_cast<CodeBlobToOopClosure*>(&code_blob_cl);
 320   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
 321   AlwaysTrueClosure always_true;
 322 
 323   _serial_roots.oops_do(oops, worker_id);
 324   _vm_roots.oops_do(oops, worker_id);
 325 
 326   _thread_roots.oops_do(oops, NULL, worker_id);
 327   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
 328   _code_roots.code_blobs_do(adjust_code_closure, worker_id);
 329 
 330   _serial_weak_roots.weak_oops_do(oops, worker_id);
 331   _weak_roots.oops_do<OopClosure>(oops, worker_id);
 332   _dedup_roots.oops_do(&always_true, oops, worker_id);
 333 }
 334 
 335 ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
 336    ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
 337    _serial_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 338    _thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
 339    _vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 340    _cld_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 341    _serial_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 342    _weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
 343    _code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
 344  }
 345 
 346  void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
 347    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
 348    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
 349    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
 350    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
 351    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
 352    AlwaysTrueClosure always_true;
 353    ResourceMark rm;
 354 
 355    _serial_roots.oops_do(oops, 0);
 356    _vm_roots.oops_do(oops, 0);
 357    _cld_roots.cld_do(&clds, 0);
 358    _thread_roots.threads_do(&tc_cl, 0);
 359    _code_roots.code_blobs_do(&code, 0);
 360 
 361    _serial_weak_roots.weak_oops_do(oops, 0);
 362    _weak_roots.oops_do<OopClosure>(oops, 0);
 363    _dedup_roots.oops_do(&always_true, oops, 0);
 364  }