Print this page
8236073: G1: Use SoftMaxHeapSize to guide GC heuristics


 141 
 142 // Return maximum number of regions that heap can expand to.
 143 uint HeterogeneousHeapRegionManager::max_expandable_length() const {
 144   return _max_regions;
 145 }
 146 
 147 uint HeterogeneousHeapRegionManager::find_unavailable_in_range(uint start_idx, uint end_idx, uint* res_idx) const {
 148   guarantee(res_idx != NULL, "checking");
 149   guarantee(start_idx <= (max_length() + 1), "checking");
 150 
 151   uint num_regions = 0;
 152 
 153   uint cur = start_idx;
 154   while (cur <= end_idx && is_available(cur)) {
 155     cur++;
 156   }
 157   if (cur == end_idx + 1) {
 158     return num_regions;
 159   }
 160   *res_idx = cur;
 161   while (cur <= end_idx && !is_available(cur)) {
 162     cur++;
 163   }
 164   num_regions = cur - *res_idx;
 165 
 166 #ifdef ASSERT
 167   for (uint i = *res_idx; i < (*res_idx + num_regions); i++) {
 168     assert(!is_available(i), "just checking");
 169   }
 170   assert(cur == end_idx + 1 || num_regions == 0 || is_available(cur),
 171     "The region at the current position %u must be available or at the end", cur);
 172 #endif
 173   return num_regions;
 174 }
 175 
 176 uint HeterogeneousHeapRegionManager::expand_dram(uint num_regions, WorkGang* pretouch_workers) {
 177   return expand_in_range(start_index_of_dram(), end_index_of_dram(), num_regions, pretouch_workers);
 178 }
 179 
 180 uint HeterogeneousHeapRegionManager::expand_nvdimm(uint num_regions, WorkGang* pretouch_workers) {
 181   return expand_in_range(start_index_of_nvdimm(), end_index_of_nvdimm(), num_regions, pretouch_workers);
 182 }
 183 
 184 // Follows same logic as expand_at() form HeapRegionManager.
 185 uint HeterogeneousHeapRegionManager::expand_in_range(uint start, uint end, uint num_regions, WorkGang* pretouch_gang) {
 186 
 187   uint so_far = 0;
 188   uint chunk_start = 0;


 330       return G1_NO_HRM_INDEX;
 331   }
 332   return find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num, true);
 333 }
 334 
 335 uint HeterogeneousHeapRegionManager::find_contiguous_empty_or_unavailable(size_t num) {
 336   if (has_borrowed_regions()) {
 337     return G1_NO_HRM_INDEX;
 338   }
 339   return find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num, false);
 340 }
 341 
 342 uint HeterogeneousHeapRegionManager::find_contiguous(size_t start, size_t end, size_t num, bool empty_only) {
 343   uint found = 0;
 344   size_t length_found = 0;
 345   uint cur = (uint)start;
 346   uint length_unavailable = 0;
 347 
 348   while (length_found < num && cur <= end) {
 349     HeapRegion* hr = _regions.get_by_index(cur);
 350     if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
 351       // This region is a potential candidate for allocation into.
 352       if (!is_available(cur)) {
 353         if(shrink_dram(1) == 1) {
 354           uint ret = expand_in_range(cur, cur, 1, NULL);
 355           assert(ret == 1, "We should be able to expand at this index");
 356         } else {
 357           length_unavailable++;
 358         }
 359       }
 360       length_found++;
 361     }
 362     else {
 363       // This region is not a candidate. The next region is the next possible one.
 364       found = cur + 1;
 365       length_found = 0;
 366     }
 367     cur++;
 368   }
 369 
 370   if (length_found == num) {
 371     for (uint i = found; i < (found + num); i++) {
 372       HeapRegion* hr = _regions.get_by_index(i);
 373       // sanity check
 374       guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
 375                 "Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
 376                 " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr));
 377     }
 378     if (!empty_only && length_unavailable > (max_expandable_length() - total_regions_committed())) {
 379       // if 'length_unavailable' number of regions will be made available, we will exceed max regions.
 380       return G1_NO_HRM_INDEX;
 381     }
 382     return found;
 383   }
 384   else {
 385     return G1_NO_HRM_INDEX;
 386   }
 387 }
 388 
 389 uint HeterogeneousHeapRegionManager::find_highest_free(bool* expanded) {
 390   // Loop downwards from the highest dram region index, looking for an
 391   // entry which is either free or not yet committed.  If not yet
 392   // committed, expand_at that index.
 393   uint curr = end_index_of_dram();
 394   while (true) {




 141 
 142 // Return maximum number of regions that heap can expand to.
 143 uint HeterogeneousHeapRegionManager::max_expandable_length() const {
 144   return _max_regions;
 145 }
 146 
 147 uint HeterogeneousHeapRegionManager::find_unavailable_in_range(uint start_idx, uint end_idx, uint* res_idx) const {
 148   guarantee(res_idx != NULL, "checking");
 149   guarantee(start_idx <= (max_length() + 1), "checking");
 150 
 151   uint num_regions = 0;
 152 
 153   uint cur = start_idx;
 154   while (cur <= end_idx && is_available(cur)) {
 155     cur++;
 156   }
 157   if (cur == end_idx + 1) {
 158     return num_regions;
 159   }
 160   *res_idx = cur;
 161   while (cur <= end_idx && is_unavailable_for_allocation(cur)) {
 162     cur++;
 163   }
 164   num_regions = cur - *res_idx;
 165 
 166 #ifdef ASSERT
 167   for (uint i = *res_idx; i < (*res_idx + num_regions); i++) {
 168     assert(is_unavailable_for_allocation(i), "just checking");
 169   }
 170   assert(cur == end_idx + 1 || num_regions == 0 || is_available(cur),
 171     "The region at the current position %u must be available or at the end", cur);
 172 #endif
 173   return num_regions;
 174 }
 175 
 176 uint HeterogeneousHeapRegionManager::expand_dram(uint num_regions, WorkGang* pretouch_workers) {
 177   return expand_in_range(start_index_of_dram(), end_index_of_dram(), num_regions, pretouch_workers);
 178 }
 179 
 180 uint HeterogeneousHeapRegionManager::expand_nvdimm(uint num_regions, WorkGang* pretouch_workers) {
 181   return expand_in_range(start_index_of_nvdimm(), end_index_of_nvdimm(), num_regions, pretouch_workers);
 182 }
 183 
 184 // Follows same logic as expand_at() form HeapRegionManager.
 185 uint HeterogeneousHeapRegionManager::expand_in_range(uint start, uint end, uint num_regions, WorkGang* pretouch_gang) {
 186 
 187   uint so_far = 0;
 188   uint chunk_start = 0;


 330       return G1_NO_HRM_INDEX;
 331   }
 332   return find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num, true);
 333 }
 334 
 335 uint HeterogeneousHeapRegionManager::find_contiguous_empty_or_unavailable(size_t num) {
 336   if (has_borrowed_regions()) {
 337     return G1_NO_HRM_INDEX;
 338   }
 339   return find_contiguous(start_index_of_nvdimm(), end_index_of_nvdimm(), num, false);
 340 }
 341 
 342 uint HeterogeneousHeapRegionManager::find_contiguous(size_t start, size_t end, size_t num, bool empty_only) {
 343   uint found = 0;
 344   size_t length_found = 0;
 345   uint cur = (uint)start;
 346   uint length_unavailable = 0;
 347 
 348   while (length_found < num && cur <= end) {
 349     HeapRegion* hr = _regions.get_by_index(cur);
 350     if ((!empty_only && is_unavailable_for_allocation(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
 351       // This region is a potential candidate for allocation into.
 352       if (is_unavailable_for_allocation(cur)) {
 353         if(shrink_dram(1) == 1) {
 354           uint ret = expand_in_range(cur, cur, 1, NULL);
 355           assert(ret == 1, "We should be able to expand at this index");
 356         } else {
 357           length_unavailable++;
 358         }
 359       }
 360       length_found++;
 361     }
 362     else {
 363       // This region is not a candidate. The next region is the next possible one.
 364       found = cur + 1;
 365       length_found = 0;
 366     }
 367     cur++;
 368   }
 369 
 370   if (length_found == num) {
 371     for (uint i = found; i < (found + num); i++) {
 372       HeapRegion* hr = _regions.get_by_index(i);
 373       // sanity check
 374       guarantee((!empty_only && is_unavailable_for_allocation(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
 375                 "Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
 376                 " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr));
 377     }
 378     if (!empty_only && length_unavailable > (max_expandable_length() - total_regions_committed())) {
 379       // if 'length_unavailable' number of regions will be made available, we will exceed max regions.
 380       return G1_NO_HRM_INDEX;
 381     }
 382     return found;
 383   }
 384   else {
 385     return G1_NO_HRM_INDEX;
 386   }
 387 }
 388 
 389 uint HeterogeneousHeapRegionManager::find_highest_free(bool* expanded) {
 390   // Loop downwards from the highest dram region index, looking for an
 391   // entry which is either free or not yet committed.  If not yet
 392   // committed, expand_at that index.
 393   uint curr = end_index_of_dram();
 394   while (true) {