8291725: Leftover marks when VM shutdown aborts bitmap clearing make mixed gc fail

Reviewed-by: iwalulya, ayang
This commit is contained in:
Thomas Schatzl 2022-09-06 13:41:37 +00:00
parent 6a1e98cbf7
commit b2067e63da

View File

@ -1271,6 +1271,22 @@ class G1MergeHeapRootsTask : public WorkerTask {
"Bitmap should have no mark for region %u", hr->hrm_index());
}
bool should_clear_region(HeapRegion* hr) const {
// The bitmap for young regions must obviously be clear as we never mark through them;
// old regions are only in the collection set after the concurrent cycle completed,
// so their bitmaps must also be clear except when the pause occurs during the
// Concurrent Cleanup for Next Mark phase. Only at that point the region's bitmap may
// contain marks while being in the collection set at the same time.
//
// There is one exception: shutdown might have aborted the Concurrent Cleanup for Next
// Mark phase midway, which might have also left stale marks in old generation regions.
// There might actually have been scheduled multiple collections, but at that point we do
// not care that much about performance and just do the work multiple times if needed.
return (_g1h->collector_state()->clearing_bitmap() ||
_g1h->concurrent_mark_is_terminating()) &&
hr->is_old();
}
public:
G1ClearBitmapClosure(G1CollectedHeap* g1h) : _g1h(g1h) { }
@ -1279,13 +1295,7 @@ class G1MergeHeapRootsTask : public WorkerTask {
// Evacuation failure uses the bitmap to record evacuation failed objects,
// so the bitmap for the regions in the collection set must be cleared if not already.
//
// A clear bitmap is obvious for young regions as we never mark through them;
// old regions are only in the collection set after the concurrent cycle completed,
// so their bitmaps must also be clear except when the pause occurs during the
// concurrent bitmap clear. At that point the region's bitmap may contain marks
// while being in the collection set at the same time.
if (_g1h->collector_state()->clearing_bitmap() && hr->is_old()) {
if (should_clear_region(hr)) {
_g1h->clear_bitmap_for_region(hr);
} else {
assert_bitmap_clear(hr, _g1h->concurrent_mark()->mark_bitmap());