< prev index next >

src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp

Print this page
rev 60594 : [mq]: 8240556-abort-conc-mark-new

@@ -40,10 +40,11 @@
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/vmThread.hpp"
 #include "utilities/debug.hpp"
+#include "utilities/formatBuffer.hpp"
 #include "utilities/ticks.hpp"
 
 G1ConcurrentMarkThread::G1ConcurrentMarkThread(G1ConcurrentMark* cm) :
   ConcurrentGCThread(),
   _vtime_start(0.0),

@@ -53,10 +54,35 @@
 {
   set_name("G1 Main Marker");
   create_and_start();
 }
 
+void G1ConcurrentMarkThread::set_idle() {
+  assert(_state != StartMark && _state != StartUndo, "must not be starting a new cycle");
+  _state = Idle;
+}
+
+void G1ConcurrentMarkThread::set_started(bool full_cycle) {
+  assert(_state == Idle, "cycle in progress");
+  _state = full_cycle ? StartMark : StartUndo;
+}
+
+void G1ConcurrentMarkThread::set_in_progress() {
+  assert(_state == StartMark || _state == StartUndo, "must be starting a cycle");
+  _state = InProgress;
+}
+
+bool G1ConcurrentMarkThread::idle() const { return _state == Idle; }
+
+bool G1ConcurrentMarkThread::started() const {
+  return _state == StartMark || _state == StartUndo;
+}
+
+bool G1ConcurrentMarkThread::in_progress() const {
+  return _state == InProgress;
+}
+
 class CMRemark : public VoidClosure {
   G1ConcurrentMark* _cm;
 public:
   CMRemark(G1ConcurrentMark* cm) : _cm(cm) {}
 

@@ -133,20 +159,29 @@
 
 void G1ConcurrentMarkThread::run_service() {
   _vtime_start = os::elapsedVTime();
 
   while (!should_terminate()) {
-    if (wait_for_next_cycle()) {
+    Command cmd = wait_for_next_cycle();
+    if (cmd == Terminate) {
       break;
     }
 
     GCIdMark gc_id_mark;
-    GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
+    GCTraceConcTime(Info, gc) tt(FormatBuffer<128>("Concurrent %s Cycle",
+                                                   cmd == MarkCycle ? "Mark" : "Undo"));
 
     concurrent_cycle_start();
-    full_concurrent_cycle_do();
-    concurrent_cycle_end();
+
+    if (cmd == MarkCycle) {
+      mark_concurrent_cycle_do();
+    } else {
+      assert(cmd == UndoCycle, "Must be command to undo concurrent start but is %d", cmd);
+      undo_concurrent_cycle_do();
+    }
+
+    concurrent_cycle_end(cmd == MarkCycle && !_cm->has_aborted());
 
     _vtime_accum = (os::elapsedVTime() - _vtime_start);
   }
   _cm->root_regions()->cancel_scan();
 }

@@ -154,23 +189,35 @@
 void G1ConcurrentMarkThread::stop_service() {
   MutexLocker ml(CGC_lock, Mutex::_no_safepoint_check_flag);
   CGC_lock->notify_all();
 }
 
-bool G1ConcurrentMarkThread::wait_for_next_cycle() {
+G1ConcurrentMarkThread::Command G1ConcurrentMarkThread::wait_for_next_cycle() {
   assert(!in_progress(), "should have been cleared");
 
   MonitorLocker ml(CGC_lock, Mutex::_no_safepoint_check_flag);
   while (!started() && !should_terminate()) {
     ml.wait();
   }
 
+  Command result;
+  if (should_terminate()) {
+    result = Terminate;
+  } else if (_state == StartMark) {
+    result = MarkCycle;
+  } else if (_state == StartUndo) {
+    result = UndoCycle;
+  } else {
+    log_error(gc)("Invalid command for concurrent cycle");
+    ShouldNotReachHere();
+  }
+
   if (started()) {
     set_in_progress();
   }
 
-  return should_terminate();
+  return result;
 }
 
 bool G1ConcurrentMarkThread::phase_clear_cld_claimed_marks() {
   G1ConcPhaseTimer p(_cm, "Concurrent Clear Claimed Marks");
   ClassLoaderDataGraph::clear_claimed_marks();

@@ -236,11 +283,11 @@
 
 void G1ConcurrentMarkThread::concurrent_cycle_start() {
   _cm->concurrent_cycle_start();
 }
 
-void G1ConcurrentMarkThread::full_concurrent_cycle_do() {
+void G1ConcurrentMarkThread::mark_concurrent_cycle_do() {
   HandleMark hm(Thread::current());
   ResourceMark rm;
 
   // Phase 1: Clear CLD claimed marks.
   phase_clear_cld_claimed_marks();

@@ -292,17 +339,29 @@
 
   // Phase 10: Clear bitmap for next mark.
   phase_clear_bitmap_for_next_mark();
 }
 
-void G1ConcurrentMarkThread::concurrent_cycle_end() {
+void G1ConcurrentMarkThread::undo_concurrent_cycle_do() {
+  HandleMark hm(Thread::current());
+  ResourceMark rm;
+
+  // We can (and should) abort if there has been a concurrent cycle abort for
+  // some reason.
+  if (_cm->has_aborted()) { return; }
+
+  // Phase 1: Clear bitmap for next mark.
+  phase_clear_bitmap_for_next_mark();
+}
+
+void G1ConcurrentMarkThread::concurrent_cycle_end(bool mark_cycle_completed) {
   // Update the number of full collections that have been
   // completed. This will also notify the G1OldGCCount_lock in case a
   // Java thread is waiting for a full GC to happen (e.g., it
   // called System.gc() with +ExplicitGCInvokesConcurrent).
   SuspendibleThreadSetJoiner sts_join;
   G1CollectedHeap::heap()->increment_old_marking_cycles_completed(true /* concurrent */,
-                                                                  !_cm->has_aborted());
+                                                                  mark_cycle_completed /* heap_examined */);
 
   _cm->concurrent_cycle_end();
   ConcurrentGCBreakpoints::notify_active_to_idle();
 }
< prev index next >