src/share/vm/gc_implementation/g1/concurrentMark.cpp

changeset 2472
0fa27f37d4d4
parent 2469
7e37af9d69ef
child 2493
97ba643ea3ed
child 2494
234761c55641
equal deleted inserted replaced
2471:cb913d743d09 2472:0fa27f37d4d4
456 _parallel_marking_threads(0), 456 _parallel_marking_threads(0),
457 _sleep_factor(0.0), 457 _sleep_factor(0.0),
458 _marking_task_overhead(1.0), 458 _marking_task_overhead(1.0),
459 _cleanup_sleep_factor(0.0), 459 _cleanup_sleep_factor(0.0),
460 _cleanup_task_overhead(1.0), 460 _cleanup_task_overhead(1.0),
461 _cleanup_list("Cleanup List"),
461 _region_bm(max_regions, false /* in_resource_area*/), 462 _region_bm(max_regions, false /* in_resource_area*/),
462 _card_bm((rs.size() + CardTableModRefBS::card_size - 1) >> 463 _card_bm((rs.size() + CardTableModRefBS::card_size - 1) >>
463 CardTableModRefBS::card_shift, 464 CardTableModRefBS::card_shift,
464 false /* in_resource_area*/), 465 false /* in_resource_area*/),
465 _prevMarkBitMap(&_markBitMap1), 466 _prevMarkBitMap(&_markBitMap1),
518 assert(_markBitMap1.covers(rs), "_markBitMap1 inconsistency"); 519 assert(_markBitMap1.covers(rs), "_markBitMap1 inconsistency");
519 assert(_markBitMap2.covers(rs), "_markBitMap2 inconsistency"); 520 assert(_markBitMap2.covers(rs), "_markBitMap2 inconsistency");
520 521
521 SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set(); 522 SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
522 satb_qs.set_buffer_size(G1SATBBufferSize); 523 satb_qs.set_buffer_size(G1SATBBufferSize);
523
524 int size = (int) MAX2(ParallelGCThreads, (size_t)1);
525 _par_cleanup_thread_state = NEW_C_HEAP_ARRAY(ParCleanupThreadState*, size);
526 for (int i = 0 ; i < size; i++) {
527 _par_cleanup_thread_state[i] = new ParCleanupThreadState;
528 }
529 524
530 _tasks = NEW_C_HEAP_ARRAY(CMTask*, _max_task_num); 525 _tasks = NEW_C_HEAP_ARRAY(CMTask*, _max_task_num);
531 _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_task_num); 526 _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_task_num);
532 527
533 // so that the assertion in MarkingTaskQueue::task_queue doesn't fail 528 // so that the assertion in MarkingTaskQueue::task_queue doesn't fail
709 _active_tasks = 0; 704 _active_tasks = 0;
710 clear_concurrent_marking_in_progress(); 705 clear_concurrent_marking_in_progress();
711 } 706 }
712 707
713 ConcurrentMark::~ConcurrentMark() { 708 ConcurrentMark::~ConcurrentMark() {
714 int size = (int) MAX2(ParallelGCThreads, (size_t)1);
715 for (int i = 0; i < size; i++) delete _par_cleanup_thread_state[i];
716 FREE_C_HEAP_ARRAY(ParCleanupThreadState*,
717 _par_cleanup_thread_state);
718
719 for (int i = 0; i < (int) _max_task_num; ++i) { 709 for (int i = 0; i < (int) _max_task_num; ++i) {
720 delete _task_queues->queue(i); 710 delete _task_queues->queue(i);
721 delete _tasks[i]; 711 delete _tasks[i];
722 } 712 }
723 delete _task_queues; 713 delete _task_queues;
1508 G1CollectedHeap* _g1; 1498 G1CollectedHeap* _g1;
1509 int _worker_num; 1499 int _worker_num;
1510 size_t _max_live_bytes; 1500 size_t _max_live_bytes;
1511 size_t _regions_claimed; 1501 size_t _regions_claimed;
1512 size_t _freed_bytes; 1502 size_t _freed_bytes;
1513 size_t _cleared_h_regions; 1503 FreeRegionList _local_cleanup_list;
1514 size_t _freed_regions; 1504 HumongousRegionSet _humongous_proxy_set;
1515 UncleanRegionList* _unclean_region_list;
1516 double _claimed_region_time; 1505 double _claimed_region_time;
1517 double _max_region_time; 1506 double _max_region_time;
1518 1507
1519 public: 1508 public:
1520 G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1, 1509 G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1,
1521 UncleanRegionList* list,
1522 int worker_num); 1510 int worker_num);
1523 size_t freed_bytes() { return _freed_bytes; } 1511 size_t freed_bytes() { return _freed_bytes; }
1524 size_t cleared_h_regions() { return _cleared_h_regions; } 1512 FreeRegionList* local_cleanup_list() {
1525 size_t freed_regions() { return _freed_regions; } 1513 return &_local_cleanup_list;
1526 UncleanRegionList* unclean_region_list() { 1514 }
1527 return _unclean_region_list; 1515 HumongousRegionSet* humongous_proxy_set() {
1516 return &_humongous_proxy_set;
1528 } 1517 }
1529 1518
1530 bool doHeapRegion(HeapRegion *r); 1519 bool doHeapRegion(HeapRegion *r);
1531 1520
1532 size_t max_live_bytes() { return _max_live_bytes; } 1521 size_t max_live_bytes() { return _max_live_bytes; }
1535 double max_region_time_sec() { return _max_region_time; } 1524 double max_region_time_sec() { return _max_region_time; }
1536 }; 1525 };
1537 1526
1538 class G1ParNoteEndTask: public AbstractGangTask { 1527 class G1ParNoteEndTask: public AbstractGangTask {
1539 friend class G1NoteEndOfConcMarkClosure; 1528 friend class G1NoteEndOfConcMarkClosure;
1529
1540 protected: 1530 protected:
1541 G1CollectedHeap* _g1h; 1531 G1CollectedHeap* _g1h;
1542 size_t _max_live_bytes; 1532 size_t _max_live_bytes;
1543 size_t _freed_bytes; 1533 size_t _freed_bytes;
1544 ConcurrentMark::ParCleanupThreadState** _par_cleanup_thread_state; 1534 FreeRegionList* _cleanup_list;
1535
1545 public: 1536 public:
1546 G1ParNoteEndTask(G1CollectedHeap* g1h, 1537 G1ParNoteEndTask(G1CollectedHeap* g1h,
1547 ConcurrentMark::ParCleanupThreadState** 1538 FreeRegionList* cleanup_list) :
1548 par_cleanup_thread_state) :
1549 AbstractGangTask("G1 note end"), _g1h(g1h), 1539 AbstractGangTask("G1 note end"), _g1h(g1h),
1550 _max_live_bytes(0), _freed_bytes(0), 1540 _max_live_bytes(0), _freed_bytes(0), _cleanup_list(cleanup_list) { }
1551 _par_cleanup_thread_state(par_cleanup_thread_state)
1552 {}
1553 1541
1554 void work(int i) { 1542 void work(int i) {
1555 double start = os::elapsedTime(); 1543 double start = os::elapsedTime();
1556 G1NoteEndOfConcMarkClosure g1_note_end(_g1h, 1544 G1NoteEndOfConcMarkClosure g1_note_end(_g1h, i);
1557 &_par_cleanup_thread_state[i]->list,
1558 i);
1559 if (G1CollectedHeap::use_parallel_gc_threads()) { 1545 if (G1CollectedHeap::use_parallel_gc_threads()) {
1560 _g1h->heap_region_par_iterate_chunked(&g1_note_end, i, 1546 _g1h->heap_region_par_iterate_chunked(&g1_note_end, i,
1561 HeapRegion::NoteEndClaimValue); 1547 HeapRegion::NoteEndClaimValue);
1562 } else { 1548 } else {
1563 _g1h->heap_region_iterate(&g1_note_end); 1549 _g1h->heap_region_iterate(&g1_note_end);
1564 } 1550 }
1565 assert(g1_note_end.complete(), "Shouldn't have yielded!"); 1551 assert(g1_note_end.complete(), "Shouldn't have yielded!");
1566 1552
1567 // Now finish up freeing the current thread's regions. 1553 // Now update the lists
1568 _g1h->finish_free_region_work(g1_note_end.freed_bytes(), 1554 _g1h->update_sets_after_freeing_regions(g1_note_end.freed_bytes(),
1569 g1_note_end.cleared_h_regions(), 1555 NULL /* free_list */,
1570 0, NULL); 1556 g1_note_end.humongous_proxy_set(),
1557 true /* par */);
1571 { 1558 {
1572 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); 1559 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
1573 _max_live_bytes += g1_note_end.max_live_bytes(); 1560 _max_live_bytes += g1_note_end.max_live_bytes();
1574 _freed_bytes += g1_note_end.freed_bytes(); 1561 _freed_bytes += g1_note_end.freed_bytes();
1562
1563 _cleanup_list->add_as_tail(g1_note_end.local_cleanup_list());
1564 assert(g1_note_end.local_cleanup_list()->is_empty(), "post-condition");
1575 } 1565 }
1576 double end = os::elapsedTime(); 1566 double end = os::elapsedTime();
1577 if (G1PrintParCleanupStats) { 1567 if (G1PrintParCleanupStats) {
1578 gclog_or_tty->print(" Worker thread %d [%8.3f..%8.3f = %8.3f ms] " 1568 gclog_or_tty->print(" Worker thread %d [%8.3f..%8.3f = %8.3f ms] "
1579 "claimed %d regions (tot = %8.3f ms, max = %8.3f ms).\n", 1569 "claimed %d regions (tot = %8.3f ms, max = %8.3f ms).\n",
1610 1600
1611 }; 1601 };
1612 1602
1613 G1NoteEndOfConcMarkClosure:: 1603 G1NoteEndOfConcMarkClosure::
1614 G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1, 1604 G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1,
1615 UncleanRegionList* list,
1616 int worker_num) 1605 int worker_num)
1617 : _g1(g1), _worker_num(worker_num), 1606 : _g1(g1), _worker_num(worker_num),
1618 _max_live_bytes(0), _regions_claimed(0), 1607 _max_live_bytes(0), _regions_claimed(0),
1619 _freed_bytes(0), _cleared_h_regions(0), _freed_regions(0), 1608 _freed_bytes(0),
1620 _claimed_region_time(0.0), _max_region_time(0.0), 1609 _claimed_region_time(0.0), _max_region_time(0.0),
1621 _unclean_region_list(list) 1610 _local_cleanup_list("Local Cleanup List"),
1622 {} 1611 _humongous_proxy_set("Local Cleanup Humongous Proxy Set") { }
1623 1612
1624 bool G1NoteEndOfConcMarkClosure::doHeapRegion(HeapRegion *r) { 1613 bool G1NoteEndOfConcMarkClosure::doHeapRegion(HeapRegion *hr) {
1625 // We use a claim value of zero here because all regions 1614 // We use a claim value of zero here because all regions
1626 // were claimed with value 1 in the FinalCount task. 1615 // were claimed with value 1 in the FinalCount task.
1627 r->reset_gc_time_stamp(); 1616 hr->reset_gc_time_stamp();
1628 if (!r->continuesHumongous()) { 1617 if (!hr->continuesHumongous()) {
1629 double start = os::elapsedTime(); 1618 double start = os::elapsedTime();
1630 _regions_claimed++; 1619 _regions_claimed++;
1631 r->note_end_of_marking(); 1620 hr->note_end_of_marking();
1632 _max_live_bytes += r->max_live_bytes(); 1621 _max_live_bytes += hr->max_live_bytes();
1633 _g1->free_region_if_totally_empty_work(r, 1622 _g1->free_region_if_totally_empty(hr,
1634 _freed_bytes, 1623 &_freed_bytes,
1635 _cleared_h_regions, 1624 &_local_cleanup_list,
1636 _freed_regions, 1625 &_humongous_proxy_set,
1637 _unclean_region_list, 1626 true /* par */);
1638 true /*par*/);
1639 double region_time = (os::elapsedTime() - start); 1627 double region_time = (os::elapsedTime() - start);
1640 _claimed_region_time += region_time; 1628 _claimed_region_time += region_time;
1641 if (region_time > _max_region_time) _max_region_time = region_time; 1629 if (region_time > _max_region_time) _max_region_time = region_time;
1642 } 1630 }
1643 return false; 1631 return false;
1652 // If a full collection has happened, we shouldn't do this. 1640 // If a full collection has happened, we shouldn't do this.
1653 if (has_aborted()) { 1641 if (has_aborted()) {
1654 g1h->set_marking_complete(); // So bitmap clearing isn't confused 1642 g1h->set_marking_complete(); // So bitmap clearing isn't confused
1655 return; 1643 return;
1656 } 1644 }
1645
1646 g1h->verify_region_sets_optional();
1657 1647
1658 if (VerifyDuringGC) { 1648 if (VerifyDuringGC) {
1659 HandleMark hm; // handle scope 1649 HandleMark hm; // handle scope
1660 gclog_or_tty->print(" VerifyDuringGC:(before)"); 1650 gclog_or_tty->print(" VerifyDuringGC:(before)");
1661 Universe::heap()->prepare_for_verify(); 1651 Universe::heap()->prepare_for_verify();
1717 1707
1718 g1h->reset_gc_time_stamp(); 1708 g1h->reset_gc_time_stamp();
1719 1709
1720 // Note end of marking in all heap regions. 1710 // Note end of marking in all heap regions.
1721 double note_end_start = os::elapsedTime(); 1711 double note_end_start = os::elapsedTime();
1722 G1ParNoteEndTask g1_par_note_end_task(g1h, _par_cleanup_thread_state); 1712 G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list);
1723 if (G1CollectedHeap::use_parallel_gc_threads()) { 1713 if (G1CollectedHeap::use_parallel_gc_threads()) {
1724 int n_workers = g1h->workers()->total_workers(); 1714 int n_workers = g1h->workers()->total_workers();
1725 g1h->set_par_threads(n_workers); 1715 g1h->set_par_threads(n_workers);
1726 g1h->workers()->run_task(&g1_par_note_end_task); 1716 g1h->workers()->run_task(&g1_par_note_end_task);
1727 g1h->set_par_threads(0); 1717 g1h->set_par_threads(0);
1729 assert(g1h->check_heap_region_claim_values(HeapRegion::NoteEndClaimValue), 1719 assert(g1h->check_heap_region_claim_values(HeapRegion::NoteEndClaimValue),
1730 "sanity check"); 1720 "sanity check");
1731 } else { 1721 } else {
1732 g1_par_note_end_task.work(0); 1722 g1_par_note_end_task.work(0);
1733 } 1723 }
1734 g1h->set_unclean_regions_coming(true); 1724
1725 if (!cleanup_list_is_empty()) {
1726 // The cleanup list is not empty, so we'll have to process it
1727 // concurrently. Notify anyone else that might be wanting free
1728 // regions that there will be more free regions coming soon.
1729 g1h->set_free_regions_coming();
1730 }
1735 double note_end_end = os::elapsedTime(); 1731 double note_end_end = os::elapsedTime();
1736 // Tell the mutators that there might be unclean regions coming...
1737 if (G1PrintParCleanupStats) { 1732 if (G1PrintParCleanupStats) {
1738 gclog_or_tty->print_cr(" note end of marking: %8.3f ms.", 1733 gclog_or_tty->print_cr(" note end of marking: %8.3f ms.",
1739 (note_end_end - note_end_start)*1000.0); 1734 (note_end_end - note_end_start)*1000.0);
1740 } 1735 }
1741 1736
1797 Universe::heap()->prepare_for_verify(); 1792 Universe::heap()->prepare_for_verify();
1798 Universe::verify(/* allow dirty */ true, 1793 Universe::verify(/* allow dirty */ true,
1799 /* silent */ false, 1794 /* silent */ false,
1800 /* prev marking */ true); 1795 /* prev marking */ true);
1801 } 1796 }
1797
1798 g1h->verify_region_sets_optional();
1802 } 1799 }
1803 1800
1804 void ConcurrentMark::completeCleanup() { 1801 void ConcurrentMark::completeCleanup() {
1805 // A full collection intervened.
1806 if (has_aborted()) return; 1802 if (has_aborted()) return;
1807 1803
1808 int first = 0; 1804 G1CollectedHeap* g1h = G1CollectedHeap::heap();
1809 int last = (int)MAX2(ParallelGCThreads, (size_t)1); 1805
1810 for (int t = 0; t < last; t++) { 1806 _cleanup_list.verify_optional();
1811 UncleanRegionList* list = &_par_cleanup_thread_state[t]->list; 1807 FreeRegionList local_free_list("Local Cleanup List");
1812 assert(list->well_formed(), "Inv"); 1808
1813 HeapRegion* hd = list->hd(); 1809 if (G1ConcRegionFreeingVerbose) {
1814 while (hd != NULL) { 1810 gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
1815 // Now finish up the other stuff. 1811 "cleanup list has "SIZE_FORMAT" entries",
1816 hd->rem_set()->clear(); 1812 _cleanup_list.length());
1817 HeapRegion* next_hd = hd->next_from_unclean_list(); 1813 }
1818 (void)list->pop(); 1814
1819 assert(list->hd() == next_hd, "how not?"); 1815 // Noone else should be accessing the _cleanup_list at this point,
1820 _g1h->put_region_on_unclean_list(hd); 1816 // so it's not necessary to take any locks
1821 if (!hd->isHumongous()) { 1817 while (!_cleanup_list.is_empty()) {
1822 // Add this to the _free_regions count by 1. 1818 HeapRegion* hr = _cleanup_list.remove_head();
1823 _g1h->finish_free_region_work(0, 0, 1, NULL); 1819 assert(hr != NULL, "the list was not empty");
1820 hr->rem_set()->clear();
1821 local_free_list.add_as_tail(hr);
1822
1823 // Instead of adding one region at a time to the secondary_free_list,
1824 // we accumulate them in the local list and move them a few at a
1825 // time. This also cuts down on the number of notify_all() calls
1826 // we do during this process. We'll also append the local list when
1827 // _cleanup_list is empty (which means we just removed the last
1828 // region from the _cleanup_list).
1829 if ((local_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
1830 _cleanup_list.is_empty()) {
1831 if (G1ConcRegionFreeingVerbose) {
1832 gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
1833 "appending "SIZE_FORMAT" entries to the "
1834 "secondary_free_list, clean list still has "
1835 SIZE_FORMAT" entries",
1836 local_free_list.length(),
1837 _cleanup_list.length());
1824 } 1838 }
1825 hd = list->hd(); 1839
1826 assert(hd == next_hd, "how not?"); 1840 {
1827 } 1841 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
1828 } 1842 g1h->secondary_free_list_add_as_tail(&local_free_list);
1843 SecondaryFreeList_lock->notify_all();
1844 }
1845
1846 if (G1StressConcRegionFreeing) {
1847 for (uintx i = 0; i < G1StressConcRegionFreeingDelayMillis; ++i) {
1848 os::sleep(Thread::current(), (jlong) 1, false);
1849 }
1850 }
1851 }
1852 }
1853 assert(local_free_list.is_empty(), "post-condition");
1829 } 1854 }
1830 1855
1831 bool G1CMIsAliveClosure::do_object_b(oop obj) { 1856 bool G1CMIsAliveClosure::do_object_b(oop obj) {
1832 HeapWord* addr = (HeapWord*)obj; 1857 HeapWord* addr = (HeapWord*)obj;
1833 return addr != NULL && 1858 return addr != NULL &&
2895 public: 2920 public:
2896 virtual void do_oop(narrowOop* p) { do_oop_work(p); } 2921 virtual void do_oop(narrowOop* p) { do_oop_work(p); }
2897 virtual void do_oop( oop* p) { do_oop_work(p); } 2922 virtual void do_oop( oop* p) { do_oop_work(p); }
2898 2923
2899 template <class T> void do_oop_work(T* p) { 2924 template <class T> void do_oop_work(T* p) {
2900 assert(_g1h->is_in_g1_reserved((HeapWord*) p), "invariant"); 2925 assert( _g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
2901 assert(!_g1h->heap_region_containing((HeapWord*) p)->is_on_free_list(), 2926 assert(!_g1h->is_on_free_list(
2902 "invariant"); 2927 _g1h->heap_region_containing((HeapWord*) p)), "invariant");
2903 2928
2904 oop obj = oopDesc::load_decode_heap_oop(p); 2929 oop obj = oopDesc::load_decode_heap_oop(p);
2905 if (_cm->verbose_high()) 2930 if (_cm->verbose_high())
2906 gclog_or_tty->print_cr("[%d] we're looking at location " 2931 gclog_or_tty->print_cr("[%d] we're looking at location "
2907 "*"PTR_FORMAT" = "PTR_FORMAT, 2932 "*"PTR_FORMAT" = "PTR_FORMAT,
3117 } 3142 }
3118 3143
3119 void CMTask::push(oop obj) { 3144 void CMTask::push(oop obj) {
3120 HeapWord* objAddr = (HeapWord*) obj; 3145 HeapWord* objAddr = (HeapWord*) obj;
3121 assert(_g1h->is_in_g1_reserved(objAddr), "invariant"); 3146 assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
3122 assert(!_g1h->heap_region_containing(objAddr)->is_on_free_list(), 3147 assert(!_g1h->is_on_free_list(
3123 "invariant"); 3148 _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
3124 assert(!_g1h->is_obj_ill(obj), "invariant"); 3149 assert(!_g1h->is_obj_ill(obj), "invariant");
3125 assert(_nextMarkBitMap->isMarked(objAddr), "invariant"); 3150 assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
3126 3151
3127 if (_cm->verbose_high()) 3152 if (_cm->verbose_high())
3128 gclog_or_tty->print_cr("[%d] pushing "PTR_FORMAT, _task_id, (void*) obj); 3153 gclog_or_tty->print_cr("[%d] pushing "PTR_FORMAT, _task_id, (void*) obj);
3363 if (_cm->verbose_high()) 3388 if (_cm->verbose_high())
3364 gclog_or_tty->print_cr("[%d] popped "PTR_FORMAT, _task_id, 3389 gclog_or_tty->print_cr("[%d] popped "PTR_FORMAT, _task_id,
3365 (void*) obj); 3390 (void*) obj);
3366 3391
3367 assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" ); 3392 assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
3368 assert(!_g1h->heap_region_containing(obj)->is_on_free_list(), 3393 assert(!_g1h->is_on_free_list(
3369 "invariant"); 3394 _g1h->heap_region_containing((HeapWord*) obj)), "invariant");
3370 3395
3371 scan_object(obj); 3396 scan_object(obj);
3372 3397
3373 if (_task_queue->size() <= target_size || has_aborted()) 3398 if (_task_queue->size() <= target_size || has_aborted())
3374 ret = false; 3399 ret = false;

mercurial