< prev index next >
src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp
Print this page
rev 60594 : [mq]: 8240556-abort-conc-mark-new
*** 40,49 ****
--- 40,50 ----
#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,62 ****
--- 54,88 ----
{
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,152 ****
void G1ConcurrentMarkThread::run_service() {
_vtime_start = os::elapsedVTime();
while (!should_terminate()) {
! if (wait_for_next_cycle()) {
break;
}
GCIdMark gc_id_mark;
! GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
concurrent_cycle_start();
! full_concurrent_cycle_do();
! concurrent_cycle_end();
_vtime_accum = (os::elapsedVTime() - _vtime_start);
}
_cm->root_regions()->cancel_scan();
}
--- 159,187 ----
void G1ConcurrentMarkThread::run_service() {
_vtime_start = os::elapsedVTime();
while (!should_terminate()) {
! Command cmd = wait_for_next_cycle();
! if (cmd == Terminate) {
break;
}
GCIdMark gc_id_mark;
! GCTraceConcTime(Info, gc) tt(FormatBuffer<128>("Concurrent %s Cycle",
! cmd == MarkCycle ? "Mark" : "Undo"));
concurrent_cycle_start();
!
! 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,176 ****
void G1ConcurrentMarkThread::stop_service() {
MutexLocker ml(CGC_lock, Mutex::_no_safepoint_check_flag);
CGC_lock->notify_all();
}
! bool 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();
}
if (started()) {
set_in_progress();
}
! return should_terminate();
}
bool G1ConcurrentMarkThread::phase_clear_cld_claimed_marks() {
G1ConcPhaseTimer p(_cm, "Concurrent Clear Claimed Marks");
ClassLoaderDataGraph::clear_claimed_marks();
--- 189,223 ----
void G1ConcurrentMarkThread::stop_service() {
MutexLocker ml(CGC_lock, Mutex::_no_safepoint_check_flag);
CGC_lock->notify_all();
}
! 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 result;
}
bool G1ConcurrentMarkThread::phase_clear_cld_claimed_marks() {
G1ConcPhaseTimer p(_cm, "Concurrent Clear Claimed Marks");
ClassLoaderDataGraph::clear_claimed_marks();
*** 236,246 ****
void G1ConcurrentMarkThread::concurrent_cycle_start() {
_cm->concurrent_cycle_start();
}
! void G1ConcurrentMarkThread::full_concurrent_cycle_do() {
HandleMark hm(Thread::current());
ResourceMark rm;
// Phase 1: Clear CLD claimed marks.
phase_clear_cld_claimed_marks();
--- 283,293 ----
void G1ConcurrentMarkThread::concurrent_cycle_start() {
_cm->concurrent_cycle_start();
}
! void G1ConcurrentMarkThread::mark_concurrent_cycle_do() {
HandleMark hm(Thread::current());
ResourceMark rm;
// Phase 1: Clear CLD claimed marks.
phase_clear_cld_claimed_marks();
*** 292,308 ****
// Phase 10: Clear bitmap for next mark.
phase_clear_bitmap_for_next_mark();
}
! void G1ConcurrentMarkThread::concurrent_cycle_end() {
// 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());
_cm->concurrent_cycle_end();
ConcurrentGCBreakpoints::notify_active_to_idle();
}
--- 339,367 ----
// Phase 10: Clear bitmap for next mark.
phase_clear_bitmap_for_next_mark();
}
! 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 */,
! mark_cycle_completed /* heap_examined */);
_cm->concurrent_cycle_end();
ConcurrentGCBreakpoints::notify_active_to_idle();
}
< prev index next >