1/*
2 * Copyright (c) 2015, 2019, 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#include "precompiled.hpp"
26#include "aot/aotLoader.hpp"
27#include "classfile/classLoaderDataGraph.hpp"
28#include "classfile/stringTable.hpp"
29#include "classfile/systemDictionary.hpp"
30#include "code/codeCache.hpp"
31#include "gc/g1/g1BarrierSet.hpp"
32#include "gc/g1/g1CodeBlobClosure.hpp"
33#include "gc/g1/g1CollectedHeap.inline.hpp"
34#include "gc/g1/g1CollectorState.hpp"
35#include "gc/g1/g1GCPhaseTimes.hpp"
36#include "gc/g1/g1ParScanThreadState.inline.hpp"
37#include "gc/g1/g1Policy.hpp"
38#include "gc/g1/g1RootClosures.hpp"
39#include "gc/g1/g1RootProcessor.hpp"
40#include "gc/g1/heapRegion.inline.hpp"
41#include "gc/shared/referenceProcessor.hpp"
42#include "memory/allocation.inline.hpp"
43#include "memory/universe.hpp"
44#include "runtime/mutex.hpp"
45#include "services/management.hpp"
46#include "utilities/macros.hpp"
47#if INCLUDE_JVMCI
48#include "jvmci/jvmci.hpp"
49#endif
50
51void G1RootProcessor::worker_has_discovered_all_strong_classes() {
52 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
53
54 uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
55 if (new_value == n_workers()) {
56 // This thread is last. Notify the others.
57 MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
58 _lock.notify_all();
59 }
60}
61
62void G1RootProcessor::wait_until_all_strong_classes_discovered() {
63 assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
64
65 if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
66 MonitorLocker ml(&_lock, Mutex::_no_safepoint_check_flag);
67 while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
68 ml.wait(0);
69 }
70 }
71}
72
73G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
74 _g1h(g1h),
75 _process_strong_tasks(G1RP_PS_NumElements),
76 _srs(n_workers),
77 _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
78 _n_workers_discovered_strong_classes(0) {}
79
80void G1RootProcessor::evacuate_roots(G1ParScanThreadState* pss, uint worker_i) {
81 G1GCPhaseTimes* phase_times = _g1h->phase_times();
82
83 G1EvacPhaseTimesTracker timer(phase_times, pss, G1GCPhaseTimes::ExtRootScan, worker_i);
84
85 G1EvacuationRootClosures* closures = pss->closures();
86 process_java_roots(closures, phase_times, worker_i);
87
88 // This is the point where this worker thread will not find more strong CLDs/nmethods.
89 // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing.
90 if (closures->trace_metadata()) {
91 worker_has_discovered_all_strong_classes();
92 }
93
94 process_vm_roots(closures, phase_times, worker_i);
95
96 {
97 // Now the CM ref_processor roots.
98 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CMRefRoots, worker_i);
99 if (_process_strong_tasks.try_claim_task(G1RP_PS_refProcessor_oops_do)) {
100 // We need to treat the discovered reference lists of the
101 // concurrent mark ref processor as roots and keep entries
102 // (which are added by the marking threads) on them live
103 // until they can be processed at the end of marking.
104 _g1h->ref_processor_cm()->weak_oops_do(closures->strong_oops());
105 }
106 }
107
108 if (closures->trace_metadata()) {
109 {
110 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WaitForStrongCLD, worker_i);
111 // Barrier to make sure all workers passed
112 // the strong CLD and strong nmethods phases.
113 wait_until_all_strong_classes_discovered();
114 }
115
116 // Now take the complement of the strong CLDs.
117 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::WeakCLDRoots, worker_i);
118 assert(closures->second_pass_weak_clds() != NULL, "Should be non-null if we are tracing metadata.");
119 ClassLoaderDataGraph::roots_cld_do(NULL, closures->second_pass_weak_clds());
120 } else {
121 phase_times->record_time_secs(G1GCPhaseTimes::WaitForStrongCLD, worker_i, 0.0);
122 phase_times->record_time_secs(G1GCPhaseTimes::WeakCLDRoots, worker_i, 0.0);
123 assert(closures->second_pass_weak_clds() == NULL, "Should be null if not tracing metadata.");
124 }
125
126 _process_strong_tasks.all_tasks_completed(n_workers());
127}
128
129// Adaptor to pass the closures to the strong roots in the VM.
130class StrongRootsClosures : public G1RootClosures {
131 OopClosure* _roots;
132 CLDClosure* _clds;
133 CodeBlobClosure* _blobs;
134public:
135 StrongRootsClosures(OopClosure* roots, CLDClosure* clds, CodeBlobClosure* blobs) :
136 _roots(roots), _clds(clds), _blobs(blobs) {}
137
138 OopClosure* weak_oops() { return NULL; }
139 OopClosure* strong_oops() { return _roots; }
140
141 CLDClosure* weak_clds() { return NULL; }
142 CLDClosure* strong_clds() { return _clds; }
143
144 CodeBlobClosure* strong_codeblobs() { return _blobs; }
145};
146
147void G1RootProcessor::process_strong_roots(OopClosure* oops,
148 CLDClosure* clds,
149 CodeBlobClosure* blobs) {
150 StrongRootsClosures closures(oops, clds, blobs);
151
152 process_java_roots(&closures, NULL, 0);
153 process_vm_roots(&closures, NULL, 0);
154
155 _process_strong_tasks.all_tasks_completed(n_workers());
156}
157
158// Adaptor to pass the closures to all the roots in the VM.
159class AllRootsClosures : public G1RootClosures {
160 OopClosure* _roots;
161 CLDClosure* _clds;
162public:
163 AllRootsClosures(OopClosure* roots, CLDClosure* clds) :
164 _roots(roots), _clds(clds) {}
165
166 OopClosure* weak_oops() { return _roots; }
167 OopClosure* strong_oops() { return _roots; }
168
169 // By returning the same CLDClosure for both weak and strong CLDs we ensure
170 // that a single walk of the CLDG will invoke the closure on all CLDs i the
171 // system.
172 CLDClosure* weak_clds() { return _clds; }
173 CLDClosure* strong_clds() { return _clds; }
174
175 // We don't want to visit code blobs more than once, so we return NULL for the
176 // strong case and walk the entire code cache as a separate step.
177 CodeBlobClosure* strong_codeblobs() { return NULL; }
178};
179
180void G1RootProcessor::process_all_roots(OopClosure* oops,
181 CLDClosure* clds,
182 CodeBlobClosure* blobs) {
183 AllRootsClosures closures(oops, clds);
184
185 process_java_roots(&closures, NULL, 0);
186 process_vm_roots(&closures, NULL, 0);
187
188 process_code_cache_roots(blobs, NULL, 0);
189
190 _process_strong_tasks.all_tasks_completed(n_workers());
191}
192
193void G1RootProcessor::process_java_roots(G1RootClosures* closures,
194 G1GCPhaseTimes* phase_times,
195 uint worker_i) {
196 // Iterating over the CLDG and the Threads are done early to allow us to
197 // first process the strong CLDs and nmethods and then, after a barrier,
198 // let the thread process the weak CLDs and nmethods.
199 {
200 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::CLDGRoots, worker_i);
201 if (_process_strong_tasks.try_claim_task(G1RP_PS_ClassLoaderDataGraph_oops_do)) {
202 ClassLoaderDataGraph::roots_cld_do(closures->strong_clds(), closures->weak_clds());
203 }
204 }
205
206 {
207 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
208 bool is_par = n_workers() > 1;
209 Threads::possibly_parallel_oops_do(is_par,
210 closures->strong_oops(),
211 closures->strong_codeblobs());
212 }
213}
214
215void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
216 G1GCPhaseTimes* phase_times,
217 uint worker_i) {
218 OopClosure* strong_roots = closures->strong_oops();
219
220 {
221 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i);
222 if (_process_strong_tasks.try_claim_task(G1RP_PS_Universe_oops_do)) {
223 Universe::oops_do(strong_roots);
224 }
225 }
226
227 {
228 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JNIRoots, worker_i);
229 if (_process_strong_tasks.try_claim_task(G1RP_PS_JNIHandles_oops_do)) {
230 JNIHandles::oops_do(strong_roots);
231 }
232 }
233
234 {
235 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ObjectSynchronizerRoots, worker_i);
236 if (_process_strong_tasks.try_claim_task(G1RP_PS_ObjectSynchronizer_oops_do)) {
237 ObjectSynchronizer::oops_do(strong_roots);
238 }
239 }
240
241 {
242 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ManagementRoots, worker_i);
243 if (_process_strong_tasks.try_claim_task(G1RP_PS_Management_oops_do)) {
244 Management::oops_do(strong_roots);
245 }
246 }
247
248 {
249 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMTIRoots, worker_i);
250 if (_process_strong_tasks.try_claim_task(G1RP_PS_jvmti_oops_do)) {
251 JvmtiExport::oops_do(strong_roots);
252 }
253 }
254
255#if INCLUDE_AOT
256 if (UseAOT) {
257 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::AOTCodeRoots, worker_i);
258 if (_process_strong_tasks.try_claim_task(G1RP_PS_aot_oops_do)) {
259 AOTLoader::oops_do(strong_roots);
260 }
261 }
262#endif
263
264#if INCLUDE_JVMCI
265 if (EnableJVMCI) {
266 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMCIRoots, worker_i);
267 if (_process_strong_tasks.try_claim_task(G1RP_PS_JVMCI_oops_do)) {
268 JVMCI::oops_do(strong_roots);
269 }
270 }
271#endif
272
273 {
274 G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
275 if (_process_strong_tasks.try_claim_task(G1RP_PS_SystemDictionary_oops_do)) {
276 SystemDictionary::oops_do(strong_roots);
277 }
278 }
279}
280
281void G1RootProcessor::process_code_cache_roots(CodeBlobClosure* code_closure,
282 G1GCPhaseTimes* phase_times,
283 uint worker_i) {
284 if (_process_strong_tasks.try_claim_task(G1RP_PS_CodeCache_oops_do)) {
285 CodeCache::blobs_do(code_closure);
286 }
287}
288
289uint G1RootProcessor::n_workers() const {
290 return _srs.n_threads();
291}
292