--- old/src/hotspot/share/gc/g1/g1RemSet.cpp 2019-11-13 17:04:45.430337080 -0800 +++ new/src/hotspot/share/gc/g1/g1RemSet.cpp 2019-11-13 17:04:45.058339390 -0800 @@ -1261,7 +1261,8 @@ #endif } -bool G1RemSet::clean_card_before_refine(CardValue*& card_ptr) { +bool G1RemSet::clean_card_before_refine(CardValue*& card_ptr + DEBUG_ONLY(COMMA KVHashtable& top_map)) { assert(!_g1h->is_gc_active(), "Only call concurrently"); // Find the start address represented by the card. @@ -1277,6 +1278,8 @@ check_card_ptr(card_ptr, _ct); // If the card is no longer dirty, nothing to do. + // We cannot load the card value before the "r == NULL" check, because G1 + // could uncommit parts of the card table covering uncommitted regions. if (*card_ptr != G1CardTable::dirty_card_val()) { return false; } @@ -1359,11 +1362,21 @@ // as iteration failure. *const_cast(card_ptr) = G1CardTable::clean_card_val(); +#ifdef ASSERT + HeapWord** existing_top = top_map.lookup(card_ptr); + if (existing_top != NULL) { + assert(scan_limit == *existing_top, "top must be stable"); + } else { + top_map.add(card_ptr, scan_limit); + } +#endif + return true; } void G1RemSet::refine_card_concurrently(CardValue* const card_ptr, - const uint worker_id) { + const uint worker_id + DEBUG_ONLY(COMMA KVHashtable& top_map)) { assert(!_g1h->is_gc_active(), "Only call concurrently"); check_card_ptr(card_ptr, _ct); @@ -1371,9 +1384,11 @@ HeapWord* start = _ct->addr_for(card_ptr); // And find the region containing it. HeapRegion* r = _g1h->heap_region_containing(start); + // This reload of the top is safe even though it happens after the full + // fence, because top is stable for unfiltered humongous regions, so it must + // return the same value as the previous load when cleaning the card. HeapWord* scan_limit = r->top(); - // top() can only increase since last read of top() before cleaning the card. - assert(scan_limit > start, "sanity"); + assert(scan_limit == *top_map.lookup(card_ptr), "top must be stable"); // Don't use addr_for(card_ptr + 1) which can ask for // a card beyond the heap.