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
|