< prev index next >

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

Print this page
rev 13387 : [mq]: parallel_sp_cleaning.patch


  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  */
  23 
  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/stringTable.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
  30 #include "gc/shenandoah/shenandoahHeap.hpp"
  31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  32 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  33 #include "gc/shenandoah/shenandoahPhaseTimes.hpp"

  34 #include "memory/allocation.inline.hpp"
  35 #include "runtime/fprofiler.hpp"
  36 #include "runtime/mutex.hpp"

  37 #include "services/management.hpp"
  38 
  39 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
  40                                                  ShenandoahCollectorPolicy::TimingPhase phase) :
  41   _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
  42   _srs(n_workers),
  43   _phase(phase),
  44   _codecache_iterator(CodeCache::parallel_iterator()),
  45   _om_iterator(ObjectSynchronizer::parallel_iterator())

  46 {
  47   heap->shenandoahPolicy()->record_workers_start(_phase);




  48 }
  49 
  50 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
  51   delete _process_strong_tasks;
  52   ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);


  53 }
  54 
  55 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
  56                                                    OopClosure* weak_oops,
  57                                                    CLDClosure* clds,
  58                                                    CodeBlobClosure* blobs,
  59                                                    uint worker_id) {
  60 
  61   process_java_roots(oops, clds, NULL, blobs, worker_id);
  62   process_vm_roots(oops, NULL, weak_oops, worker_id);
  63 
  64   _process_strong_tasks->all_tasks_completed(n_workers());
  65 }
  66 
  67 void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,
  68                                                 OopClosure* weak_oops,
  69                                                 CLDClosure* clds,
  70                                                 CodeBlobClosure* blobs,
  71                                                 uint worker_id) {
  72 
  73   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
  74   process_java_roots(oops, clds, clds, NULL, worker_id);
  75   process_vm_roots(oops, oops, weak_oops, worker_id);
  76 
  77   if (blobs != NULL) {
  78     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
  79     _codecache_iterator.parallel_blobs_do(blobs);
  80   }
  81 
  82   _process_strong_tasks->all_tasks_completed(n_workers());
  83 }
  84 
  85 void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,
  86                                                  CLDClosure* strong_clds,
  87                                                  CLDClosure* weak_clds,
  88                                                  CodeBlobClosure* strong_code,

  89                                                  uint worker_id)
  90 {
  91   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
  92   // Iterating over the CLDG and the Threads are done early to allow us to
  93   // first process the strong CLDs and nmethods and then, after a barrier,
  94   // let the thread process the weak CLDs and nmethods.
  95   {
  96     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CLDGRoots, worker_id);
  97     _cld_iterator.root_cld_do(strong_clds, weak_clds);
  98   }
  99 
 100   {
 101     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
 102     bool is_par = n_workers() > 1;
 103     ResourceMark rm;
 104     Threads::possibly_parallel_oops_do(is_par, strong_roots, strong_code);
 105   }
 106 }
 107 
 108 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
 109                                                OopClosure* weak_roots,
 110                                                OopClosure* jni_weak_roots,
 111                                                uint worker_id)
 112 {
 113   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
 114   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
 115     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::UniverseRoots, worker_id);
 116     Universe::oops_do(strong_roots);
 117   }
 118 
 119   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
 120     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::JNIRoots, worker_id);
 121     JNIHandles::oops_do(strong_roots);
 122   }
 123 
 124   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_FlatProfiler_oops_do)) {


 153       while(_om_iterator.parallel_oops_do(strong_roots));
 154     }
 155   }
 156 
 157   // All threads execute the following. A specific chunk of buckets
 158   // from the StringTable are the individual tasks.
 159   if (weak_roots != NULL) {
 160     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::StringTableRoots, worker_id);
 161     StringTable::possibly_parallel_oops_do(weak_roots);
 162   }
 163 }
 164 
 165 uint ShenandoahRootProcessor::n_workers() const {
 166   return _srs.n_threads();
 167 }
 168 
 169 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahCollectorPolicy::TimingPhase phase) :
 170   _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
 171   _srs(n_workers),
 172   _phase(phase),
 173   _codecache_iterator(CodeCache::parallel_iterator())

 174 {
 175   heap->shenandoahPolicy()->record_workers_start(_phase);




 176 }
 177 
 178 ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
 179   delete _process_strong_tasks;
 180   ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);


 181 }
 182 
 183 void ShenandoahRootEvacuator::process_evacuate_roots(OopClosure* oops,
 184                                                      CodeBlobClosure* blobs,
 185                                                      uint worker_id) {
 186 
 187   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
 188   {
 189     bool is_par = n_workers() > 1;
 190     ResourceMark rm;
 191     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
 192     Threads::possibly_parallel_oops_do(is_par, oops, NULL);

 193   }
 194 
 195   {
 196     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
 197     _codecache_iterator.parallel_blobs_do(blobs);
 198   }
 199 
 200   _process_strong_tasks->all_tasks_completed(n_workers());
 201 }
 202 
 203 uint ShenandoahRootEvacuator::n_workers() const {
 204   return _srs.n_threads();
 205 }
 206 
 207 // Implemenation of ParallelCLDRootIterator
 208 ParallelCLDRootIterator::ParallelCLDRootIterator() {
 209   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 210   ClassLoaderDataGraph::clear_claimed_marks();
 211 }
 212 


  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  */
  23 
  24 #include "precompiled.hpp"
  25 
  26 #include "classfile/stringTable.hpp"
  27 #include "classfile/systemDictionary.hpp"
  28 #include "code/codeCache.hpp"
  29 #include "gc/shenandoah/shenandoahRootProcessor.hpp"
  30 #include "gc/shenandoah/shenandoahHeap.hpp"
  31 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
  32 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
  33 #include "gc/shenandoah/shenandoahPhaseTimes.hpp"
  34 #include "gc/shenandoah/vm_operations_shenandoah.hpp"
  35 #include "memory/allocation.inline.hpp"
  36 #include "runtime/fprofiler.hpp"
  37 #include "runtime/mutex.hpp"
  38 #include "runtime/sweeper.hpp"
  39 #include "services/management.hpp"
  40 
  41 ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahHeap* heap, uint n_workers,
  42                                                  ShenandoahCollectorPolicy::TimingPhase phase) :
  43   _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
  44   _srs(n_workers),
  45   _phase(phase),
  46   _codecache_iterator(CodeCache::parallel_iterator()),
  47   _om_iterator(ObjectSynchronizer::parallel_iterator()),
  48   _threads_nmethods_cl(NULL)
  49 {
  50   heap->shenandoahPolicy()->record_workers_start(_phase);
  51   VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
  52   if (! op->_safepoint_cleanup_done) {
  53     _threads_nmethods_cl = NMethodSweeper::prepare_mark_active_nmethods();
  54   }
  55 }
  56 
  57 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
  58   delete _process_strong_tasks;
  59   ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);
  60   VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
  61   op->_safepoint_cleanup_done = true;
  62 }
  63 
  64 void ShenandoahRootProcessor::process_strong_roots(OopClosure* oops,
  65                                                    OopClosure* weak_oops,
  66                                                    CLDClosure* clds,
  67                                                    CodeBlobClosure* blobs,
  68                                                    uint worker_id) {
  69 
  70   process_java_roots(oops, clds, NULL, NULL, _threads_nmethods_cl, worker_id);
  71   process_vm_roots(oops, NULL, weak_oops, worker_id);
  72 
  73   _process_strong_tasks->all_tasks_completed(n_workers());
  74 }
  75 
  76 void ShenandoahRootProcessor::process_all_roots(OopClosure* oops,
  77                                                 OopClosure* weak_oops,
  78                                                 CLDClosure* clds,
  79                                                 CodeBlobClosure* blobs,
  80                                                 uint worker_id) {
  81 
  82   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
  83   process_java_roots(oops, clds, clds, blobs, _threads_nmethods_cl, worker_id);
  84   process_vm_roots(oops, oops, weak_oops, worker_id);
  85 
  86   if (blobs != NULL) {
  87     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
  88     _codecache_iterator.parallel_blobs_do(blobs);
  89   }
  90 
  91   _process_strong_tasks->all_tasks_completed(n_workers());
  92 }
  93 
  94 void ShenandoahRootProcessor::process_java_roots(OopClosure* strong_roots,
  95                                                  CLDClosure* strong_clds,
  96                                                  CLDClosure* weak_clds,
  97                                                  CodeBlobClosure* strong_code,
  98                                                  CodeBlobClosure* nmethods_cl,
  99                                                  uint worker_id)
 100 {
 101   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
 102   // Iterating over the CLDG and the Threads are done early to allow us to
 103   // first process the strong CLDs and nmethods and then, after a barrier,
 104   // let the thread process the weak CLDs and nmethods.
 105   {
 106     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CLDGRoots, worker_id);
 107     _cld_iterator.root_cld_do(strong_clds, weak_clds);
 108   }
 109 
 110   {
 111     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
 112     bool is_par = n_workers() > 1;
 113     ResourceMark rm;
 114     Threads::possibly_parallel_oops_do(is_par, strong_roots, strong_code, nmethods_cl);
 115   }
 116 }
 117 
 118 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
 119                                                OopClosure* weak_roots,
 120                                                OopClosure* jni_weak_roots,
 121                                                uint worker_id)
 122 {
 123   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
 124   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
 125     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::UniverseRoots, worker_id);
 126     Universe::oops_do(strong_roots);
 127   }
 128 
 129   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_oops_do)) {
 130     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::JNIRoots, worker_id);
 131     JNIHandles::oops_do(strong_roots);
 132   }
 133 
 134   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_FlatProfiler_oops_do)) {


 163       while(_om_iterator.parallel_oops_do(strong_roots));
 164     }
 165   }
 166 
 167   // All threads execute the following. A specific chunk of buckets
 168   // from the StringTable are the individual tasks.
 169   if (weak_roots != NULL) {
 170     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::StringTableRoots, worker_id);
 171     StringTable::possibly_parallel_oops_do(weak_roots);
 172   }
 173 }
 174 
 175 uint ShenandoahRootProcessor::n_workers() const {
 176   return _srs.n_threads();
 177 }
 178 
 179 ShenandoahRootEvacuator::ShenandoahRootEvacuator(ShenandoahHeap* heap, uint n_workers, ShenandoahCollectorPolicy::TimingPhase phase) :
 180   _process_strong_tasks(new SubTasksDone(SHENANDOAH_RP_PS_NumElements)),
 181   _srs(n_workers),
 182   _phase(phase),
 183   _codecache_iterator(CodeCache::parallel_iterator()),
 184   _threads_nmethods_cl(NULL)
 185 {
 186   heap->shenandoahPolicy()->record_workers_start(_phase);
 187   VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
 188   if (! op->_safepoint_cleanup_done) {
 189     _threads_nmethods_cl = NMethodSweeper::prepare_mark_active_nmethods();
 190   }
 191 }
 192 
 193 ShenandoahRootEvacuator::~ShenandoahRootEvacuator() {
 194   delete _process_strong_tasks;
 195   ShenandoahHeap::heap()->shenandoahPolicy()->record_workers_end(_phase);
 196   VM_ShenandoahOperation* op = (VM_ShenandoahOperation*) VMThread::vm_operation();
 197   op->_safepoint_cleanup_done = true;
 198 }
 199 
 200 void ShenandoahRootEvacuator::process_evacuate_roots(OopClosure* oops,
 201                                                      CodeBlobClosure* blobs,
 202                                                      uint worker_id) {
 203 
 204   ShenandoahPhaseTimes* phase_times = ShenandoahHeap::heap()->shenandoahPolicy()->phase_times();
 205   {
 206     bool is_par = n_workers() > 1;
 207     ResourceMark rm;
 208     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::ThreadRoots, worker_id);
 209 
 210     Threads::possibly_parallel_oops_do(is_par, oops, NULL, _threads_nmethods_cl);
 211   }
 212 
 213   {
 214     ShenandoahParPhaseTimesTracker timer(phase_times, ShenandoahPhaseTimes::CodeCacheRoots, worker_id);
 215     _codecache_iterator.parallel_blobs_do(blobs);
 216   }
 217 
 218   _process_strong_tasks->all_tasks_completed(n_workers());
 219 }
 220 
 221 uint ShenandoahRootEvacuator::n_workers() const {
 222   return _srs.n_threads();
 223 }
 224 
 225 // Implemenation of ParallelCLDRootIterator
 226 ParallelCLDRootIterator::ParallelCLDRootIterator() {
 227   assert(SafepointSynchronize::is_at_safepoint(), "Must at safepoint");
 228   ClassLoaderDataGraph::clear_claimed_marks();
 229 }
 230 
< prev index next >