src/hotspot/share/gc/g1/g1RemSet.cpp
changeset 52345 418fb8bb5151
parent 51877 5f931e3e7a63
child 52348 21fdf8d9a8b6
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Wed Oct 31 07:06:54 2018 -0400
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Wed Oct 31 13:43:57 2018 +0100
@@ -133,10 +133,10 @@
 
     virtual bool do_heap_region(HeapRegion* r) {
       uint hrm_index = r->hrm_index();
-      if (!r->in_collection_set() && r->is_old_or_humongous_or_archive()) {
+      if (!r->in_collection_set() && r->is_old_or_humongous_or_archive() && !r->is_empty()) {
         _scan_top[hrm_index] = r->top();
       } else {
-        _scan_top[hrm_index] = r->bottom();
+        _scan_top[hrm_index] = NULL;
       }
       return false;
     }
@@ -191,6 +191,7 @@
   void reset() {
     for (uint i = 0; i < _max_regions; i++) {
       _iter_states[i] = Unclaimed;
+      _scan_top[i] = NULL;
     }
 
     G1ResetScanTopClosure cl(_scan_top);
@@ -350,6 +351,10 @@
     _scan_state->add_dirty_region(region_idx);
   }
 
+  if (r->rem_set()->cardset_is_empty()) {
+    return;
+  }
+
   // We claim cards in blocks so as to reduce the contention.
   size_t const block_size = G1RSetScanBlockSize;
 
@@ -367,18 +372,21 @@
     }
     _cards_claimed++;
 
-    // If the card is dirty, then G1 will scan it during Update RS.
-    if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
+    HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index);
+    uint const region_idx_for_card = _g1h->addr_to_region(card_start);
+
+#ifdef ASSERT
+    HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
+    assert(hr == NULL || hr->is_in_reserved(card_start),
+           "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
+#endif
+    HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
+    if (card_start >= top) {
       continue;
     }
 
-    HeapWord* const card_start = _g1h->bot()->address_for_index(card_index);
-    uint const region_idx_for_card = _g1h->addr_to_region(card_start);
-
-    assert(_g1h->region_at(region_idx_for_card)->is_in_reserved(card_start),
-           "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
-    HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
-    if (card_start >= top) {
+    // If the card is dirty, then G1 will scan it during Update RS.
+    if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
       continue;
     }
 
@@ -545,6 +553,16 @@
                                         uint worker_i) {
   assert(!_g1h->is_gc_active(), "Only call concurrently");
 
+  // Construct the region representing the card.
+  HeapWord* start = _ct->addr_for(card_ptr);
+  // And find the region containing it.
+  HeapRegion* r = _g1h->heap_region_containing_or_null(start);
+
+  // If this is a (stale) card into an uncommitted region, exit.
+  if (r == NULL) {
+    return;
+  }
+
   check_card_ptr(card_ptr, _ct);
 
   // If the card is no longer dirty, nothing to do.
@@ -552,11 +570,6 @@
     return;
   }
 
-  // Construct the region representing the card.
-  HeapWord* start = _ct->addr_for(card_ptr);
-  // And find the region containing it.
-  HeapRegion* r = _g1h->heap_region_containing(start);
-
   // This check is needed for some uncommon cases where we should
   // ignore the card.
   //
@@ -679,6 +692,18 @@
                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
   assert(_g1h->is_gc_active(), "Only call during GC");
 
+  // Construct the region representing the card.
+  HeapWord* card_start = _ct->addr_for(card_ptr);
+  // And find the region containing it.
+  uint const card_region_idx = _g1h->addr_to_region(card_start);
+
+  HeapWord* scan_limit = _scan_state->scan_top(card_region_idx);
+  if (scan_limit == NULL) {
+    // This is a card into an uncommitted region. We need to bail out early as we
+    // should not access the corresponding card table entry.
+    return false;
+  }
+
   check_card_ptr(card_ptr, _ct);
 
   // If the card is no longer dirty, nothing to do. This covers cards that were already
@@ -691,13 +716,7 @@
   // number of potential duplicate scans (multiple threads may enqueue the same card twice).
   *card_ptr = G1CardTable::clean_card_val() | G1CardTable::claimed_card_val();
 
-  // Construct the region representing the card.
-  HeapWord* card_start = _ct->addr_for(card_ptr);
-  // And find the region containing it.
-  uint const card_region_idx = _g1h->addr_to_region(card_start);
-
   _scan_state->add_dirty_region(card_region_idx);
-  HeapWord* scan_limit = _scan_state->scan_top(card_region_idx);
   if (scan_limit <= card_start) {
     // If the card starts above the area in the region containing objects to scan, skip it.
     return false;