Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp @ 20804:7848fc12602b
Merge with jdk8u40-b25
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Tue, 07 Apr 2015 14:58:49 +0200 |
parents | 7df07d855c8e |
children |
comparison
equal
deleted
inserted
replaced
20184:84105dcdb05b | 20804:7848fc12602b |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" | 27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
28 #include "gc_implementation/g1/g1CollectorPolicy.hpp" | 28 #include "gc_implementation/g1/g1CollectorPolicy.hpp" |
29 #include "gc_implementation/g1/g1Log.hpp" | 29 #include "gc_implementation/g1/g1Log.hpp" |
30 #include "gc_implementation/g1/g1MMUTracker.hpp" | 30 #include "gc_implementation/g1/g1MMUTracker.hpp" |
31 #include "gc_implementation/g1/vm_operations_g1.hpp" | 31 #include "gc_implementation/g1/vm_operations_g1.hpp" |
32 #include "gc_implementation/shared/gcTrace.hpp" | |
32 #include "memory/resourceArea.hpp" | 33 #include "memory/resourceArea.hpp" |
33 #include "runtime/vmThread.hpp" | 34 #include "runtime/vmThread.hpp" |
34 | 35 |
35 // ======= Concurrent Mark Thread ======== | 36 // ======= Concurrent Mark Thread ======== |
36 | 37 |
107 // correctness issue. | 108 // correctness issue. |
108 | 109 |
109 double scan_start = os::elapsedTime(); | 110 double scan_start = os::elapsedTime(); |
110 if (!cm()->has_aborted()) { | 111 if (!cm()->has_aborted()) { |
111 if (G1Log::fine()) { | 112 if (G1Log::fine()) { |
112 gclog_or_tty->date_stamp(PrintGCDateStamps); | 113 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
113 gclog_or_tty->stamp(PrintGCTimeStamps); | |
114 gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]"); | 114 gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]"); |
115 } | 115 } |
116 | 116 |
117 _cm->scanRootRegions(); | 117 _cm->scanRootRegions(); |
118 | 118 |
119 double scan_end = os::elapsedTime(); | 119 double scan_end = os::elapsedTime(); |
120 if (G1Log::fine()) { | 120 if (G1Log::fine()) { |
121 gclog_or_tty->date_stamp(PrintGCDateStamps); | 121 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
122 gclog_or_tty->stamp(PrintGCTimeStamps); | |
123 gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]", | 122 gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]", |
124 scan_end - scan_start); | 123 scan_end - scan_start); |
125 } | 124 } |
126 } | 125 } |
127 | 126 |
128 double mark_start_sec = os::elapsedTime(); | 127 double mark_start_sec = os::elapsedTime(); |
129 if (G1Log::fine()) { | 128 if (G1Log::fine()) { |
130 gclog_or_tty->date_stamp(PrintGCDateStamps); | 129 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
131 gclog_or_tty->stamp(PrintGCTimeStamps); | |
132 gclog_or_tty->print_cr("[GC concurrent-mark-start]"); | 130 gclog_or_tty->print_cr("[GC concurrent-mark-start]"); |
133 } | 131 } |
134 | 132 |
135 int iter = 0; | 133 int iter = 0; |
136 do { | 134 do { |
149 jlong sleep_time_ms = mmu_tracker->when_ms(now, remark_prediction_ms); | 147 jlong sleep_time_ms = mmu_tracker->when_ms(now, remark_prediction_ms); |
150 os::sleep(current_thread, sleep_time_ms, false); | 148 os::sleep(current_thread, sleep_time_ms, false); |
151 } | 149 } |
152 | 150 |
153 if (G1Log::fine()) { | 151 if (G1Log::fine()) { |
154 gclog_or_tty->date_stamp(PrintGCDateStamps); | 152 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
155 gclog_or_tty->stamp(PrintGCTimeStamps); | |
156 gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf secs]", | 153 gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf secs]", |
157 mark_end_sec - mark_start_sec); | 154 mark_end_sec - mark_start_sec); |
158 } | 155 } |
159 | 156 |
160 CMCheckpointRootsFinalClosure final_cl(_cm); | 157 CMCheckpointRootsFinalClosure final_cl(_cm); |
165 if (G1TraceMarkStackOverflow) { | 162 if (G1TraceMarkStackOverflow) { |
166 gclog_or_tty->print_cr("Restarting conc marking because of MS overflow " | 163 gclog_or_tty->print_cr("Restarting conc marking because of MS overflow " |
167 "in remark (restart #%d).", iter); | 164 "in remark (restart #%d).", iter); |
168 } | 165 } |
169 if (G1Log::fine()) { | 166 if (G1Log::fine()) { |
170 gclog_or_tty->date_stamp(PrintGCDateStamps); | 167 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
171 gclog_or_tty->stamp(PrintGCTimeStamps); | |
172 gclog_or_tty->print_cr("[GC concurrent-mark-restart-for-overflow]"); | 168 gclog_or_tty->print_cr("[GC concurrent-mark-restart-for-overflow]"); |
173 } | 169 } |
174 } | 170 } |
175 } while (cm()->restart_for_overflow()); | 171 } while (cm()->restart_for_overflow()); |
176 | 172 |
192 VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */); | 188 VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */); |
193 VMThread::execute(&op); | 189 VMThread::execute(&op); |
194 } else { | 190 } else { |
195 // We don't want to update the marking status if a GC pause | 191 // We don't want to update the marking status if a GC pause |
196 // is already underway. | 192 // is already underway. |
197 _sts.join(); | 193 SuspendibleThreadSetJoiner sts; |
198 g1h->set_marking_complete(); | 194 g1h->set_marking_complete(); |
199 _sts.leave(); | |
200 } | 195 } |
201 | 196 |
202 // Check if cleanup set the free_regions_coming flag. If it | 197 // Check if cleanup set the free_regions_coming flag. If it |
203 // hasn't, we can just skip the next step. | 198 // hasn't, we can just skip the next step. |
204 if (g1h->free_regions_coming()) { | 199 if (g1h->free_regions_coming()) { |
210 // place, it would wait for us to process the regions | 205 // place, it would wait for us to process the regions |
211 // reclaimed by cleanup. | 206 // reclaimed by cleanup. |
212 | 207 |
213 double cleanup_start_sec = os::elapsedTime(); | 208 double cleanup_start_sec = os::elapsedTime(); |
214 if (G1Log::fine()) { | 209 if (G1Log::fine()) { |
215 gclog_or_tty->date_stamp(PrintGCDateStamps); | 210 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
216 gclog_or_tty->stamp(PrintGCTimeStamps); | |
217 gclog_or_tty->print_cr("[GC concurrent-cleanup-start]"); | 211 gclog_or_tty->print_cr("[GC concurrent-cleanup-start]"); |
218 } | 212 } |
219 | 213 |
220 // Now do the concurrent cleanup operation. | 214 // Now do the concurrent cleanup operation. |
221 _cm->completeCleanup(); | 215 _cm->completeCleanup(); |
231 // the GC workers finishing. | 225 // the GC workers finishing. |
232 g1h->reset_free_regions_coming(); | 226 g1h->reset_free_regions_coming(); |
233 | 227 |
234 double cleanup_end_sec = os::elapsedTime(); | 228 double cleanup_end_sec = os::elapsedTime(); |
235 if (G1Log::fine()) { | 229 if (G1Log::fine()) { |
236 gclog_or_tty->date_stamp(PrintGCDateStamps); | 230 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
237 gclog_or_tty->stamp(PrintGCTimeStamps); | |
238 gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf secs]", | 231 gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf secs]", |
239 cleanup_end_sec - cleanup_start_sec); | 232 cleanup_end_sec - cleanup_start_sec); |
240 } | 233 } |
241 } | 234 } |
242 guarantee(cm()->cleanup_list_is_empty(), | 235 guarantee(cm()->cleanup_list_is_empty(), |
264 // abort() will have completed and has_aborted() will return | 257 // abort() will have completed and has_aborted() will return |
265 // true to prevent us from calling | 258 // true to prevent us from calling |
266 // record_concurrent_mark_cleanup_completed() (and, in fact, it's | 259 // record_concurrent_mark_cleanup_completed() (and, in fact, it's |
267 // not needed any more as the concurrent mark state has been | 260 // not needed any more as the concurrent mark state has been |
268 // already reset). | 261 // already reset). |
269 _sts.join(); | 262 { |
270 if (!cm()->has_aborted()) { | 263 SuspendibleThreadSetJoiner sts; |
271 g1_policy->record_concurrent_mark_cleanup_completed(); | 264 if (!cm()->has_aborted()) { |
272 } | 265 g1_policy->record_concurrent_mark_cleanup_completed(); |
273 _sts.leave(); | 266 } |
267 } | |
274 | 268 |
275 if (cm()->has_aborted()) { | 269 if (cm()->has_aborted()) { |
276 if (G1Log::fine()) { | 270 if (G1Log::fine()) { |
277 gclog_or_tty->date_stamp(PrintGCDateStamps); | 271 gclog_or_tty->gclog_stamp(cm()->concurrent_gc_id()); |
278 gclog_or_tty->stamp(PrintGCTimeStamps); | |
279 gclog_or_tty->print_cr("[GC concurrent-mark-abort]"); | 272 gclog_or_tty->print_cr("[GC concurrent-mark-abort]"); |
280 } | 273 } |
281 } | 274 } |
282 | 275 |
283 // We now want to allow clearing of the marking bitmap to be | 276 // We now want to allow clearing of the marking bitmap to be |
284 // suspended by a collection pause. | 277 // suspended by a collection pause. |
285 _sts.join(); | 278 // We may have aborted just before the remark. Do not bother clearing the |
286 _cm->clearNextBitmap(); | 279 // bitmap then, as it has been done during mark abort. |
287 _sts.leave(); | 280 if (!cm()->has_aborted()) { |
281 SuspendibleThreadSetJoiner sts; | |
282 _cm->clearNextBitmap(); | |
283 } else { | |
284 assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear"); | |
285 } | |
288 } | 286 } |
289 | 287 |
290 // Update the number of full collections that have been | 288 // Update the number of full collections that have been |
291 // completed. This will also notify the FullGCCount_lock in case a | 289 // completed. This will also notify the FullGCCount_lock in case a |
292 // Java thread is waiting for a full GC to happen (e.g., it | 290 // Java thread is waiting for a full GC to happen (e.g., it |
293 // called System.gc() with +ExplicitGCInvokesConcurrent). | 291 // called System.gc() with +ExplicitGCInvokesConcurrent). |
294 _sts.join(); | 292 { |
295 g1h->increment_old_marking_cycles_completed(true /* concurrent */); | 293 SuspendibleThreadSetJoiner sts; |
296 g1h->register_concurrent_cycle_end(); | 294 g1h->increment_old_marking_cycles_completed(true /* concurrent */); |
297 _sts.leave(); | 295 g1h->register_concurrent_cycle_end(); |
296 } | |
298 } | 297 } |
299 assert(_should_terminate, "just checking"); | 298 assert(_should_terminate, "just checking"); |
300 | 299 |
301 terminate(); | 300 terminate(); |
302 } | |
303 | |
304 | |
305 void ConcurrentMarkThread::yield() { | |
306 _sts.yield("Concurrent Mark"); | |
307 } | 301 } |
308 | 302 |
309 void ConcurrentMarkThread::stop() { | 303 void ConcurrentMarkThread::stop() { |
310 { | 304 { |
311 MutexLockerEx ml(Terminator_lock); | 305 MutexLockerEx ml(Terminator_lock); |