Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/concurrentMark.cpp @ 993:54b3b351d6f9
Merge
author | jrose |
---|---|
date | Wed, 23 Sep 2009 23:56:15 -0700 |
parents | 148e5441d916 e1fdf4fd34dc |
children | 035d2e036a9b |
comparison
equal
deleted
inserted
replaced
992:6a8ccac44f41 | 993:54b3b351d6f9 |
---|---|
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 |
877 checkpointRootsInitialPost(); | 863 checkpointRootsInitialPost(); |
878 | 864 |
879 // Statistics. | 865 // Statistics. |
880 double end = os::elapsedTime(); | 866 double end = os::elapsedTime(); |
881 _init_times.add((end - start) * 1000.0); | 867 _init_times.add((end - start) * 1000.0); |
882 GCOverheadReporter::recordSTWEnd(end); | |
883 | 868 |
884 g1p->record_concurrent_mark_init_end(); | 869 g1p->record_concurrent_mark_init_end(); |
885 } | 870 } |
886 | 871 |
887 /* | 872 /* |
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), |