1581 _cset_updater(hrSorted, true /* parallel */, chunk_size) { }
1582
1583 bool doHeapRegion(HeapRegion* r) {
1584 // Do we have any marking information for this region?
1585 if (r->is_marked()) {
1586 // We will skip any region that's currently used as an old GC
1587 // alloc region (we should not consider those for collection
1588 // before we fill them up).
1589 if (_cset_updater.should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
1590 _cset_updater.add_region(r);
1591 }
1592 }
1593 return false;
1594 }
1595 };
1596
1597 class ParKnownGarbageTask: public AbstractGangTask {
1598 CollectionSetChooser* _hrSorted;
1599 uint _chunk_size;
1600 G1CollectedHeap* _g1;
1601 public:
1602 ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size) :
1603 AbstractGangTask("ParKnownGarbageTask"),
1604 _hrSorted(hrSorted), _chunk_size(chunk_size),
1605 _g1(G1CollectedHeap::heap()) { }
1606
1607 void work(uint worker_id) {
1608 ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size);
1609
1610 // Back to zero for the claim value.
1611 _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, worker_id,
1612 _g1->workers()->active_workers(),
1613 HeapRegion::InitialClaimValue);
1614 }
1615 };
1616
1617 void
1618 G1CollectorPolicy::record_concurrent_mark_cleanup_end(int no_of_gc_threads) {
1619 _collectionSetChooser->clear();
1620
1621 uint region_num = _g1->num_regions();
1622 if (G1CollectedHeap::use_parallel_gc_threads()) {
1623 const uint OverpartitionFactor = 4;
1624 uint WorkUnit;
1625 // The use of MinChunkSize = 8 in the original code
1626 // causes some assertion failures when the total number of
1627 // region is less than 8. The code here tries to fix that.
1628 // Should the original code also be fixed?
1629 if (no_of_gc_threads > 0) {
1630 const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
1631 WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
1632 MinWorkUnit);
1633 } else {
1634 assert(no_of_gc_threads > 0,
1635 "The active gc workers should be greater than 0");
1636 // In a product build do something reasonable to avoid a crash.
1637 const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
1638 WorkUnit =
1639 MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
1640 MinWorkUnit);
1641 }
1642 _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
1643 WorkUnit);
1644 ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser,
1645 (int) WorkUnit);
1646 _g1->workers()->run_task(&parKnownGarbageTask);
1647
1648 assert(_g1->check_heap_region_claim_values(HeapRegion::InitialClaimValue),
1649 "sanity check");
1650 } else {
1651 KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
1652 _g1->heap_region_iterate(&knownGarbagecl);
1653 }
1654
1655 _collectionSetChooser->sort_regions();
1656
1657 double end_sec = os::elapsedTime();
1658 double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
1659 _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
1660 _cur_mark_stop_world_time_ms += elapsed_time_ms;
1661 _prev_collection_pause_end_ms += elapsed_time_ms;
1662 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true);
1663 }
1664
1665 // Add the heap region at the head of the non-incremental collection set
1666 void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) {
1667 assert(_inc_cset_build_state == Active, "Precondition");
1668 assert(hr->is_old(), "the region should be old");
1669
|
1581 _cset_updater(hrSorted, true /* parallel */, chunk_size) { }
1582
1583 bool doHeapRegion(HeapRegion* r) {
1584 // Do we have any marking information for this region?
1585 if (r->is_marked()) {
1586 // We will skip any region that's currently used as an old GC
1587 // alloc region (we should not consider those for collection
1588 // before we fill them up).
1589 if (_cset_updater.should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
1590 _cset_updater.add_region(r);
1591 }
1592 }
1593 return false;
1594 }
1595 };
1596
1597 class ParKnownGarbageTask: public AbstractGangTask {
1598 CollectionSetChooser* _hrSorted;
1599 uint _chunk_size;
1600 G1CollectedHeap* _g1;
1601 HeapRegionClaimer _hrclaimer;
1602
1603 public:
1604 ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size, uint n_workers) :
1605 AbstractGangTask("ParKnownGarbageTask"),
1606 _hrSorted(hrSorted), _chunk_size(chunk_size),
1607 _g1(G1CollectedHeap::heap()), _hrclaimer(n_workers) {}
1608
1609 void work(uint worker_id) {
1610 ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size);
1611 _g1->heap_region_par_iterate(&parKnownGarbageCl, worker_id, &_hrclaimer);
1612 }
1613 };
1614
1615 void
1616 G1CollectorPolicy::record_concurrent_mark_cleanup_end(int no_of_gc_threads) {
1617 _collectionSetChooser->clear();
1618
1619 uint region_num = _g1->num_regions();
1620 if (G1CollectedHeap::use_parallel_gc_threads()) {
1621 const uint OverpartitionFactor = 4;
1622 uint WorkUnit;
1623 // The use of MinChunkSize = 8 in the original code
1624 // causes some assertion failures when the total number of
1625 // region is less than 8. The code here tries to fix that.
1626 // Should the original code also be fixed?
1627 if (no_of_gc_threads > 0) {
1628 const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
1629 WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
1630 MinWorkUnit);
1631 } else {
1632 assert(no_of_gc_threads > 0,
1633 "The active gc workers should be greater than 0");
1634 // In a product build do something reasonable to avoid a crash.
1635 const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
1636 WorkUnit =
1637 MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
1638 MinWorkUnit);
1639 }
1640 _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
1641 WorkUnit);
1642 ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads);
1643 _g1->workers()->run_task(&parKnownGarbageTask);
1644 } else {
1645 KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
1646 _g1->heap_region_iterate(&knownGarbagecl);
1647 }
1648
1649 _collectionSetChooser->sort_regions();
1650
1651 double end_sec = os::elapsedTime();
1652 double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
1653 _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
1654 _cur_mark_stop_world_time_ms += elapsed_time_ms;
1655 _prev_collection_pause_end_ms += elapsed_time_ms;
1656 _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true);
1657 }
1658
1659 // Add the heap region at the head of the non-incremental collection set
1660 void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) {
1661 assert(_inc_cset_build_state == Active, "Precondition");
1662 assert(hr->is_old(), "the region should be old");
1663
|