40 #include "logging/log.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "runtime/handles.inline.hpp"
43 #include "runtime/vmThread.hpp"
44 #include "utilities/debug.hpp"
45
46 // ======= Concurrent Mark Thread ========
47
48 // Check order in EXPAND_CURRENT_PHASES
49 STATIC_ASSERT(ConcurrentGCPhaseManager::UNCONSTRAINED_PHASE <
50 ConcurrentGCPhaseManager::IDLE_PHASE);
51
52 #define EXPAND_CONCURRENT_PHASES(expander) \
53 expander(ANY, = ConcurrentGCPhaseManager::UNCONSTRAINED_PHASE, NULL) \
54 expander(IDLE, = ConcurrentGCPhaseManager::IDLE_PHASE, NULL) \
55 expander(CONCURRENT_CYCLE,, "Concurrent Cycle") \
56 expander(CLEAR_CLAIMED_MARKS,, "Concurrent Clear Claimed Marks") \
57 expander(SCAN_ROOT_REGIONS,, "Concurrent Scan Root Regions") \
58 expander(CONCURRENT_MARK,, "Concurrent Mark") \
59 expander(MARK_FROM_ROOTS,, "Concurrent Mark From Roots") \
60 expander(BEFORE_REMARK,, NULL) \
61 expander(REMARK,, NULL) \
62 expander(REBUILD_REMEMBERED_SETS,, "Concurrent Rebuild Remembered Sets") \
63 expander(CLEANUP_FOR_NEXT_MARK,, "Concurrent Cleanup for Next Mark") \
64 /* */
65
66 class G1ConcurrentPhase : public AllStatic {
67 public:
68 enum {
69 #define CONCURRENT_PHASE_ENUM(tag, value, ignore_title) tag value,
70 EXPAND_CONCURRENT_PHASES(CONCURRENT_PHASE_ENUM)
71 #undef CONCURRENT_PHASE_ENUM
72 PHASE_ID_LIMIT
73 };
74 };
75
76 // The CM thread is created when the G1 garbage collector is used
77
78 G1ConcurrentMarkThread::G1ConcurrentMarkThread(G1ConcurrentMark* cm) :
79 ConcurrentGCThread(),
292 // the "end" logging is inside the loop and not at the end of
293 // a scope. Also, the timer doesn't support nesting.
294 // Mimicking the same log output instead.
295 {
296 G1ConcPhaseManager mark_manager(G1ConcurrentPhase::CONCURRENT_MARK, this);
297 jlong mark_start = os::elapsed_counter();
298 const char* cm_title = lookup_concurrent_phase_title(G1ConcurrentPhase::CONCURRENT_MARK);
299 log_info(gc, marking)("%s (%.3fs)",
300 cm_title,
301 TimeHelper::counter_to_seconds(mark_start));
302 for (uint iter = 1; !_cm->has_aborted(); ++iter) {
303 // Concurrent marking.
304 {
305 G1ConcPhase p(G1ConcurrentPhase::MARK_FROM_ROOTS, this);
306 _cm->mark_from_roots();
307 }
308 if (_cm->has_aborted()) {
309 break;
310 }
311
312 // Provide a control point after mark_from_roots.
313 {
314 G1ConcPhaseManager p(G1ConcurrentPhase::BEFORE_REMARK, this);
315 }
316 if (_cm->has_aborted()) {
317 break;
318 }
319
320 // Delay remark pause for MMU.
321 double mark_end_time = os::elapsedVTime();
322 jlong mark_end = os::elapsed_counter();
323 _vtime_mark_accum += (mark_end_time - cycle_start);
324 delay_to_keep_mmu(g1_policy, true /* remark */);
325 if (_cm->has_aborted()) {
326 break;
327 }
328
329 // Pause Remark.
330 log_info(gc, marking)("%s (%.3fs, %.3fs) %.3fms",
331 cm_title,
332 TimeHelper::counter_to_seconds(mark_start),
|
40 #include "logging/log.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "runtime/handles.inline.hpp"
43 #include "runtime/vmThread.hpp"
44 #include "utilities/debug.hpp"
45
46 // ======= Concurrent Mark Thread ========
47
48 // Check order in EXPAND_CURRENT_PHASES
49 STATIC_ASSERT(ConcurrentGCPhaseManager::UNCONSTRAINED_PHASE <
50 ConcurrentGCPhaseManager::IDLE_PHASE);
51
52 #define EXPAND_CONCURRENT_PHASES(expander) \
53 expander(ANY, = ConcurrentGCPhaseManager::UNCONSTRAINED_PHASE, NULL) \
54 expander(IDLE, = ConcurrentGCPhaseManager::IDLE_PHASE, NULL) \
55 expander(CONCURRENT_CYCLE,, "Concurrent Cycle") \
56 expander(CLEAR_CLAIMED_MARKS,, "Concurrent Clear Claimed Marks") \
57 expander(SCAN_ROOT_REGIONS,, "Concurrent Scan Root Regions") \
58 expander(CONCURRENT_MARK,, "Concurrent Mark") \
59 expander(MARK_FROM_ROOTS,, "Concurrent Mark From Roots") \
60 expander(PRECLEAN,, "Concurrent Preclean") \
61 expander(BEFORE_REMARK,, NULL) \
62 expander(REMARK,, NULL) \
63 expander(REBUILD_REMEMBERED_SETS,, "Concurrent Rebuild Remembered Sets") \
64 expander(CLEANUP_FOR_NEXT_MARK,, "Concurrent Cleanup for Next Mark") \
65 /* */
66
67 class G1ConcurrentPhase : public AllStatic {
68 public:
69 enum {
70 #define CONCURRENT_PHASE_ENUM(tag, value, ignore_title) tag value,
71 EXPAND_CONCURRENT_PHASES(CONCURRENT_PHASE_ENUM)
72 #undef CONCURRENT_PHASE_ENUM
73 PHASE_ID_LIMIT
74 };
75 };
76
77 // The CM thread is created when the G1 garbage collector is used
78
79 G1ConcurrentMarkThread::G1ConcurrentMarkThread(G1ConcurrentMark* cm) :
80 ConcurrentGCThread(),
293 // the "end" logging is inside the loop and not at the end of
294 // a scope. Also, the timer doesn't support nesting.
295 // Mimicking the same log output instead.
296 {
297 G1ConcPhaseManager mark_manager(G1ConcurrentPhase::CONCURRENT_MARK, this);
298 jlong mark_start = os::elapsed_counter();
299 const char* cm_title = lookup_concurrent_phase_title(G1ConcurrentPhase::CONCURRENT_MARK);
300 log_info(gc, marking)("%s (%.3fs)",
301 cm_title,
302 TimeHelper::counter_to_seconds(mark_start));
303 for (uint iter = 1; !_cm->has_aborted(); ++iter) {
304 // Concurrent marking.
305 {
306 G1ConcPhase p(G1ConcurrentPhase::MARK_FROM_ROOTS, this);
307 _cm->mark_from_roots();
308 }
309 if (_cm->has_aborted()) {
310 break;
311 }
312
313 if (G1UseReferencePrecleaning) {
314 {
315 G1ConcPhase p(G1ConcurrentPhase::PRECLEAN, this);
316 _cm->preclean();
317 }
318 }
319
320 // Provide a control point before remark.
321 {
322 G1ConcPhaseManager p(G1ConcurrentPhase::BEFORE_REMARK, this);
323 }
324 if (_cm->has_aborted()) {
325 break;
326 }
327
328 // Delay remark pause for MMU.
329 double mark_end_time = os::elapsedVTime();
330 jlong mark_end = os::elapsed_counter();
331 _vtime_mark_accum += (mark_end_time - cycle_start);
332 delay_to_keep_mmu(g1_policy, true /* remark */);
333 if (_cm->has_aborted()) {
334 break;
335 }
336
337 // Pause Remark.
338 log_info(gc, marking)("%s (%.3fs, %.3fs) %.3fms",
339 cm_title,
340 TimeHelper::counter_to_seconds(mark_start),
|