src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54940 2d90a0988c95
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    25 
    25 
    26 #include "classfile/classLoaderDataGraph.hpp"
    26 #include "classfile/classLoaderDataGraph.hpp"
    27 #include "classfile/stringTable.hpp"
    27 #include "classfile/stringTable.hpp"
    28 #include "classfile/systemDictionary.hpp"
    28 #include "classfile/systemDictionary.hpp"
    29 #include "code/codeCache.hpp"
    29 #include "code/codeCache.hpp"
    30 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
       
    31 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
    30 #include "gc/shenandoah/shenandoahRootProcessor.inline.hpp"
    32 #include "gc/shenandoah/shenandoahHeap.hpp"
    31 #include "gc/shenandoah/shenandoahHeap.hpp"
    33 #include "gc/shenandoah/shenandoahHeuristics.hpp"
       
    34 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
    32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
    35 #include "gc/shenandoah/shenandoahStringDedup.hpp"
    33 #include "gc/shenandoah/shenandoahStringDedup.hpp"
    36 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
    34 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
    37 #include "gc/shenandoah/shenandoahUtils.hpp"
       
    38 #include "gc/shenandoah/shenandoahVMOperations.hpp"
    35 #include "gc/shenandoah/shenandoahVMOperations.hpp"
    39 #include "gc/shared/weakProcessor.inline.hpp"
    36 #include "jfr/jfr.hpp"
    40 #include "memory/allocation.inline.hpp"
       
    41 #include "memory/iterator.hpp"
    37 #include "memory/iterator.hpp"
    42 #include "memory/resourceArea.hpp"
    38 #include "memory/resourceArea.hpp"
    43 #include "memory/universe.hpp"
    39 #include "memory/universe.hpp"
    44 #include "runtime/thread.hpp"
    40 #include "runtime/thread.hpp"
    45 #include "services/management.hpp"
    41 #include "services/management.hpp"
    46 
    42 
    47 ShenandoahSerialRoot::ShenandoahSerialRoot(ShenandoahSerialRoot::OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases phase) :
    43 ShenandoahSerialRoot::ShenandoahSerialRoot(ShenandoahSerialRoot::OopsDo oops_do, ShenandoahPhaseTimings::GCParPhases phase) :
    48   _claimed(false), _oops_do(oops_do), _phase(phase) {
    44   _oops_do(oops_do), _phase(phase) {
    49 }
    45 }
    50 
    46 
    51 void ShenandoahSerialRoot::oops_do(OopClosure* cl, uint worker_id) {
    47 void ShenandoahSerialRoot::oops_do(OopClosure* cl, uint worker_id) {
    52   if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
    48   if (_claimed.try_set()) {
    53     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
    49     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
    54     ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
    50     ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
    55     _oops_do(cl);
    51     _oops_do(cl);
    56   }
    52   }
       
    53 }
       
    54 
       
    55 // Overwrite the second argument for SD::oops_do, don't include vm global oop storage.
       
    56 static void system_dictionary_oops_do(OopClosure* cl) {
       
    57   SystemDictionary::oops_do(cl, false);
    57 }
    58 }
    58 
    59 
    59 ShenandoahSerialRoots::ShenandoahSerialRoots() :
    60 ShenandoahSerialRoots::ShenandoahSerialRoots() :
    60   _universe_root(&Universe::oops_do, ShenandoahPhaseTimings::UniverseRoots),
    61   _universe_root(&Universe::oops_do, ShenandoahPhaseTimings::UniverseRoots),
    61   _object_synchronizer_root(&ObjectSynchronizer::oops_do, ShenandoahPhaseTimings::ObjectSynchronizerRoots),
    62   _object_synchronizer_root(&ObjectSynchronizer::oops_do, ShenandoahPhaseTimings::ObjectSynchronizerRoots),
    62   _management_root(&Management::oops_do, ShenandoahPhaseTimings::ManagementRoots),
    63   _management_root(&Management::oops_do, ShenandoahPhaseTimings::ManagementRoots),
    63   _system_dictionary_root(&SystemDictionary::oops_do, ShenandoahPhaseTimings::SystemDictionaryRoots),
    64   _system_dictionary_root(&system_dictionary_oops_do, ShenandoahPhaseTimings::SystemDictionaryRoots),
    64   _jvmti_root(&JvmtiExport::oops_do, ShenandoahPhaseTimings::JVMTIRoots),
    65   _jvmti_root(&JvmtiExport::oops_do, ShenandoahPhaseTimings::JVMTIRoots) {
    65   _jni_handle_root(&JNIHandles::oops_do, ShenandoahPhaseTimings::JNIRoots) {
       
    66 }
    66 }
    67 
    67 
    68 void ShenandoahSerialRoots::oops_do(OopClosure* cl, uint worker_id) {
    68 void ShenandoahSerialRoots::oops_do(OopClosure* cl, uint worker_id) {
    69   _universe_root.oops_do(cl, worker_id);
    69   _universe_root.oops_do(cl, worker_id);
    70   _object_synchronizer_root.oops_do(cl, worker_id);
    70   _object_synchronizer_root.oops_do(cl, worker_id);
    71   _management_root.oops_do(cl, worker_id);
    71   _management_root.oops_do(cl, worker_id);
    72   _system_dictionary_root.oops_do(cl, worker_id);
    72   _system_dictionary_root.oops_do(cl, worker_id);
    73   _jvmti_root.oops_do(cl, worker_id);
    73   _jvmti_root.oops_do(cl, worker_id);
    74   _jni_handle_root.oops_do(cl, worker_id);
    74 }
       
    75 
       
    76 ShenandoahWeakSerialRoot::ShenandoahWeakSerialRoot(ShenandoahWeakSerialRoot::WeakOopsDo weak_oops_do, ShenandoahPhaseTimings::GCParPhases phase) :
       
    77   _weak_oops_do(weak_oops_do), _phase(phase) {
       
    78 }
       
    79 
       
    80 void ShenandoahWeakSerialRoot::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
       
    81   if (_claimed.try_set()) {
       
    82     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
       
    83     ShenandoahWorkerTimingsTracker timer(worker_times, _phase, worker_id);
       
    84     _weak_oops_do(is_alive, keep_alive);
       
    85   }
       
    86 }
       
    87 
       
    88 #if INCLUDE_JVMTI
       
    89 ShenandoahJVMTIWeakRoot::ShenandoahJVMTIWeakRoot() :
       
    90   ShenandoahWeakSerialRoot(&JvmtiExport::weak_oops_do, ShenandoahPhaseTimings::JVMTIWeakRoots) {
       
    91 }
       
    92 #endif // INCLUDE_JVMTI
       
    93 
       
    94 #if INCLUDE_JFR
       
    95 ShenandoahJFRWeakRoot::ShenandoahJFRWeakRoot() :
       
    96   ShenandoahWeakSerialRoot(&Jfr::weak_oops_do, ShenandoahPhaseTimings::JFRWeakRoots) {
       
    97 }
       
    98 #endif // INCLUDE_JFR
       
    99 
       
   100 void ShenandoahSerialWeakRoots::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
       
   101   JVMTI_ONLY(_jvmti_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
       
   102   JFR_ONLY(_jfr_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
       
   103 }
       
   104 
       
   105 void ShenandoahSerialWeakRoots::weak_oops_do(OopClosure* cl, uint worker_id) {
       
   106   AlwaysTrueClosure always_true;
       
   107   weak_oops_do(&always_true, cl, worker_id);
    75 }
   108 }
    76 
   109 
    77 ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) {
   110 ShenandoahThreadRoots::ShenandoahThreadRoots(bool is_par) : _is_par(is_par) {
    78   Threads::change_thread_claim_token();
   111   Threads::change_thread_claim_token();
    79 }
   112 }
    94 
   127 
    95 ShenandoahThreadRoots::~ShenandoahThreadRoots() {
   128 ShenandoahThreadRoots::~ShenandoahThreadRoots() {
    96   Threads::assert_all_threads_claimed();
   129   Threads::assert_all_threads_claimed();
    97 }
   130 }
    98 
   131 
    99 ShenandoahWeakRoots::ShenandoahWeakRoots(uint n_workers) :
       
   100   _process_timings(n_workers),
       
   101   _task(&_process_timings, n_workers) {
       
   102 }
       
   103 
       
   104 ShenandoahWeakRoots::~ShenandoahWeakRoots() {
       
   105   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
       
   106   ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(&_process_timings,
       
   107                                                                          worker_times);
       
   108 }
       
   109 
       
   110 ShenandoahStringDedupRoots::ShenandoahStringDedupRoots() {
   132 ShenandoahStringDedupRoots::ShenandoahStringDedupRoots() {
   111   if (ShenandoahStringDedup::is_enabled()) {
   133   if (ShenandoahStringDedup::is_enabled()) {
   112     StringDedup::gc_prologue(false);
   134     StringDedup::gc_prologue(false);
   113   }
   135   }
   114 }
   136 }
   121 
   143 
   122 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
   144 void ShenandoahStringDedupRoots::oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
   123   if (ShenandoahStringDedup::is_enabled()) {
   145   if (ShenandoahStringDedup::is_enabled()) {
   124     ShenandoahStringDedup::parallel_oops_do(is_alive, keep_alive, worker_id);
   146     ShenandoahStringDedup::parallel_oops_do(is_alive, keep_alive, worker_id);
   125   }
   147   }
   126 }
       
   127 
       
   128 ShenandoahClassLoaderDataRoots::ShenandoahClassLoaderDataRoots() {
       
   129   ClassLoaderDataGraph::clear_claimed_marks();
       
   130 }
       
   131 
       
   132 void ShenandoahClassLoaderDataRoots::clds_do(CLDClosure* strong_clds, CLDClosure* weak_clds, uint worker_id) {
       
   133   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
       
   134   ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
       
   135   ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
       
   136 }
   148 }
   137 
   149 
   138 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
   150 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
   139   _heap(ShenandoahHeap::heap()),
   151   _heap(ShenandoahHeap::heap()),
   140   _phase(phase) {
   152   _phase(phase) {
   145 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
   157 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
   146   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
   158   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
   147   _heap->phase_timings()->record_workers_end(_phase);
   159   _heap->phase_timings()->record_workers_end(_phase);
   148 }
   160 }
   149 
   161 
   150 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
   162 ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool include_concurrent_roots) :
   151   ShenandoahRootProcessor(phase),
   163   ShenandoahRootProcessor(phase),
   152   _thread_roots(n_workers > 1),
   164   _thread_roots(n_workers > 1),
   153   _weak_roots(n_workers) {
   165   _include_concurrent_roots(include_concurrent_roots) {
   154 }
   166 }
   155 
   167 
   156 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
   168 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
   157   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
   169   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
   158   CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
       
   159   CLDToOopClosure* weak_clds = ShenandoahHeap::heap()->unload_classes() ? NULL : &clds;
       
   160 
       
   161   AlwaysTrueClosure always_true;
   170   AlwaysTrueClosure always_true;
   162 
   171 
   163   _serial_roots.oops_do(oops, worker_id);
   172   _serial_roots.oops_do(oops, worker_id);
       
   173   _serial_weak_roots.weak_oops_do(oops, worker_id);
       
   174   if (_include_concurrent_roots) {
       
   175     CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
       
   176     _vm_roots.oops_do<OopClosure>(oops, worker_id);
       
   177     _cld_roots.cld_do(&clds, worker_id);
       
   178     _weak_roots.oops_do<OopClosure>(oops, worker_id);
       
   179   }
   164 
   180 
   165   _thread_roots.oops_do(oops, NULL, worker_id);
   181   _thread_roots.oops_do(oops, NULL, worker_id);
   166   _cld_roots.clds_do(&clds, &clds, worker_id);
       
   167   _code_roots.code_blobs_do(&blobsCl, worker_id);
   182   _code_roots.code_blobs_do(&blobsCl, worker_id);
   168 
   183 
   169   _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id);
       
   170   _dedup_roots.oops_do(&always_true, oops, worker_id);
   184   _dedup_roots.oops_do(&always_true, oops, worker_id);
   171 }
   185 }
   172 
   186 
   173 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase, bool update_code_cache) :
   187 ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
   174   ShenandoahRootProcessor(phase),
   188   ShenandoahRootProcessor(phase),
   175   _thread_roots(n_workers > 1),
   189   _thread_roots(n_workers > 1) {
   176   _weak_roots(n_workers),
       
   177   _update_code_cache(update_code_cache) {
       
   178 }
   190 }
   179 
   191 
   180 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
   192 ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
   181   ShenandoahRootProcessor(phase),
   193   ShenandoahRootProcessor(phase),
   182   _thread_roots(n_workers > 1),
   194   _thread_roots(n_workers > 1) {
   183   _weak_roots(n_workers) {
       
   184   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
   195   assert(ShenandoahHeap::heap()->is_full_gc_in_progress(), "Full GC only");
   185 }
   196 }
   186 
   197 
   187 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
   198 void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
   188   CodeBlobToOopClosure adjust_code_closure(oops, CodeBlobToOopClosure::FixRelocations);
   199   CodeBlobToOopClosure adjust_code_closure(oops, CodeBlobToOopClosure::FixRelocations);
   189   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
   200   CLDToOopClosure adjust_cld_closure(oops, ClassLoaderData::_claim_strong);
   190   AlwaysTrueClosure always_true;
   201   AlwaysTrueClosure always_true;
   191 
   202 
   192   _serial_roots.oops_do(oops, worker_id);
   203   _serial_roots.oops_do(oops, worker_id);
       
   204   _vm_roots.oops_do(oops, worker_id);
   193 
   205 
   194   _thread_roots.oops_do(oops, NULL, worker_id);
   206   _thread_roots.oops_do(oops, NULL, worker_id);
   195   _cld_roots.clds_do(&adjust_cld_closure, NULL, worker_id);
   207   _cld_roots.cld_do(&adjust_cld_closure, worker_id);
   196   _code_roots.code_blobs_do(&adjust_code_closure, worker_id);
   208   _code_roots.code_blobs_do(&adjust_code_closure, worker_id);
   197 
   209 
   198   _weak_roots.oops_do<AlwaysTrueClosure, OopClosure>(&always_true, oops, worker_id);
   210   _serial_weak_roots.weak_oops_do(oops, worker_id);
       
   211   _weak_roots.oops_do<OopClosure>(oops, worker_id);
   199   _dedup_roots.oops_do(&always_true, oops, worker_id);
   212   _dedup_roots.oops_do(&always_true, oops, worker_id);
   200 }
   213 }
       
   214 
       
   215  ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
       
   216    ShenandoahRootProcessor(ShenandoahPhaseTimings::_num_phases),
       
   217    _thread_roots(false /*is par*/) {
       
   218  }
       
   219 
       
   220  void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
       
   221    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
       
   222    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
       
   223    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
       
   224    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
       
   225    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
       
   226    AlwaysTrueClosure always_true;
       
   227    ResourceMark rm;
       
   228 
       
   229    _serial_roots.oops_do(oops, 0);
       
   230    _vm_roots.oops_do(oops, 0);
       
   231    _cld_roots.cld_do(&clds, 0);
       
   232    _thread_roots.threads_do(&tc_cl, 0);
       
   233    _code_roots.code_blobs_do(&code, 0);
       
   234 
       
   235    _serial_weak_roots.weak_oops_do(oops, 0);
       
   236    _weak_roots.oops_do<OopClosure>(oops, 0);
       
   237    _dedup_roots.oops_do(&always_true, oops, 0);
       
   238  }
       
   239 
       
   240  void ShenandoahHeapIterationRootScanner::strong_roots_do(OopClosure* oops) {
       
   241    assert(Thread::current()->is_VM_thread(), "Only by VM thread");
       
   242    // Must use _claim_none to avoid interfering with concurrent CLDG iteration
       
   243    CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
       
   244    MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
       
   245    ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
       
   246    ResourceMark rm;
       
   247 
       
   248    _serial_roots.oops_do(oops, 0);
       
   249    _vm_roots.oops_do(oops, 0);
       
   250    _cld_roots.always_strong_cld_do(&clds, 0);
       
   251    _thread_roots.threads_do(&tc_cl, 0);
       
   252  }