8048085: Aborting marking just before remark results in useless additional clearing of the next mark bitmap
Summary: Skip clearing the next bitmap if we just recently aborted since the full GC already clears this bitmap.
Reviewed-by: brutisso
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Jul 21 09:59:37 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Jul 21 09:59:46 2014 +0200
@@ -891,6 +891,10 @@
guarantee(!g1h->mark_in_progress(), "invariant");
}
+bool ConcurrentMark::nextMarkBitmapIsClear() {
+ return _nextMarkBitMap->getNextMarkedWordAddress(_heap_start, _heap_end) == _heap_end;
+}
+
class NoteStartOfMarkHRClosure: public HeapRegionClosure {
public:
bool doHeapRegion(HeapRegion* r) {
@@ -3358,7 +3362,8 @@
// abandon current marking iteration due to a Full GC
void ConcurrentMark::abort() {
- // Clear all marks to force marking thread to do nothing
+ // Clear all marks in the next bitmap for the next marking cycle. This will allow us to skip the next
+ // concurrent bitmap clearing.
_nextMarkBitMap->clearAll();
// Note we cannot clear the previous marking bitmap here
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Mon Jul 21 09:59:37 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Mon Jul 21 09:59:46 2014 +0200
@@ -736,6 +736,9 @@
// Clear the next marking bitmap (will be called concurrently).
void clearNextBitmap();
+ // Return whether the next mark bitmap has no marks set.
+ bool nextMarkBitmapIsClear();
+
// These two do the work that needs to be done before and after the
// initial root checkpoint. Since this checkpoint can be done at two
// different points (i.e. an explicit pause or piggy-backed on a
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Jul 21 09:59:37 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Jul 21 09:59:46 2014 +0200
@@ -277,9 +277,13 @@
// We now want to allow clearing of the marking bitmap to be
// suspended by a collection pause.
- {
+ // We may have aborted just before the remark. Do not bother clearing the
+ // bitmap then, as it has been done during mark abort.
+ if (!cm()->has_aborted()) {
SuspendibleThreadSetJoiner sts;
_cm->clearNextBitmap();
+ } else {
+ assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear");
}
}