1 /*
2 * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_GC_G1_G1CONCURRENTMARKTHREAD_HPP
26 #define SHARE_GC_G1_G1CONCURRENTMARKTHREAD_HPP
27
28 #include "gc/shared/concurrentGCThread.hpp"
29 #include "runtime/atomic.hpp"
30
31 class G1ConcurrentMark;
32 class G1Policy;
33
34 // The concurrent mark thread triggers the various steps of the concurrent marking
35 // cycle, including various marking cleanup.
36 //
37 // The concurrent cycle may either be "Full" (i.e. include marking, rebuilding and
38 // scrubbing, resetting for the next cycle) or "Undo", i.e. shortened to just the
39 // reset part.
40 class G1ConcurrentMarkThread: public ConcurrentGCThread {
41 G1ConcurrentMark* _cm;
42
43 enum ServiceState : uint {
44 Idle,
45 FullCycleMarking,
46 FullCycleRebuildOrScrub,
47 FullCycleResetForNextCycle,
48 UndoCycleResetForNextCycle
49 };
50
51 Atomic<ServiceState> _state;
52
53 ServiceState state() const { return _state.load_acquire(); }
54 void set_state(ServiceState new_state) { _state.release_store(new_state); }
55
56 // Returns whether we are in a "Full" cycle.
57 bool is_in_full_concurrent_cycle() const;
58
59 // Wait for next cycle. Returns the command passed over.
60 bool wait_for_next_cycle();
61
62 bool mark_loop_needs_restart() const;
63
64 // Phases and subphases for the full concurrent cycle in order.
65 //
66 // All these methods return true if the cycle should be aborted.
67 bool phase_clear_cld_claimed_marks();
68 bool phase_scan_root_regions();
69
70 bool phase_mark_loop();
71 bool subphase_mark_from_roots();
72 bool subphase_preclean();
73 bool subphase_delay_to_keep_mmu_before_remark();
74 bool subphase_remark();
75
76 bool phase_rebuild_and_scrub();
77 bool phase_delay_to_keep_mmu_before_cleanup();
78 bool phase_cleanup();
79 bool phase_clear_bitmap_for_next_mark();
80
81 void concurrent_cycle_start();
82
83 void concurrent_mark_cycle_do();
84 void concurrent_undo_cycle_do();
85
86 void concurrent_cycle_end(bool mark_cycle_completed);
87
88 // Delay pauses to meet MMU.
89 void delay_to_keep_mmu(bool remark);
90 double mmu_delay_end(G1Policy* policy, bool remark);
91
92 void run_service();
93 void stop_service();
94
95 public:
96 // Constructor
97 G1ConcurrentMarkThread(G1ConcurrentMark* cm);
98
99 // Total cpu time used by all marking related threads (i.e. this thread and the
100 // marking worker threads) in seconds.
101 double total_mark_cpu_time_s();
102 // Cpu time used by all marking worker threads in seconds.
103 double worker_threads_cpu_time_s();
104 // State management.
105 void set_idle();
106 void start_full_cycle();
107 void start_undo_cycle();
108
109 void set_full_cycle_rebuild_and_scrub();
110 void set_full_cycle_reset_for_next_cycle();
111
112 bool is_idle() const;
113 // Returns true from the moment a concurrent cycle is
114 // initiated (during the concurrent start pause when calling one of the
115 // start_*_cycle() methods) to the moment when the cycle completes.
116 bool is_in_progress() const;
117
118 bool is_in_marking() const;
119 bool is_in_marking_or_rebuild() const;
120 bool is_in_reset_for_next_cycle() const;
121
122 bool is_in_undo_cycle() const;
123
124 // Update the perf data counter for concurrent mark.
125 void update_perf_counter_cpu_time();
126 };
127
128 #endif // SHARE_GC_G1_G1CONCURRENTMARKTHREAD_HPP