< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp

Print this page
rev 53282 : 8220546: Shenandoah Reports timing details for weak root processing
Reviewed-by: rkennke
   1 /*
   2  * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */


  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/classLoaderDataGraph.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "classfile/systemDictionary.hpp"
  29 #include "code/codeCache.hpp"
  30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
  31 #include "gc/shenandoah/shenandoahHeap.hpp"
  32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  33 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  34 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  35 #include "gc/shenandoah/shenandoahUtils.hpp"
  36 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  37 #include "gc/shared/weakProcessor.inline.hpp"
  38 #include "memory/allocation.inline.hpp"
  39 #include "memory/iterator.hpp"
  40 #include "memory/resourceArea.hpp"
  41 #include "runtime/thread.hpp"
  42 #include "services/management.hpp"
  43 


















  44 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
  45                                                  ShenandoahPhaseTimings::Phase phase) :
  46   _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
  47   _srs(n_workers),
  48   _par_state_string(StringTable::weak_storage()),
  49   _phase(phase),
  50   _coderoots_all_iterator(ShenandoahCodeRoots::iterator()),
  51   _weak_processor_task(n_workers)
  52 {

  53   heap->phase_timings()->record_workers_start(_phase);
  54 
  55   if (ShenandoahStringDedup::is_enabled()) {
  56     StringDedup::gc_prologue(false);
  57   }
  58 }
  59 
  60 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
  61   delete _process_strong_tasks;
  62   if (ShenandoahStringDedup::is_enabled()) {
  63     StringDedup::gc_epilogue();
  64   }
  65 











  66   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
  67 }
  68 












  69 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
  70   CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
  71   CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
  72 
  73   CodeCache::blobs_do(&blobs);
  74   ClassLoaderDataGraph::cld_do(&clds);
  75   Universe::oops_do(oops);
  76   Management::oops_do(oops);
  77   JvmtiExport::oops_do(oops);
  78   JNIHandles::oops_do(oops);
  79   WeakProcessor::oops_do(oops);
  80   ObjectSynchronizer::oops_do(oops);
  81   SystemDictionary::oops_do(oops);
  82   StringTable::oops_do(oops);
  83 
  84   if (ShenandoahStringDedup::is_enabled()) {
  85     ShenandoahStringDedup::oops_do_slow(oops);
  86   }
  87 
  88   // Do thread roots the last. This allows verification code to find


 177     Universe::oops_do(strong_roots);
 178   }
 179 
 180   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
 181     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
 182     JNIHandles::oops_do(strong_roots);
 183   }
 184   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Management_oops_do)) {
 185     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
 186     Management::oops_do(strong_roots);
 187   }
 188   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_jvmti_oops_do)) {
 189     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
 190     JvmtiExport::oops_do(strong_roots);
 191   }
 192   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
 193     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
 194     SystemDictionary::oops_do(strong_roots);
 195   }
 196   if (jni_weak_roots != NULL) {
 197       ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id);
 198       AlwaysTrueClosure always_true;
 199       _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots);

 200   }
 201 
 202   if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
 203     ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id);
 204   }
 205 
 206   {
 207     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
 208     if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
 209       ObjectSynchronizer::oops_do(strong_roots);
 210     }
 211   }
 212 
 213   // All threads execute the following. A specific chunk of buckets
 214   // from the StringTable are the individual tasks.
 215   if (weak_roots != NULL) {
 216     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
 217     StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
 218   }
 219 }


   1 /*
   2  * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.
   7  *
   8  * This code is distributed in the hope that it will be useful, but WITHOUT
   9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  11  * version 2 for more details (a copy is included in the LICENSE file that
  12  * accompanied this code).
  13  *
  14  * You should have received a copy of the GNU General Public License version
  15  * 2 along with this work; if not, write to the Free Software Foundation,
  16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  17  *
  18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  19  * or visit www.oracle.com if you need additional information or have any
  20  * questions.
  21  *
  22  */


  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/classLoaderDataGraph.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "classfile/systemDictionary.hpp"
  29 #include "code/codeCache.hpp"
  30 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
  31 #include "gc/shenandoah/shenandoahHeap.hpp"
  32 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
  33 #include "gc/shenandoah/shenandoahStringDedup.hpp"
  34 #include "gc/shenandoah/shenandoahTimingTracker.hpp"
  35 #include "gc/shenandoah/shenandoahUtils.hpp"
  36 #include "gc/shenandoah/shenandoahVMOperations.hpp"
  37 #include "gc/shared/weakProcessor.inline.hpp"
  38 #include "memory/allocation.inline.hpp"
  39 #include "memory/iterator.hpp"
  40 #include "memory/resourceArea.hpp"
  41 #include "runtime/thread.hpp"
  42 #include "services/management.hpp"
  43 
  44 struct PhaseMap {
  45   WeakProcessorPhases::Phase            _weak_processor_phase;
  46   ShenandoahPhaseTimings::GCParPhases   _shenandoah_phase;
  47 };
  48 
  49 static const struct PhaseMap phase_mapping[] = {
  50 #if INCLUDE_JVMTI
  51   {WeakProcessorPhases::jvmti,       ShenandoahPhaseTimings::JVMTIWeakRoots},
  52 #endif
  53 #if INCLUDE_JFR
  54   {WeakProcessorPhases::jfr,         ShenandoahPhaseTimings::JFRWeakRoots},
  55 #endif
  56   {WeakProcessorPhases::jni,         ShenandoahPhaseTimings::JNIWeakRoots},
  57   {WeakProcessorPhases::vm,          ShenandoahPhaseTimings::VMWeakRoots}
  58 };
  59 
  60 STATIC_ASSERT(sizeof(phase_mapping) / sizeof(PhaseMap) == WeakProcessorPhases::phase_count);
  61 
  62 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
  63                                                  ShenandoahPhaseTimings::Phase phase) :
  64   _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
  65   _srs(n_workers),
  66   _par_state_string(StringTable::weak_storage()),
  67   _phase(phase),
  68   _coderoots_all_iterator(ShenandoahCodeRoots::iterator()),
  69   _weak_processor_timings(n_workers),
  70   _weak_processor_task(&_weak_processor_timings, n_workers),
  71   _processed_weak_roots(false) {
  72   heap->phase_timings()->record_workers_start(_phase);
  73 
  74   if (ShenandoahStringDedup::is_enabled()) {
  75     StringDedup::gc_prologue(false);
  76   }
  77 }
  78 
  79 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
  80   delete _process_strong_tasks;
  81   if (ShenandoahStringDedup::is_enabled()) {
  82     StringDedup::gc_epilogue();
  83   }
  84 
  85   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
  86 
  87   if (_processed_weak_roots) {
  88     assert(_weak_processor_timings.max_threads() == n_workers(), "Must match");
  89     for (uint index = 0; index < WeakProcessorPhases::phase_count; index ++) {
  90       weak_processor_timing_to_shenandoah_timing(phase_mapping[index]._weak_processor_phase,
  91                                                  phase_mapping[index]._shenandoah_phase,
  92                                                  worker_times);
  93     }
  94   }
  95 
  96   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);
  97 }
  98 
  99 void ShenandoahRootProcessor::weak_processor_timing_to_shenandoah_timing(const WeakProcessorPhases::Phase wpp,
 100                                                                          const ShenandoahPhaseTimings::GCParPhases spp,
 101                                                                          ShenandoahWorkerTimings* worker_times) const {
 102   if (WeakProcessorPhases::is_serial(wpp)) {
 103     worker_times->record_time_secs(spp, 0, _weak_processor_timings.phase_time_sec(wpp));
 104   } else {
 105     for (uint index = 0; index < _weak_processor_timings.max_threads(); index ++) {
 106       worker_times->record_time_secs(spp, index, _weak_processor_timings.worker_time_sec(index, wpp));
 107     }
 108   }
 109 }
 110 
 111 void ShenandoahRootProcessor::process_all_roots_slow(OopClosure* oops) {
 112   CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
 113   CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
 114 
 115   CodeCache::blobs_do(&blobs);
 116   ClassLoaderDataGraph::cld_do(&clds);
 117   Universe::oops_do(oops);
 118   Management::oops_do(oops);
 119   JvmtiExport::oops_do(oops);
 120   JNIHandles::oops_do(oops);
 121   WeakProcessor::oops_do(oops);
 122   ObjectSynchronizer::oops_do(oops);
 123   SystemDictionary::oops_do(oops);
 124   StringTable::oops_do(oops);
 125 
 126   if (ShenandoahStringDedup::is_enabled()) {
 127     ShenandoahStringDedup::oops_do_slow(oops);
 128   }
 129 
 130   // Do thread roots the last. This allows verification code to find


 219     Universe::oops_do(strong_roots);
 220   }
 221 
 222   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
 223     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIRoots, worker_id);
 224     JNIHandles::oops_do(strong_roots);
 225   }
 226   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_Management_oops_do)) {
 227     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ManagementRoots, worker_id);
 228     Management::oops_do(strong_roots);
 229   }
 230   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_jvmti_oops_do)) {
 231     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JVMTIRoots, worker_id);
 232     JvmtiExport::oops_do(strong_roots);
 233   }
 234   if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
 235     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
 236     SystemDictionary::oops_do(strong_roots);
 237   }
 238   if (jni_weak_roots != NULL) {

 239     AlwaysTrueClosure always_true;
 240     _weak_processor_task.work<AlwaysTrueClosure, OopClosure>(worker_id, &always_true, jni_weak_roots);
 241     _processed_weak_roots = true;
 242   }
 243 
 244   if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
 245     ShenandoahStringDedup::parallel_oops_do(weak_roots, worker_id);
 246   }
 247 
 248   {
 249     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
 250     if (_process_strong_tasks->try_claim_task(SHENANDOAH_RP_PS_ObjectSynchronizer_oops_do)) {
 251       ObjectSynchronizer::oops_do(strong_roots);
 252     }
 253   }
 254 
 255   // All threads execute the following. A specific chunk of buckets
 256   // from the StringTable are the individual tasks.
 257   if (weak_roots != NULL) {
 258     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringTableRoots, worker_id);
 259     StringTable::possibly_parallel_oops_do(&_par_state_string, weak_roots);
 260   }
 261 }


< prev index next >