< prev index next >

src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp

Print this page
rev 50281 : 8195097: Make it possible to process StringTable outside safepoint
Reviewed-by:


  37 #include "gc/cms/concurrentMarkSweepThread.hpp"
  38 #include "gc/cms/parNewGeneration.hpp"
  39 #include "gc/cms/promotionInfo.inline.hpp"
  40 #include "gc/cms/vmCMSOperations.hpp"
  41 #include "gc/serial/genMarkSweep.hpp"
  42 #include "gc/serial/tenuredGeneration.hpp"
  43 #include "gc/shared/adaptiveSizePolicy.hpp"
  44 #include "gc/shared/cardGeneration.inline.hpp"
  45 #include "gc/shared/cardTableRS.hpp"
  46 #include "gc/shared/collectedHeap.inline.hpp"
  47 #include "gc/shared/collectorCounters.hpp"
  48 #include "gc/shared/collectorPolicy.hpp"
  49 #include "gc/shared/gcLocker.hpp"
  50 #include "gc/shared/gcPolicyCounters.hpp"
  51 #include "gc/shared/gcTimer.hpp"
  52 #include "gc/shared/gcTrace.hpp"
  53 #include "gc/shared/gcTraceTime.inline.hpp"
  54 #include "gc/shared/genCollectedHeap.hpp"
  55 #include "gc/shared/genOopClosures.inline.hpp"
  56 #include "gc/shared/isGCActiveMark.hpp"

  57 #include "gc/shared/referencePolicy.hpp"
  58 #include "gc/shared/space.inline.hpp"
  59 #include "gc/shared/strongRootsScope.hpp"
  60 #include "gc/shared/taskqueue.inline.hpp"
  61 #include "gc/shared/weakProcessor.hpp"
  62 #include "logging/log.hpp"
  63 #include "logging/logStream.hpp"
  64 #include "memory/allocation.hpp"
  65 #include "memory/binaryTreeDictionary.inline.hpp"
  66 #include "memory/iterator.inline.hpp"
  67 #include "memory/padded.hpp"
  68 #include "memory/resourceArea.hpp"
  69 #include "oops/access.inline.hpp"
  70 #include "oops/oop.inline.hpp"
  71 #include "prims/jvmtiExport.hpp"
  72 #include "runtime/atomic.hpp"
  73 #include "runtime/flags/flagSetting.hpp"
  74 #include "runtime/globals_extension.hpp"
  75 #include "runtime/handles.inline.hpp"
  76 #include "runtime/java.hpp"


2752   _collector->resetYields();
2753   _collector->resetTimer();
2754   _collector->startTimer();
2755   _collector->gc_timer_cm()->register_gc_concurrent_start(title);
2756 }
2757 
2758 CMSPhaseAccounting::~CMSPhaseAccounting() {
2759   _collector->gc_timer_cm()->register_gc_concurrent_end();
2760   _collector->stopTimer();
2761   log_debug(gc)("Concurrent active time: %.3fms", TimeHelper::counter_to_seconds(_collector->timerTicks()));
2762   log_trace(gc)(" (CMS %s yielded %d times)", _title, _collector->yields());
2763 }
2764 
2765 // CMS work
2766 
2767 // The common parts of CMSParInitialMarkTask and CMSParRemarkTask.
2768 class CMSParMarkTask : public AbstractGangTask {
2769  protected:
2770   CMSCollector*     _collector;
2771   uint              _n_workers;

2772   CMSParMarkTask(const char* name, CMSCollector* collector, uint n_workers) :
2773       AbstractGangTask(name),
2774       _collector(collector),
2775       _n_workers(n_workers) {}

2776   // Work method in support of parallel rescan ... of young gen spaces
2777   void do_young_space_rescan(OopsInGenClosure* cl,
2778                              ContiguousSpace* space,
2779                              HeapWord** chunk_array, size_t chunk_top);
2780   void work_on_young_gen_roots(OopsInGenClosure* cl);
2781 };
2782 
2783 // Parallel initial mark task
2784 class CMSParInitialMarkTask: public CMSParMarkTask {
2785   StrongRootsScope* _strong_roots_scope;
2786  public:
2787   CMSParInitialMarkTask(CMSCollector* collector, StrongRootsScope* strong_roots_scope, uint n_workers) :
2788       CMSParMarkTask("Scan roots and young gen for initial mark in parallel", collector, n_workers),
2789       _strong_roots_scope(strong_roots_scope) {}
2790   void work(uint worker_id);
2791 };
2792 
2793 // Checkpoint the roots into this generation from outside
2794 // this generation. [Note this initial checkpoint need only
2795 // be approximate -- we'll do a catch up phase subsequently.]


4257   ParMarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
4258 
4259   // ---------- young gen roots --------------
4260   {
4261     work_on_young_gen_roots(&par_mri_cl);
4262     _timer.stop();
4263     log_trace(gc, task)("Finished young gen initial mark scan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
4264   }
4265 
4266   // ---------- remaining roots --------------
4267   _timer.reset();
4268   _timer.start();
4269 
4270   CLDToOopClosure cld_closure(&par_mri_cl, true);
4271 
4272   heap->cms_process_roots(_strong_roots_scope,
4273                           false,     // yg was scanned above
4274                           GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
4275                           _collector->should_unload_classes(),
4276                           &par_mri_cl,
4277                           &cld_closure);


4278   assert(_collector->should_unload_classes()
4279          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
4280          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
4281   _timer.stop();
4282   log_trace(gc, task)("Finished remaining root initial mark scan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
4283 }
4284 
4285 // Parallel remark task
4286 class CMSParRemarkTask: public CMSParMarkTask {
4287   CompactibleFreeListSpace* _cms_space;
4288 
4289   // The per-thread work queues, available here for stealing.
4290   OopTaskQueueSet*       _task_queues;
4291   ParallelTaskTerminator _term;
4292   StrongRootsScope*      _strong_roots_scope;
4293 
4294  public:
4295   // A value of 0 passed to n_workers will cause the number of
4296   // workers to be taken from the active workers in the work gang.
4297   CMSParRemarkTask(CMSCollector* collector,


4386 
4387   // Rescan young gen roots first since these are likely
4388   // coarsely partitioned and may, on that account, constitute
4389   // the critical path; thus, it's best to start off that
4390   // work first.
4391   // ---------- young gen roots --------------
4392   {
4393     work_on_young_gen_roots(&par_mrias_cl);
4394     _timer.stop();
4395     log_trace(gc, task)("Finished young gen rescan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
4396   }
4397 
4398   // ---------- remaining roots --------------
4399   _timer.reset();
4400   _timer.start();
4401   heap->cms_process_roots(_strong_roots_scope,
4402                           false,     // yg was scanned above
4403                           GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
4404                           _collector->should_unload_classes(),
4405                           &par_mrias_cl,
4406                           NULL);     // The dirty klasses will be handled below

4407 
4408   assert(_collector->should_unload_classes()
4409          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
4410          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
4411   _timer.stop();
4412   log_trace(gc, task)("Finished remaining root rescan work in %dth thread: %3.3f sec",  worker_id, _timer.seconds());
4413 
4414   // ---------- unhandled CLD scanning ----------
4415   if (worker_id == 0) { // Single threaded at the moment.
4416     _timer.reset();
4417     _timer.start();
4418 
4419     // Scan all new class loader data objects and new dependencies that were
4420     // introduced during concurrent marking.
4421     ResourceMark rm;
4422     GrowableArray<ClassLoaderData*>* array = ClassLoaderDataGraph::new_clds();
4423     for (int i = 0; i < array->length(); i++) {
4424       par_mrias_cl.do_cld_nv(array->at(i));
4425     }
4426 




  37 #include "gc/cms/concurrentMarkSweepThread.hpp"
  38 #include "gc/cms/parNewGeneration.hpp"
  39 #include "gc/cms/promotionInfo.inline.hpp"
  40 #include "gc/cms/vmCMSOperations.hpp"
  41 #include "gc/serial/genMarkSweep.hpp"
  42 #include "gc/serial/tenuredGeneration.hpp"
  43 #include "gc/shared/adaptiveSizePolicy.hpp"
  44 #include "gc/shared/cardGeneration.inline.hpp"
  45 #include "gc/shared/cardTableRS.hpp"
  46 #include "gc/shared/collectedHeap.inline.hpp"
  47 #include "gc/shared/collectorCounters.hpp"
  48 #include "gc/shared/collectorPolicy.hpp"
  49 #include "gc/shared/gcLocker.hpp"
  50 #include "gc/shared/gcPolicyCounters.hpp"
  51 #include "gc/shared/gcTimer.hpp"
  52 #include "gc/shared/gcTrace.hpp"
  53 #include "gc/shared/gcTraceTime.inline.hpp"
  54 #include "gc/shared/genCollectedHeap.hpp"
  55 #include "gc/shared/genOopClosures.inline.hpp"
  56 #include "gc/shared/isGCActiveMark.hpp"
  57 #include "gc/shared/oopStorageParState.hpp"
  58 #include "gc/shared/referencePolicy.hpp"
  59 #include "gc/shared/space.inline.hpp"
  60 #include "gc/shared/strongRootsScope.hpp"
  61 #include "gc/shared/taskqueue.inline.hpp"
  62 #include "gc/shared/weakProcessor.hpp"
  63 #include "logging/log.hpp"
  64 #include "logging/logStream.hpp"
  65 #include "memory/allocation.hpp"
  66 #include "memory/binaryTreeDictionary.inline.hpp"
  67 #include "memory/iterator.inline.hpp"
  68 #include "memory/padded.hpp"
  69 #include "memory/resourceArea.hpp"
  70 #include "oops/access.inline.hpp"
  71 #include "oops/oop.inline.hpp"
  72 #include "prims/jvmtiExport.hpp"
  73 #include "runtime/atomic.hpp"
  74 #include "runtime/flags/flagSetting.hpp"
  75 #include "runtime/globals_extension.hpp"
  76 #include "runtime/handles.inline.hpp"
  77 #include "runtime/java.hpp"


2753   _collector->resetYields();
2754   _collector->resetTimer();
2755   _collector->startTimer();
2756   _collector->gc_timer_cm()->register_gc_concurrent_start(title);
2757 }
2758 
2759 CMSPhaseAccounting::~CMSPhaseAccounting() {
2760   _collector->gc_timer_cm()->register_gc_concurrent_end();
2761   _collector->stopTimer();
2762   log_debug(gc)("Concurrent active time: %.3fms", TimeHelper::counter_to_seconds(_collector->timerTicks()));
2763   log_trace(gc)(" (CMS %s yielded %d times)", _title, _collector->yields());
2764 }
2765 
2766 // CMS work
2767 
2768 // The common parts of CMSParInitialMarkTask and CMSParRemarkTask.
2769 class CMSParMarkTask : public AbstractGangTask {
2770  protected:
2771   CMSCollector*     _collector;
2772   uint              _n_workers;
2773   OopStorage::ParState<false, false> _par_state_string;
2774   CMSParMarkTask(const char* name, CMSCollector* collector, uint n_workers) :
2775       AbstractGangTask(name),
2776       _collector(collector),
2777       _n_workers(n_workers),
2778       _par_state_string(StringTable::weak_storage()) {}
2779   // Work method in support of parallel rescan ... of young gen spaces
2780   void do_young_space_rescan(OopsInGenClosure* cl,
2781                              ContiguousSpace* space,
2782                              HeapWord** chunk_array, size_t chunk_top);
2783   void work_on_young_gen_roots(OopsInGenClosure* cl);
2784 };
2785 
2786 // Parallel initial mark task
2787 class CMSParInitialMarkTask: public CMSParMarkTask {
2788   StrongRootsScope* _strong_roots_scope;
2789  public:
2790   CMSParInitialMarkTask(CMSCollector* collector, StrongRootsScope* strong_roots_scope, uint n_workers) :
2791       CMSParMarkTask("Scan roots and young gen for initial mark in parallel", collector, n_workers),
2792       _strong_roots_scope(strong_roots_scope) {}
2793   void work(uint worker_id);
2794 };
2795 
2796 // Checkpoint the roots into this generation from outside
2797 // this generation. [Note this initial checkpoint need only
2798 // be approximate -- we'll do a catch up phase subsequently.]


4260   ParMarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
4261 
4262   // ---------- young gen roots --------------
4263   {
4264     work_on_young_gen_roots(&par_mri_cl);
4265     _timer.stop();
4266     log_trace(gc, task)("Finished young gen initial mark scan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
4267   }
4268 
4269   // ---------- remaining roots --------------
4270   _timer.reset();
4271   _timer.start();
4272 
4273   CLDToOopClosure cld_closure(&par_mri_cl, true);
4274 
4275   heap->cms_process_roots(_strong_roots_scope,
4276                           false,     // yg was scanned above
4277                           GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
4278                           _collector->should_unload_classes(),
4279                           &par_mri_cl,
4280                           &cld_closure,
4281                           &_par_state_string);
4282 
4283   assert(_collector->should_unload_classes()
4284          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
4285          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
4286   _timer.stop();
4287   log_trace(gc, task)("Finished remaining root initial mark scan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
4288 }
4289 
4290 // Parallel remark task
4291 class CMSParRemarkTask: public CMSParMarkTask {
4292   CompactibleFreeListSpace* _cms_space;
4293 
4294   // The per-thread work queues, available here for stealing.
4295   OopTaskQueueSet*       _task_queues;
4296   ParallelTaskTerminator _term;
4297   StrongRootsScope*      _strong_roots_scope;
4298 
4299  public:
4300   // A value of 0 passed to n_workers will cause the number of
4301   // workers to be taken from the active workers in the work gang.
4302   CMSParRemarkTask(CMSCollector* collector,


4391 
4392   // Rescan young gen roots first since these are likely
4393   // coarsely partitioned and may, on that account, constitute
4394   // the critical path; thus, it's best to start off that
4395   // work first.
4396   // ---------- young gen roots --------------
4397   {
4398     work_on_young_gen_roots(&par_mrias_cl);
4399     _timer.stop();
4400     log_trace(gc, task)("Finished young gen rescan work in %dth thread: %3.3f sec", worker_id, _timer.seconds());
4401   }
4402 
4403   // ---------- remaining roots --------------
4404   _timer.reset();
4405   _timer.start();
4406   heap->cms_process_roots(_strong_roots_scope,
4407                           false,     // yg was scanned above
4408                           GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
4409                           _collector->should_unload_classes(),
4410                           &par_mrias_cl,
4411                           NULL,     // The dirty klasses will be handled below
4412                           &_par_state_string);
4413 
4414   assert(_collector->should_unload_classes()
4415          || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache),
4416          "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
4417   _timer.stop();
4418   log_trace(gc, task)("Finished remaining root rescan work in %dth thread: %3.3f sec",  worker_id, _timer.seconds());
4419 
4420   // ---------- unhandled CLD scanning ----------
4421   if (worker_id == 0) { // Single threaded at the moment.
4422     _timer.reset();
4423     _timer.start();
4424 
4425     // Scan all new class loader data objects and new dependencies that were
4426     // introduced during concurrent marking.
4427     ResourceMark rm;
4428     GrowableArray<ClassLoaderData*>* array = ClassLoaderDataGraph::new_clds();
4429     for (int i = 0; i < array->length(); i++) {
4430       par_mrias_cl.do_cld_nv(array->at(i));
4431     }
4432 


< prev index next >