< prev index next >

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

Print this page
rev 7557 : 8060025: Object copy time regressions after JDK-8031323 and JDK-8057536
Summary: Evaluate and improve object copy time by micro-optimizations and splitting out slow and fast paths aggressively.
Reviewed-by:
Contributed-by: Tony Printezis <tprintezis@twitter.com>, Thomas Schatzl <thomas.schatzl@oracle.com>


1420 
1421 void G1CollectorPolicy::print_yg_surv_rate_info() const {
1422 #ifndef PRODUCT
1423   _short_lived_surv_rate_group->print_surv_rate_summary();
1424   // add this call for any other surv rate groups
1425 #endif // PRODUCT
1426 }
1427 
1428 bool G1CollectorPolicy::is_young_list_full() {
1429   uint young_list_length = _g1->young_list()->length();
1430   uint young_list_target_length = _young_list_target_length;
1431   return young_list_length >= young_list_target_length;
1432 }
1433 
1434 bool G1CollectorPolicy::can_expand_young_list() {
1435   uint young_list_length = _g1->young_list()->length();
1436   uint young_list_max_length = _young_list_max_length;
1437   return young_list_length < young_list_max_length;
1438 }
1439 
1440 uint G1CollectorPolicy::max_regions(int purpose) {
1441   switch (purpose) {
1442     case GCAllocForSurvived:
1443       return _max_survivor_regions;
1444     case GCAllocForTenured:
1445       return REGIONS_UNLIMITED;
1446     default:
1447       ShouldNotReachHere();
1448       return REGIONS_UNLIMITED;
1449   };
1450 }
1451 
1452 void G1CollectorPolicy::update_max_gc_locker_expansion() {
1453   uint expansion_region_num = 0;
1454   if (GCLockerEdenExpansionPercent > 0) {
1455     double perc = (double) GCLockerEdenExpansionPercent / 100.0;
1456     double expansion_region_num_d = perc * (double) _young_list_target_length;
1457     // We use ceiling so that if expansion_region_num_d is > 0.0 (but
1458     // less than 1.0) we'll get 1.
1459     expansion_region_num = (uint) ceil(expansion_region_num_d);
1460   } else {
1461     assert(expansion_region_num == 0, "sanity");
1462   }
1463   _young_list_max_length = _young_list_target_length + expansion_region_num;
1464   assert(_young_list_target_length <= _young_list_max_length, "post-condition");
1465 }
1466 
1467 // Calculates survivor space parameters.
1468 void G1CollectorPolicy::update_survivors_policy() {
1469   double max_survivor_regions_d =
1470                  (double) _young_list_target_length / (double) SurvivorRatio;
1471   // We use ceiling so that if max_survivor_regions_d is > 0.0 (but


1617   _collectionSetChooser->sort_regions();
1618 
1619   double end_sec = os::elapsedTime();
1620   double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
1621   _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
1622   _cur_mark_stop_world_time_ms += elapsed_time_ms;
1623   _prev_collection_pause_end_ms += elapsed_time_ms;
1624   _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true);
1625 }
1626 
1627 // Add the heap region at the head of the non-incremental collection set
1628 void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) {
1629   assert(_inc_cset_build_state == Active, "Precondition");
1630   assert(hr->is_old(), "the region should be old");
1631 
1632   assert(!hr->in_collection_set(), "should not already be in the CSet");
1633   hr->set_in_collection_set(true);
1634   hr->set_next_in_collection_set(_collection_set);
1635   _collection_set = hr;
1636   _collection_set_bytes_used_before += hr->used();
1637   _g1->register_region_with_in_cset_fast_test(hr);
1638   size_t rs_length = hr->rem_set()->occupied();
1639   _recorded_rs_lengths += rs_length;
1640   _old_cset_region_length += 1;
1641 }
1642 
1643 // Initialize the per-collection-set information
1644 void G1CollectorPolicy::start_incremental_cset_building() {
1645   assert(_inc_cset_build_state == Inactive, "Precondition");
1646 
1647   _inc_cset_head = NULL;
1648   _inc_cset_tail = NULL;
1649   _inc_cset_bytes_used_before = 0;
1650 
1651   _inc_cset_max_finger = 0;
1652   _inc_cset_recorded_rs_lengths = 0;
1653   _inc_cset_recorded_rs_lengths_diffs = 0;
1654   _inc_cset_predicted_elapsed_time_ms = 0.0;
1655   _inc_cset_predicted_elapsed_time_ms_diffs = 0.0;
1656   _inc_cset_build_state = Active;
1657 }


1750   assert(hr->young_index_in_cset() > -1, "should have already been set");
1751   assert(_inc_cset_build_state == Active, "Precondition");
1752 
1753   // We need to clear and set the cached recorded/cached collection set
1754   // information in the heap region here (before the region gets added
1755   // to the collection set). An individual heap region's cached values
1756   // are calculated, aggregated with the policy collection set info,
1757   // and cached in the heap region here (initially) and (subsequently)
1758   // by the Young List sampling code.
1759 
1760   size_t rs_length = hr->rem_set()->occupied();
1761   add_to_incremental_cset_info(hr, rs_length);
1762 
1763   HeapWord* hr_end = hr->end();
1764   _inc_cset_max_finger = MAX2(_inc_cset_max_finger, hr_end);
1765 
1766   assert(!hr->in_collection_set(), "invariant");
1767   hr->set_in_collection_set(true);
1768   assert( hr->next_in_collection_set() == NULL, "invariant");
1769 
1770   _g1->register_region_with_in_cset_fast_test(hr);
1771 }
1772 
1773 // Add the region at the RHS of the incremental cset
1774 void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) {
1775   // We should only ever be appending survivors at the end of a pause
1776   assert(hr->is_survivor(), "Logic");
1777 
1778   // Do the 'common' stuff
1779   add_region_to_incremental_cset_common(hr);
1780 
1781   // Now add the region at the right hand side
1782   if (_inc_cset_tail == NULL) {
1783     assert(_inc_cset_head == NULL, "invariant");
1784     _inc_cset_head = hr;
1785   } else {
1786     _inc_cset_tail->set_next_in_collection_set(hr);
1787   }
1788   _inc_cset_tail = hr;
1789 }
1790 




1420 
1421 void G1CollectorPolicy::print_yg_surv_rate_info() const {
1422 #ifndef PRODUCT
1423   _short_lived_surv_rate_group->print_surv_rate_summary();
1424   // add this call for any other surv rate groups
1425 #endif // PRODUCT
1426 }
1427 
1428 bool G1CollectorPolicy::is_young_list_full() {
1429   uint young_list_length = _g1->young_list()->length();
1430   uint young_list_target_length = _young_list_target_length;
1431   return young_list_length >= young_list_target_length;
1432 }
1433 
1434 bool G1CollectorPolicy::can_expand_young_list() {
1435   uint young_list_length = _g1->young_list()->length();
1436   uint young_list_max_length = _young_list_max_length;
1437   return young_list_length < young_list_max_length;
1438 }
1439 












1440 void G1CollectorPolicy::update_max_gc_locker_expansion() {
1441   uint expansion_region_num = 0;
1442   if (GCLockerEdenExpansionPercent > 0) {
1443     double perc = (double) GCLockerEdenExpansionPercent / 100.0;
1444     double expansion_region_num_d = perc * (double) _young_list_target_length;
1445     // We use ceiling so that if expansion_region_num_d is > 0.0 (but
1446     // less than 1.0) we'll get 1.
1447     expansion_region_num = (uint) ceil(expansion_region_num_d);
1448   } else {
1449     assert(expansion_region_num == 0, "sanity");
1450   }
1451   _young_list_max_length = _young_list_target_length + expansion_region_num;
1452   assert(_young_list_target_length <= _young_list_max_length, "post-condition");
1453 }
1454 
1455 // Calculates survivor space parameters.
1456 void G1CollectorPolicy::update_survivors_policy() {
1457   double max_survivor_regions_d =
1458                  (double) _young_list_target_length / (double) SurvivorRatio;
1459   // We use ceiling so that if max_survivor_regions_d is > 0.0 (but


1605   _collectionSetChooser->sort_regions();
1606 
1607   double end_sec = os::elapsedTime();
1608   double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
1609   _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
1610   _cur_mark_stop_world_time_ms += elapsed_time_ms;
1611   _prev_collection_pause_end_ms += elapsed_time_ms;
1612   _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_sec, true);
1613 }
1614 
1615 // Add the heap region at the head of the non-incremental collection set
1616 void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) {
1617   assert(_inc_cset_build_state == Active, "Precondition");
1618   assert(hr->is_old(), "the region should be old");
1619 
1620   assert(!hr->in_collection_set(), "should not already be in the CSet");
1621   hr->set_in_collection_set(true);
1622   hr->set_next_in_collection_set(_collection_set);
1623   _collection_set = hr;
1624   _collection_set_bytes_used_before += hr->used();
1625   _g1->register_old_region_with_in_cset_fast_test(hr);
1626   size_t rs_length = hr->rem_set()->occupied();
1627   _recorded_rs_lengths += rs_length;
1628   _old_cset_region_length += 1;
1629 }
1630 
1631 // Initialize the per-collection-set information
1632 void G1CollectorPolicy::start_incremental_cset_building() {
1633   assert(_inc_cset_build_state == Inactive, "Precondition");
1634 
1635   _inc_cset_head = NULL;
1636   _inc_cset_tail = NULL;
1637   _inc_cset_bytes_used_before = 0;
1638 
1639   _inc_cset_max_finger = 0;
1640   _inc_cset_recorded_rs_lengths = 0;
1641   _inc_cset_recorded_rs_lengths_diffs = 0;
1642   _inc_cset_predicted_elapsed_time_ms = 0.0;
1643   _inc_cset_predicted_elapsed_time_ms_diffs = 0.0;
1644   _inc_cset_build_state = Active;
1645 }


1738   assert(hr->young_index_in_cset() > -1, "should have already been set");
1739   assert(_inc_cset_build_state == Active, "Precondition");
1740 
1741   // We need to clear and set the cached recorded/cached collection set
1742   // information in the heap region here (before the region gets added
1743   // to the collection set). An individual heap region's cached values
1744   // are calculated, aggregated with the policy collection set info,
1745   // and cached in the heap region here (initially) and (subsequently)
1746   // by the Young List sampling code.
1747 
1748   size_t rs_length = hr->rem_set()->occupied();
1749   add_to_incremental_cset_info(hr, rs_length);
1750 
1751   HeapWord* hr_end = hr->end();
1752   _inc_cset_max_finger = MAX2(_inc_cset_max_finger, hr_end);
1753 
1754   assert(!hr->in_collection_set(), "invariant");
1755   hr->set_in_collection_set(true);
1756   assert( hr->next_in_collection_set() == NULL, "invariant");
1757 
1758   _g1->register_young_region_with_in_cset_fast_test(hr);
1759 }
1760 
1761 // Add the region at the RHS of the incremental cset
1762 void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) {
1763   // We should only ever be appending survivors at the end of a pause
1764   assert(hr->is_survivor(), "Logic");
1765 
1766   // Do the 'common' stuff
1767   add_region_to_incremental_cset_common(hr);
1768 
1769   // Now add the region at the right hand side
1770   if (_inc_cset_tail == NULL) {
1771     assert(_inc_cset_head == NULL, "invariant");
1772     _inc_cset_head = hr;
1773   } else {
1774     _inc_cset_tail->set_next_in_collection_set(hr);
1775   }
1776   _inc_cset_tail = hr;
1777 }
1778 


< prev index next >