431 _remark_times(), _remark_mark_times(), _remark_weak_ref_times(), |
431 _remark_times(), _remark_mark_times(), _remark_weak_ref_times(), |
432 _cleanup_times(), |
432 _cleanup_times(), |
433 _total_counting_time(0.0), |
433 _total_counting_time(0.0), |
434 _total_rs_scrub_time(0.0), |
434 _total_rs_scrub_time(0.0), |
435 |
435 |
436 _parallel_workers(NULL), |
436 _parallel_workers(NULL) |
437 _cleanup_co_tracker(G1CLGroup) |
|
438 { |
437 { |
439 CMVerboseLevel verbose_level = |
438 CMVerboseLevel verbose_level = |
440 (CMVerboseLevel) G1MarkingVerboseLevel; |
439 (CMVerboseLevel) G1MarkingVerboseLevel; |
441 if (verbose_level < no_verbose) |
440 if (verbose_level < no_verbose) |
442 verbose_level = no_verbose; |
441 verbose_level = no_verbose; |
822 |
821 |
823 // update_g1_committed() will be called at the end of an evac pause |
822 // update_g1_committed() will be called at the end of an evac pause |
824 // when marking is on. So, it's also called at the end of the |
823 // when marking is on. So, it's also called at the end of the |
825 // initial-mark pause to update the heap end, if the heap expands |
824 // initial-mark pause to update the heap end, if the heap expands |
826 // during it. No need to call it here. |
825 // during it. No need to call it here. |
827 |
|
828 guarantee( !_cleanup_co_tracker.enabled(), "invariant" ); |
|
829 |
|
830 size_t max_marking_threads = |
|
831 MAX2((size_t) 1, parallel_marking_threads()); |
|
832 for (int i = 0; i < (int)_max_task_num; ++i) { |
|
833 _tasks[i]->enable_co_tracker(); |
|
834 if (i < (int) max_marking_threads) |
|
835 _tasks[i]->reset_co_tracker(marking_task_overhead()); |
|
836 else |
|
837 _tasks[i]->reset_co_tracker(0.0); |
|
838 } |
|
839 } |
826 } |
840 |
827 |
841 // Checkpoint the roots into this generation from outside |
828 // Checkpoint the roots into this generation from outside |
842 // this generation. [Note this initial checkpoint need only |
829 // this generation. [Note this initial checkpoint need only |
843 // be approximate -- we'll do a catch up phase subsequently.] |
830 // be approximate -- we'll do a catch up phase subsequently.] |
844 void ConcurrentMark::checkpointRootsInitial() { |
831 void ConcurrentMark::checkpointRootsInitial() { |
845 assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped"); |
832 assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped"); |
846 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
833 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
847 |
834 |
848 double start = os::elapsedTime(); |
835 double start = os::elapsedTime(); |
849 GCOverheadReporter::recordSTWStart(start); |
|
850 |
836 |
851 G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); |
837 G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); |
852 g1p->record_concurrent_mark_init_start(); |
838 g1p->record_concurrent_mark_init_start(); |
853 checkpointRootsInitialPre(); |
839 checkpointRootsInitialPre(); |
854 |
840 |
1036 |
1021 |
1037 ConcurrentGCThread::stsJoin(); |
1022 ConcurrentGCThread::stsJoin(); |
1038 |
1023 |
1039 guarantee( (size_t)worker_i < _cm->active_tasks(), "invariant" ); |
1024 guarantee( (size_t)worker_i < _cm->active_tasks(), "invariant" ); |
1040 CMTask* the_task = _cm->task(worker_i); |
1025 CMTask* the_task = _cm->task(worker_i); |
1041 the_task->start_co_tracker(); |
|
1042 the_task->record_start_time(); |
1026 the_task->record_start_time(); |
1043 if (!_cm->has_aborted()) { |
1027 if (!_cm->has_aborted()) { |
1044 do { |
1028 do { |
1045 double start_vtime_sec = os::elapsedVTime(); |
1029 double start_vtime_sec = os::elapsedVTime(); |
1046 double start_time_sec = os::elapsedTime(); |
1030 double start_time_sec = os::elapsedTime(); |
1062 ConcurrentGCThread::stsJoin(); |
1046 ConcurrentGCThread::stsJoin(); |
1063 } |
1047 } |
1064 double end_time2_sec = os::elapsedTime(); |
1048 double end_time2_sec = os::elapsedTime(); |
1065 double elapsed_time2_sec = end_time2_sec - start_time_sec; |
1049 double elapsed_time2_sec = end_time2_sec - start_time_sec; |
1066 |
1050 |
1067 the_task->update_co_tracker(); |
|
1068 |
|
1069 #if 0 |
1051 #if 0 |
1070 gclog_or_tty->print_cr("CM: elapsed %1.4lf ms, sleep %1.4lf ms, " |
1052 gclog_or_tty->print_cr("CM: elapsed %1.4lf ms, sleep %1.4lf ms, " |
1071 "overhead %1.4lf", |
1053 "overhead %1.4lf", |
1072 elapsed_vtime_sec * 1000.0, (double) sleep_time_ms, |
1054 elapsed_vtime_sec * 1000.0, (double) sleep_time_ms, |
1073 the_task->conc_overhead(os::elapsedTime()) * 8.0); |
1055 the_task->conc_overhead(os::elapsedTime()) * 8.0); |
1080 guarantee( !the_task->has_aborted() || _cm->has_aborted(), "invariant" ); |
1062 guarantee( !the_task->has_aborted() || _cm->has_aborted(), "invariant" ); |
1081 |
1063 |
1082 ConcurrentGCThread::stsLeave(); |
1064 ConcurrentGCThread::stsLeave(); |
1083 |
1065 |
1084 double end_vtime = os::elapsedVTime(); |
1066 double end_vtime = os::elapsedVTime(); |
1085 the_task->update_co_tracker(true); |
|
1086 _cm->update_accum_task_vtime(worker_i, end_vtime - start_vtime); |
1067 _cm->update_accum_task_vtime(worker_i, end_vtime - start_vtime); |
1087 } |
1068 } |
1088 |
1069 |
1089 CMConcurrentMarkingTask(ConcurrentMark* cm, |
1070 CMConcurrentMarkingTask(ConcurrentMark* cm, |
1090 ConcurrentMarkThread* cmt) : |
1071 ConcurrentMarkThread* cmt) : |
1134 |
1115 |
1135 G1CollectorPolicy* g1p = g1h->g1_policy(); |
1116 G1CollectorPolicy* g1p = g1h->g1_policy(); |
1136 g1p->record_concurrent_mark_remark_start(); |
1117 g1p->record_concurrent_mark_remark_start(); |
1137 |
1118 |
1138 double start = os::elapsedTime(); |
1119 double start = os::elapsedTime(); |
1139 GCOverheadReporter::recordSTWStart(start); |
|
1140 |
1120 |
1141 checkpointRootsFinalWork(); |
1121 checkpointRootsFinalWork(); |
1142 |
1122 |
1143 double mark_work_end = os::elapsedTime(); |
1123 double mark_work_end = os::elapsedTime(); |
1144 |
1124 |
1174 double now = os::elapsedTime(); |
1154 double now = os::elapsedTime(); |
1175 _remark_mark_times.add((mark_work_end - start) * 1000.0); |
1155 _remark_mark_times.add((mark_work_end - start) * 1000.0); |
1176 _remark_weak_ref_times.add((now - mark_work_end) * 1000.0); |
1156 _remark_weak_ref_times.add((now - mark_work_end) * 1000.0); |
1177 _remark_times.add((now - start) * 1000.0); |
1157 _remark_times.add((now - start) * 1000.0); |
1178 |
1158 |
1179 GCOverheadReporter::recordSTWEnd(now); |
|
1180 for (int i = 0; i < (int)_max_task_num; ++i) |
|
1181 _tasks[i]->disable_co_tracker(); |
|
1182 _cleanup_co_tracker.enable(); |
|
1183 _cleanup_co_tracker.reset(cleanup_task_overhead()); |
|
1184 g1p->record_concurrent_mark_remark_end(); |
1159 g1p->record_concurrent_mark_remark_end(); |
1185 } |
1160 } |
1186 |
1161 |
1187 |
1162 |
1188 #define CARD_BM_TEST_MODE 0 |
1163 #define CARD_BM_TEST_MODE 0 |
1189 |
1164 |
1190 class CalcLiveObjectsClosure: public HeapRegionClosure { |
1165 class CalcLiveObjectsClosure: public HeapRegionClosure { |
1191 |
1166 |
1192 CMBitMapRO* _bm; |
1167 CMBitMapRO* _bm; |
1193 ConcurrentMark* _cm; |
1168 ConcurrentMark* _cm; |
1194 COTracker* _co_tracker; |
|
1195 bool _changed; |
1169 bool _changed; |
1196 bool _yield; |
1170 bool _yield; |
1197 size_t _words_done; |
1171 size_t _words_done; |
1198 size_t _tot_live; |
1172 size_t _tot_live; |
1199 size_t _tot_used; |
1173 size_t _tot_used; |
1217 } |
1191 } |
1218 |
1192 |
1219 public: |
1193 public: |
1220 CalcLiveObjectsClosure(bool final, |
1194 CalcLiveObjectsClosure(bool final, |
1221 CMBitMapRO *bm, ConcurrentMark *cm, |
1195 CMBitMapRO *bm, ConcurrentMark *cm, |
1222 BitMap* region_bm, BitMap* card_bm, |
1196 BitMap* region_bm, BitMap* card_bm) : |
1223 COTracker* co_tracker) : |
|
1224 _bm(bm), _cm(cm), _changed(false), _yield(true), |
1197 _bm(bm), _cm(cm), _changed(false), _yield(true), |
1225 _words_done(0), _tot_live(0), _tot_used(0), |
1198 _words_done(0), _tot_live(0), _tot_used(0), |
1226 _region_bm(region_bm), _card_bm(card_bm), |
1199 _region_bm(region_bm), _card_bm(card_bm),_final(final), |
1227 _final(final), _co_tracker(co_tracker), |
|
1228 _regions_done(0), _start_vtime_sec(0.0) |
1200 _regions_done(0), _start_vtime_sec(0.0) |
1229 { |
1201 { |
1230 _bottom_card_num = |
1202 _bottom_card_num = |
1231 intptr_t(uintptr_t(G1CollectedHeap::heap()->reserved_region().start()) >> |
1203 intptr_t(uintptr_t(G1CollectedHeap::heap()->reserved_region().start()) >> |
1232 CardTableModRefBS::card_shift); |
1204 CardTableModRefBS::card_shift); |
1266 (BitMap::idx_t) end_index, true); |
1238 (BitMap::idx_t) end_index, true); |
1267 } |
1239 } |
1268 } |
1240 } |
1269 |
1241 |
1270 bool doHeapRegion(HeapRegion* hr) { |
1242 bool doHeapRegion(HeapRegion* hr) { |
1271 if (_co_tracker != NULL) |
|
1272 _co_tracker->update(); |
|
1273 |
|
1274 if (!_final && _regions_done == 0) |
1243 if (!_final && _regions_done == 0) |
1275 _start_vtime_sec = os::elapsedVTime(); |
1244 _start_vtime_sec = os::elapsedVTime(); |
1276 |
1245 |
1277 if (hr->continuesHumongous()) { |
1246 if (hr->continuesHumongous()) { |
1278 // We will ignore these here and process them when their |
1247 // We will ignore these here and process them when their |
1397 double end_vtime_sec = os::elapsedVTime(); |
1366 double end_vtime_sec = os::elapsedVTime(); |
1398 double elapsed_vtime_sec = end_vtime_sec - _start_vtime_sec; |
1367 double elapsed_vtime_sec = end_vtime_sec - _start_vtime_sec; |
1399 if (elapsed_vtime_sec > (10.0 / 1000.0)) { |
1368 if (elapsed_vtime_sec > (10.0 / 1000.0)) { |
1400 jlong sleep_time_ms = |
1369 jlong sleep_time_ms = |
1401 (jlong) (elapsed_vtime_sec * _cm->cleanup_sleep_factor() * 1000.0); |
1370 (jlong) (elapsed_vtime_sec * _cm->cleanup_sleep_factor() * 1000.0); |
1402 #if 0 |
|
1403 gclog_or_tty->print_cr("CL: elapsed %1.4lf ms, sleep %1.4lf ms, " |
|
1404 "overhead %1.4lf", |
|
1405 elapsed_vtime_sec * 1000.0, (double) sleep_time_ms, |
|
1406 _co_tracker->concOverhead(os::elapsedTime())); |
|
1407 #endif |
|
1408 os::sleep(Thread::current(), sleep_time_ms, false); |
1371 os::sleep(Thread::current(), sleep_time_ms, false); |
1409 _start_vtime_sec = end_vtime_sec; |
1372 _start_vtime_sec = end_vtime_sec; |
1410 } |
1373 } |
1411 } |
1374 } |
1412 } |
1375 } |
1422 size_t tot_used() { return _tot_used; } |
1385 size_t tot_used() { return _tot_used; } |
1423 }; |
1386 }; |
1424 |
1387 |
1425 |
1388 |
1426 void ConcurrentMark::calcDesiredRegions() { |
1389 void ConcurrentMark::calcDesiredRegions() { |
1427 guarantee( _cleanup_co_tracker.enabled(), "invariant" ); |
|
1428 _cleanup_co_tracker.start(); |
|
1429 |
|
1430 _region_bm.clear(); |
1390 _region_bm.clear(); |
1431 _card_bm.clear(); |
1391 _card_bm.clear(); |
1432 CalcLiveObjectsClosure calccl(false /*final*/, |
1392 CalcLiveObjectsClosure calccl(false /*final*/, |
1433 nextMarkBitMap(), this, |
1393 nextMarkBitMap(), this, |
1434 &_region_bm, &_card_bm, |
1394 &_region_bm, &_card_bm); |
1435 &_cleanup_co_tracker); |
|
1436 G1CollectedHeap *g1h = G1CollectedHeap::heap(); |
1395 G1CollectedHeap *g1h = G1CollectedHeap::heap(); |
1437 g1h->heap_region_iterate(&calccl); |
1396 g1h->heap_region_iterate(&calccl); |
1438 |
1397 |
1439 do { |
1398 do { |
1440 calccl.reset(); |
1399 calccl.reset(); |
1441 g1h->heap_region_iterate(&calccl); |
1400 g1h->heap_region_iterate(&calccl); |
1442 } while (calccl.changed()); |
1401 } while (calccl.changed()); |
1443 |
|
1444 _cleanup_co_tracker.update(true); |
|
1445 } |
1402 } |
1446 |
1403 |
1447 class G1ParFinalCountTask: public AbstractGangTask { |
1404 class G1ParFinalCountTask: public AbstractGangTask { |
1448 protected: |
1405 protected: |
1449 G1CollectedHeap* _g1h; |
1406 G1CollectedHeap* _g1h; |
1473 } |
1430 } |
1474 |
1431 |
1475 void work(int i) { |
1432 void work(int i) { |
1476 CalcLiveObjectsClosure calccl(true /*final*/, |
1433 CalcLiveObjectsClosure calccl(true /*final*/, |
1477 _bm, _g1h->concurrent_mark(), |
1434 _bm, _g1h->concurrent_mark(), |
1478 _region_bm, _card_bm, |
1435 _region_bm, _card_bm); |
1479 NULL /* CO tracker */); |
|
1480 calccl.no_yield(); |
1436 calccl.no_yield(); |
1481 if (ParallelGCThreads > 0) { |
1437 if (ParallelGCThreads > 0) { |
1482 _g1h->heap_region_par_iterate_chunked(&calccl, i, |
1438 _g1h->heap_region_par_iterate_chunked(&calccl, i, |
1483 HeapRegion::FinalCountClaimValue); |
1439 HeapRegion::FinalCountClaimValue); |
1484 } else { |
1440 } else { |
1664 Universe::verify(/* allow dirty */ true, |
1620 Universe::verify(/* allow dirty */ true, |
1665 /* silent */ false, |
1621 /* silent */ false, |
1666 /* prev marking */ true); |
1622 /* prev marking */ true); |
1667 } |
1623 } |
1668 |
1624 |
1669 _cleanup_co_tracker.disable(); |
|
1670 |
|
1671 G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); |
1625 G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); |
1672 g1p->record_concurrent_mark_cleanup_start(); |
1626 g1p->record_concurrent_mark_cleanup_start(); |
1673 |
1627 |
1674 double start = os::elapsedTime(); |
1628 double start = os::elapsedTime(); |
1675 GCOverheadReporter::recordSTWStart(start); |
|
1676 |
1629 |
1677 // Do counting once more with the world stopped for good measure. |
1630 // Do counting once more with the world stopped for good measure. |
1678 G1ParFinalCountTask g1_par_count_task(g1h, nextMarkBitMap(), |
1631 G1ParFinalCountTask g1_par_count_task(g1h, nextMarkBitMap(), |
1679 &_region_bm, &_card_bm); |
1632 &_region_bm, &_card_bm); |
1680 if (ParallelGCThreads > 0) { |
1633 if (ParallelGCThreads > 0) { |
1775 g1_par_note_end_task.max_live_bytes()); |
1728 g1_par_note_end_task.max_live_bytes()); |
1776 |
1729 |
1777 // Statistics. |
1730 // Statistics. |
1778 double end = os::elapsedTime(); |
1731 double end = os::elapsedTime(); |
1779 _cleanup_times.add((end - start) * 1000.0); |
1732 _cleanup_times.add((end - start) * 1000.0); |
1780 GCOverheadReporter::recordSTWEnd(end); |
|
1781 |
1733 |
1782 // G1CollectedHeap::heap()->print(); |
1734 // G1CollectedHeap::heap()->print(); |
1783 // gclog_or_tty->print_cr("HEAP GC TIME STAMP : %d", |
1735 // gclog_or_tty->print_cr("HEAP GC TIME STAMP : %d", |
1784 // G1CollectedHeap::heap()->get_gc_time_stamp()); |
1736 // G1CollectedHeap::heap()->get_gc_time_stamp()); |
1785 |
1737 |
2624 return; |
2576 return; |
2625 |
2577 |
2626 HeapWord* region_end = hr->end(); |
2578 HeapWord* region_end = hr->end(); |
2627 if (region_end > _min_finger) |
2579 if (region_end > _min_finger) |
2628 _should_gray_objects = true; |
2580 _should_gray_objects = true; |
2629 } |
|
2630 |
|
2631 void ConcurrentMark::disable_co_trackers() { |
|
2632 if (has_aborted()) { |
|
2633 if (_cleanup_co_tracker.enabled()) |
|
2634 _cleanup_co_tracker.disable(); |
|
2635 for (int i = 0; i < (int)_max_task_num; ++i) { |
|
2636 CMTask* task = _tasks[i]; |
|
2637 if (task->co_tracker_enabled()) |
|
2638 task->disable_co_tracker(); |
|
2639 } |
|
2640 } else { |
|
2641 guarantee( !_cleanup_co_tracker.enabled(), "invariant" ); |
|
2642 for (int i = 0; i < (int)_max_task_num; ++i) { |
|
2643 CMTask* task = _tasks[i]; |
|
2644 guarantee( !task->co_tracker_enabled(), "invariant" ); |
|
2645 } |
|
2646 } |
|
2647 } |
2581 } |
2648 |
2582 |
2649 // abandon current marking iteration due to a Full GC |
2583 // abandon current marking iteration due to a Full GC |
2650 void ConcurrentMark::abort() { |
2584 void ConcurrentMark::abort() { |
2651 // Clear all marks to force marking thread to do nothing |
2585 // Clear all marks to force marking thread to do nothing |
4019 CMTask::CMTask(int task_id, |
3953 CMTask::CMTask(int task_id, |
4020 ConcurrentMark* cm, |
3954 ConcurrentMark* cm, |
4021 CMTaskQueue* task_queue, |
3955 CMTaskQueue* task_queue, |
4022 CMTaskQueueSet* task_queues) |
3956 CMTaskQueueSet* task_queues) |
4023 : _g1h(G1CollectedHeap::heap()), |
3957 : _g1h(G1CollectedHeap::heap()), |
4024 _co_tracker(G1CMGroup), |
|
4025 _task_id(task_id), _cm(cm), |
3958 _task_id(task_id), _cm(cm), |
4026 _claimed(false), |
3959 _claimed(false), |
4027 _nextMarkBitMap(NULL), _hash_seed(17), |
3960 _nextMarkBitMap(NULL), _hash_seed(17), |
4028 _task_queue(task_queue), |
3961 _task_queue(task_queue), |
4029 _task_queues(task_queues), |
3962 _task_queues(task_queues), |