94
95 class GCConcPhaseTimer : StackObj {
96 G1ConcurrentMark* _cm;
97
98 public:
99 GCConcPhaseTimer(G1ConcurrentMark* cm, const char* title) : _cm(cm) {
100 _cm->register_concurrent_phase_start(title);
101 }
102
103 ~GCConcPhaseTimer() {
104 _cm->register_concurrent_phase_end();
105 }
106 };
107
108 void ConcurrentMarkThread::run_service() {
109 _vtime_start = os::elapsedVTime();
110
111 G1CollectedHeap* g1h = G1CollectedHeap::heap();
112 G1CollectorPolicy* g1_policy = g1h->g1_policy();
113
114 while (!_should_terminate) {
115 // wait until started is set.
116 sleepBeforeNextCycle();
117 if (_should_terminate) {
118 _cm->root_regions()->cancel_scan();
119 break;
120 }
121
122 assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
123 {
124 ResourceMark rm;
125 HandleMark hm;
126 double cycle_start = os::elapsedVTime();
127
128 {
129 GCConcPhaseTimer(_cm, "Concurrent Clearing of Claimed Marks");
130 ClassLoaderDataGraph::clear_claimed_marks();
131 }
132
133 // We have to ensure that we finish scanning the root regions
134 // before the next GC takes place. To ensure this we have to
135 // make sure that we do not join the STS until the root regions
136 // have been scanned. If we did then it's possible that a
137 // subsequent GC could block us from joining the STS and proceed
278 // called System.gc() with +ExplicitGCInvokesConcurrent).
279 {
280 SuspendibleThreadSetJoiner sts_join;
281 g1h->increment_old_marking_cycles_completed(true /* concurrent */);
282 g1h->register_concurrent_cycle_end();
283 }
284 }
285 }
286
287 void ConcurrentMarkThread::stop_service() {
288 MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
289 CGC_lock->notify_all();
290 }
291
292 void ConcurrentMarkThread::sleepBeforeNextCycle() {
293 // We join here because we don't want to do the "shouldConcurrentMark()"
294 // below while the world is otherwise stopped.
295 assert(!in_progress(), "should have been cleared");
296
297 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
298 while (!started() && !_should_terminate) {
299 CGC_lock->wait(Mutex::_no_safepoint_check_flag);
300 }
301
302 if (started()) {
303 set_in_progress();
304 }
305 }
306
307 // Note: As is the case with CMS - this method, although exported
308 // by the ConcurrentMarkThread, which is a non-JavaThread, can only
309 // be called by a JavaThread. Currently this is done at vm creation
310 // time (post-vm-init) by the main/Primordial (Java)Thread.
311 // XXX Consider changing this in the future to allow the CM thread
312 // itself to create this thread?
313 void ConcurrentMarkThread::makeSurrogateLockerThread(TRAPS) {
314 assert(UseG1GC, "SLT thread needed only for concurrent GC");
315 assert(THREAD->is_Java_thread(), "must be a Java thread");
316 assert(_slt == NULL, "SLT already created");
317 _slt = SurrogateLockerThread::make(THREAD);
318 }
|
94
95 class GCConcPhaseTimer : StackObj {
96 G1ConcurrentMark* _cm;
97
98 public:
99 GCConcPhaseTimer(G1ConcurrentMark* cm, const char* title) : _cm(cm) {
100 _cm->register_concurrent_phase_start(title);
101 }
102
103 ~GCConcPhaseTimer() {
104 _cm->register_concurrent_phase_end();
105 }
106 };
107
108 void ConcurrentMarkThread::run_service() {
109 _vtime_start = os::elapsedVTime();
110
111 G1CollectedHeap* g1h = G1CollectedHeap::heap();
112 G1CollectorPolicy* g1_policy = g1h->g1_policy();
113
114 while (!should_terminate()) {
115 // wait until started is set.
116 sleepBeforeNextCycle();
117 if (should_terminate()) {
118 _cm->root_regions()->cancel_scan();
119 break;
120 }
121
122 assert(GCId::current() != GCId::undefined(), "GC id should have been set up by the initial mark GC.");
123 {
124 ResourceMark rm;
125 HandleMark hm;
126 double cycle_start = os::elapsedVTime();
127
128 {
129 GCConcPhaseTimer(_cm, "Concurrent Clearing of Claimed Marks");
130 ClassLoaderDataGraph::clear_claimed_marks();
131 }
132
133 // We have to ensure that we finish scanning the root regions
134 // before the next GC takes place. To ensure this we have to
135 // make sure that we do not join the STS until the root regions
136 // have been scanned. If we did then it's possible that a
137 // subsequent GC could block us from joining the STS and proceed
278 // called System.gc() with +ExplicitGCInvokesConcurrent).
279 {
280 SuspendibleThreadSetJoiner sts_join;
281 g1h->increment_old_marking_cycles_completed(true /* concurrent */);
282 g1h->register_concurrent_cycle_end();
283 }
284 }
285 }
286
287 void ConcurrentMarkThread::stop_service() {
288 MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
289 CGC_lock->notify_all();
290 }
291
292 void ConcurrentMarkThread::sleepBeforeNextCycle() {
293 // We join here because we don't want to do the "shouldConcurrentMark()"
294 // below while the world is otherwise stopped.
295 assert(!in_progress(), "should have been cleared");
296
297 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
298 while (!started() && !should_terminate()) {
299 CGC_lock->wait(Mutex::_no_safepoint_check_flag);
300 }
301
302 if (started()) {
303 set_in_progress();
304 }
305 }
306
307 // Note: As is the case with CMS - this method, although exported
308 // by the ConcurrentMarkThread, which is a non-JavaThread, can only
309 // be called by a JavaThread. Currently this is done at vm creation
310 // time (post-vm-init) by the main/Primordial (Java)Thread.
311 // XXX Consider changing this in the future to allow the CM thread
312 // itself to create this thread?
313 void ConcurrentMarkThread::makeSurrogateLockerThread(TRAPS) {
314 assert(UseG1GC, "SLT thread needed only for concurrent GC");
315 assert(THREAD->is_Java_thread(), "must be a Java thread");
316 assert(_slt == NULL, "SLT already created");
317 _slt = SurrogateLockerThread::make(THREAD);
318 }
|