Skip to content

Commit c97871f

Browse files
committed
Version 3
1 parent 00f385d commit c97871f

File tree

2 files changed

+29
-32
lines changed

2 files changed

+29
-32
lines changed

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

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,7 @@ class G1ConcPhaseTimer : public GCTraceConcTimeImpl<LogLevel::Info, LOG_TAGS(gc,
134134
void G1ConcurrentMarkThread::run_service() {
135135
_vtime_start = os::elapsedVTime();
136136

137-
while (!should_terminate()) {
138-
if (wait_for_next_cycle()) {
139-
break;
140-
}
137+
while (wait_for_next_cycle()) {
141138

142139
GCIdMark gc_id_mark;
143140
GCTraceConcTime(Info, gc) tt("Concurrent Cycle");
@@ -168,13 +165,12 @@ bool G1ConcurrentMarkThread::wait_for_next_cycle() {
168165
set_in_progress();
169166
}
170167

171-
return should_terminate();
168+
return !should_terminate();
172169
}
173170

174-
bool G1ConcurrentMarkThread::phase_clear_cld_claimed_marks() {
171+
void G1ConcurrentMarkThread::phase_clear_cld_claimed_marks() {
175172
G1ConcPhaseTimer p(_cm, "Concurrent Clear Claimed Marks");
176173
ClassLoaderDataGraph::clear_claimed_marks();
177-
return _cm->has_aborted();
178174
}
179175

180176
bool G1ConcurrentMarkThread::phase_scan_root_regions() {
@@ -185,10 +181,9 @@ bool G1ConcurrentMarkThread::phase_scan_root_regions() {
185181

186182
bool G1ConcurrentMarkThread::phase_mark_loop() {
187183
Ticks mark_start = Ticks::now();
188-
log_info(gc, marking)("Concurrent Mark (%.3fs)", mark_start.seconds());
184+
log_info(gc, marking)("Concurrent Mark");
189185

190-
uint iter = 1;
191-
while (true) {
186+
for (uint iter = 1; true; ++iter) {
192187
// Subphase 1: Mark From Roots.
193188
if (subphase_mark_from_roots()) return true;
194189

@@ -207,13 +202,11 @@ bool G1ConcurrentMarkThread::phase_mark_loop() {
207202
if (!mark_loop_needs_restart()) break;
208203

209204
log_info(gc, marking)("Concurrent Mark Restart for Mark Stack Overflow (iteration #%u)",
210-
iter++);
205+
iter);
211206
}
212207

213-
Ticks mark_end = Ticks::now();
214-
log_info(gc, marking)("Concurrent Mark (%.3fs, %.3fs) %.3fms",
215-
mark_start.seconds(), mark_end.seconds(),
216-
(mark_end - mark_start).seconds() * 1000.0);
208+
log_info(gc, marking)("Concurrent Mark %.3fms",
209+
(Ticks::now() - mark_start).seconds() * 1000.0);
217210

218211
return false;
219212
}
@@ -283,8 +276,19 @@ void G1ConcurrentMarkThread::full_concurrent_cycle_do() {
283276
// Phase 1: Clear CLD claimed marks.
284277
phase_clear_cld_claimed_marks();
285278

286-
// Do not return before the scan root regions phase as a GC waits for a
279+
// We have to ensure that we finish scanning the root regions
280+
// before the next GC takes place. To ensure this we have to
281+
// make sure that we do not join the STS until the root regions
282+
// have been scanned. If we did then it's possible that a
283+
// subsequent GC could block us from joining the STS and proceed
284+
// without the root regions have been scanned which would be a
285+
// correctness issue.
286+
//
287+
// So do not return before the scan root regions phase as a GC waits for a
287288
// notification from it.
289+
//
290+
// For the same reason ConcurrentGCBreakpoints (in the phase methods) before
291+
// here risk deadlock, because a young GC must wait for root region scanning.
288292

289293
// Phase 2: Scan root regions.
290294
if (phase_scan_root_regions()) return;

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

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,39 +48,32 @@ class G1ConcurrentMarkThread: public ConcurrentGCThread {
4848

4949
volatile ServiceState _state;
5050

51-
// Wait for next cycle. Returns true if we should stop the service.
51+
// Wait for next cycle. Returns false if the service should be stopped.
5252
bool wait_for_next_cycle();
5353

54+
bool mark_loop_needs_restart() const;
55+
5456
// Phases and subphases for the full concurrent marking cycle in order.
5557
//
56-
// We have to ensure that we finish scanning the root regions
57-
// before the next GC takes place. To ensure this we have to
58-
// make sure that we do not join the STS until the root regions
59-
// have been scanned. If we did then it's possible that a
60-
// subsequent GC could block us from joining the STS and proceed
61-
// without the root regions have been scanned which would be a
62-
// correctness issue.
63-
// ConcurrentGCBreakpoints must not be placed before the the root
64-
// region scan phase too for this reason.
65-
//
66-
// All these methods return true if the marking should be aborted.
67-
bool phase_concurrent_cycle_start();
68-
bool phase_clear_cld_claimed_marks();
58+
// All these methods return true if the marking should be aborted. Except
59+
// phase_clear_cld_claimed_marks() because we must not abort before
60+
// scanning the root regions because of a potential deadlock otherwise.
61+
void phase_clear_cld_claimed_marks();
6962
bool phase_scan_root_regions();
7063

7164
bool phase_mark_loop();
72-
bool mark_loop_needs_restart() const;
7365
bool subphase_mark_from_roots();
7466
bool subphase_preclean();
7567
bool subphase_delay_to_keep_mmu_before_remark();
7668
bool subphase_remark();
69+
7770
bool phase_rebuild_remembered_sets();
7871
bool phase_delay_to_keep_mmu_before_cleanup();
7972
bool phase_cleanup();
8073
bool phase_clear_bitmap_for_next_mark();
8174

8275
void concurrent_cycle_start();
83-
// Perform a full concurrent cycle.
76+
8477
void full_concurrent_cycle_do();
8578
void concurrent_cycle_end();
8679

0 commit comments

Comments
 (0)