changeset 60851:c1700981433c

8241920: G1: Lazily initialize OtherRegionsTable::_coarse_map Reviewed-by: tschatzl, eosterlund
author redestad
date Thu, 09 Apr 2020 14:59:11 +0200
parents 7992ff451fec
children 60ec850952da
files src/hotspot/share/gc/g1/heapRegionRemSet.cpp src/hotspot/share/gc/g1/heapRegionRemSet.hpp
diffstat 2 files changed, 22 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp	Thu Apr 09 08:43:03 2020 -0400
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp	Thu Apr 09 14:59:11 2020 +0200
@@ -69,7 +69,7 @@
   _g1h(G1CollectedHeap::heap()),
   _m(m),
   _num_occupied(0),
-  _coarse_map(G1CollectedHeap::heap()->max_regions(), mtGC),
+  _coarse_map(mtGC),
   _n_coarse_entries(0),
   _fine_grain_regions(NULL),
   _n_fine_entries(0),
@@ -132,7 +132,7 @@
   RegionIdx_t from_hrm_ind = (RegionIdx_t) from_hr->hrm_index();
 
   // If the region is already coarsened, return.
-  if (_coarse_map.at(from_hrm_ind)) {
+  if (is_region_coarsened(from_hrm_ind)) {
     assert(contains_reference(from), "We just found " PTR_FORMAT " in the Coarse table", p2i(from));
     return;
   }
@@ -226,7 +226,6 @@
   PerRegionTable* max = NULL;
   jint max_occ = 0;
   PerRegionTable** max_prev = NULL;
-  size_t max_ind;
 
   size_t i = _fine_eviction_start;
   for (size_t k = 0; k < _fine_eviction_sample_size; k++) {
@@ -244,7 +243,6 @@
       if (max == NULL || cur_occ > max_occ) {
         max = cur;
         max_prev = prev;
-        max_ind = i;
         max_occ = cur_occ;
       }
       prev = cur->collision_list_next_addr();
@@ -265,7 +263,15 @@
 
   // Set the corresponding coarse bit.
   size_t max_hrm_index = (size_t) max->hr()->hrm_index();
-  if (!_coarse_map.at(max_hrm_index)) {
+  if (_n_coarse_entries == 0) {
+    // This will lazily initialize an uninitialized bitmap
+    _coarse_map.reinitialize(G1CollectedHeap::heap()->max_regions());
+    _coarse_map.at_put(max_hrm_index, true);
+    // Release store guarantees that the bitmap has initialized before any
+    // concurrent reader will ever see a non-zero value for _n_coarse_entries
+    // (when read with load_acquire)
+    Atomic::release_store(&_n_coarse_entries, _n_coarse_entries + 1);
+  } else if (!_coarse_map.at(max_hrm_index)) {
     _coarse_map.at_put(max_hrm_index, true);
     _n_coarse_entries++;
   }
@@ -344,19 +350,25 @@
   HeapRegion* hr = _g1h->heap_region_containing(from);
   RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index();
   // Is this region in the coarse map?
-  if (_coarse_map.at(hr_ind)) return true;
+  if (is_region_coarsened(hr_ind)) return true;
 
   PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask,
                                           hr);
   if (prt != NULL) {
     return prt->contains_reference(from);
-
   } else {
     CardIdx_t card_index = card_within_region(from, hr);
     return _sparse_table.contains_card(hr_ind, card_index);
   }
 }
 
+// A load_acquire on _n_coarse_entries - coupled with the release_store in
+// delete_region_table - guarantees we don't access _coarse_map before
+// it's been properly initialized.
+bool OtherRegionsTable::is_region_coarsened(RegionIdx_t from_hrm_ind) const {
+  return Atomic::load_acquire(&_n_coarse_entries) > 0 && _coarse_map.at(from_hrm_ind);
+}
+
 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetTable* bot,
                                    HeapRegion* hr)
   : _bot(bot),
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp	Thu Apr 09 08:43:03 2020 -0400
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp	Thu Apr 09 14:59:11 2020 +0200
@@ -153,6 +153,9 @@
 
   // Clear the entire contents of this remembered set.
   void clear();
+
+  // Safe for use by concurrent readers outside _m
+  bool is_region_coarsened(RegionIdx_t from_hrm_ind) const;
 };
 
 class PerRegionTable: public CHeapObj<mtGC> {