rev 57156 : imported patch 8234796-v3
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 #include "precompiled.hpp"
25 #include "classfile/classLoaderDataGraph.hpp"
26 #include "classfile/stringTable.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "code/codeCache.hpp"
29 #include "compiler/oopMap.hpp"
30 #include "gc/shared/barrierSet.hpp"
31 #include "gc/shared/barrierSetNMethod.hpp"
32 #include "gc/shared/oopStorageParState.inline.hpp"
33 #include "gc/shared/oopStorageSet.hpp"
34 #include "gc/shared/suspendibleThreadSet.hpp"
35 #include "gc/z/zBarrierSetNMethod.hpp"
36 #include "gc/z/zGlobals.hpp"
37 #include "gc/z/zNMethod.hpp"
38 #include "gc/z/zOopClosures.inline.hpp"
39 #include "gc/z/zRootsIterator.hpp"
40 #include "gc/z/zStat.hpp"
41 #include "gc/z/zThreadLocalData.hpp"
42 #include "memory/iterator.hpp"
43 #include "memory/resourceArea.hpp"
44 #include "memory/universe.hpp"
45 #include "prims/jvmtiExport.hpp"
46 #include "prims/resolvedMethodTable.hpp"
47 #include "runtime/atomic.hpp"
48 #include "runtime/thread.hpp"
49 #include "runtime/safepoint.hpp"
50 #include "runtime/synchronizer.hpp"
51 #include "services/management.hpp"
52 #include "utilities/debug.hpp"
53 #if INCLUDE_JFR
54 #include "jfr/jfr.hpp"
55 #endif
56
57 static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup");
58 static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots");
59 static const ZStatSubPhase ZSubPhasePauseRootsTeardown("Pause Roots Teardown");
60 static const ZStatSubPhase ZSubPhasePauseRootsUniverse("Pause Roots Universe");
61 static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer");
62 static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management");
63 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport");
64 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport");
65 static const ZStatSubPhase ZSubPhasePauseRootsSystemDictionary("Pause Roots SystemDictionary");
66 static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads");
67 static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache");
68
69 static const ZStatSubPhase ZSubPhaseConcurrentRootsSetup("Concurrent Roots Setup");
70 static const ZStatSubPhase ZSubPhaseConcurrentRoots("Concurrent Roots");
71 static const ZStatSubPhase ZSubPhaseConcurrentRootsTeardown("Concurrent Roots Teardown");
72 static const ZStatSubPhase ZSubPhaseConcurrentRootsJNIHandles("Concurrent Roots JNIHandles");
73 static const ZStatSubPhase ZSubPhaseConcurrentRootsVMHandles("Concurrent Roots VMHandles");
74 static const ZStatSubPhase ZSubPhaseConcurrentRootsClassLoaderDataGraph("Concurrent Roots ClassLoaderDataGraph");
75
76 static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup");
77 static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots");
78 static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown");
79 static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport");
80 static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak");
81
82 static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots");
83 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles");
84 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles");
85 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable");
86 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsResolvedMethodTable("Concurrent Weak Roots ResolvedMethodTable");
87
88 template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
89 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) :
90 _iter(iter),
91 _claimed(false) {}
92
93 template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
94 void ZSerialOopsDo<T, F>::oops_do(ZRootsIteratorClosure* cl) {
95 if (!_claimed && Atomic::cmpxchg(&_claimed, false, true) == false) {
96 (_iter->*F)(cl);
97 }
98 }
99
100 template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
101 ZParallelOopsDo<T, F>::ZParallelOopsDo(T* iter) :
102 _iter(iter),
103 _completed(false) {}
104
105 template <typename T, void (T::*F)(ZRootsIteratorClosure*)>
106 void ZParallelOopsDo<T, F>::oops_do(ZRootsIteratorClosure* cl) {
107 if (!_completed) {
108 (_iter->*F)(cl);
109 if (!_completed) {
110 _completed = true;
111 }
112 }
113 }
114
115 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)>
116 ZSerialWeakOopsDo<T, F>::ZSerialWeakOopsDo(T* iter) :
117 _iter(iter),
118 _claimed(false) {}
119
120 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)>
121 void ZSerialWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
122 if (!_claimed && Atomic::cmpxchg(&_claimed, false, true) == false) {
123 (_iter->*F)(is_alive, cl);
124 }
125 }
126
127 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)>
128 ZParallelWeakOopsDo<T, F>::ZParallelWeakOopsDo(T* iter) :
129 _iter(iter),
130 _completed(false) {}
131
132 template <typename T, void (T::*F)(BoolObjectClosure*, ZRootsIteratorClosure*)>
133 void ZParallelWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
134 if (!_completed) {
135 (_iter->*F)(is_alive, cl);
136 if (!_completed) {
137 _completed = true;
138 }
139 }
140 }
141
142 class ZRootsIteratorCodeBlobClosure : public CodeBlobToOopClosure {
143 private:
144 BarrierSetNMethod* _bs;
145
146 public:
147 ZRootsIteratorCodeBlobClosure(OopClosure* cl) :
148 CodeBlobToOopClosure(cl, true /* fix_relocations */),
149 _bs(BarrierSet::barrier_set()->barrier_set_nmethod()) {}
150
151 virtual void do_code_blob(CodeBlob* cb) {
152 nmethod* const nm = cb->as_nmethod_or_null();
153 if (nm != NULL && nm->oops_do_try_claim()) {
154 CodeBlobToOopClosure::do_code_blob(cb);
155 _bs->disarm(nm);
156 }
157 }
158 };
159
160 class ZRootsIteratorThreadClosure : public ThreadClosure {
161 private:
162 ZRootsIteratorClosure* _cl;
163
164 public:
165 ZRootsIteratorThreadClosure(ZRootsIteratorClosure* cl) :
166 _cl(cl) {}
167
168 virtual void do_thread(Thread* thread) {
169 ZRootsIteratorCodeBlobClosure code_cl(_cl);
170 thread->oops_do(_cl, ClassUnloading ? &code_cl : NULL);
171 _cl->do_thread(thread);
172 }
173 };
174
175 ZRootsIterator::ZRootsIterator(bool visit_jvmti_weak_export) :
176 _visit_jvmti_weak_export(visit_jvmti_weak_export),
177 _universe(this),
178 _object_synchronizer(this),
179 _management(this),
180 _jvmti_export(this),
181 _jvmti_weak_export(this),
182 _system_dictionary(this),
183 _threads(this),
184 _code_cache(this) {
185 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
186 ZStatTimer timer(ZSubPhasePauseRootsSetup);
187 Threads::change_thread_claim_token();
188 COMPILER2_PRESENT(DerivedPointerTable::clear());
189 if (ClassUnloading) {
190 nmethod::oops_do_marking_prologue();
191 } else {
192 ZNMethod::oops_do_begin();
193 }
194 }
195
196 ZRootsIterator::~ZRootsIterator() {
197 ZStatTimer timer(ZSubPhasePauseRootsTeardown);
198 ResourceMark rm;
199 if (ClassUnloading) {
200 nmethod::oops_do_marking_epilogue();
201 } else {
202 ZNMethod::oops_do_end();
203 }
204
205 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
206 Threads::assert_all_threads_claimed();
207 }
208
209 void ZRootsIterator::do_universe(ZRootsIteratorClosure* cl) {
210 ZStatTimer timer(ZSubPhasePauseRootsUniverse);
211 Universe::oops_do(cl);
212 }
213
214 void ZRootsIterator::do_object_synchronizer(ZRootsIteratorClosure* cl) {
215 ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer);
216 ObjectSynchronizer::oops_do(cl);
217 }
218
219 void ZRootsIterator::do_management(ZRootsIteratorClosure* cl) {
220 ZStatTimer timer(ZSubPhasePauseRootsManagement);
221 Management::oops_do(cl);
222 }
223
224 void ZRootsIterator::do_jvmti_export(ZRootsIteratorClosure* cl) {
225 ZStatTimer timer(ZSubPhasePauseRootsJVMTIExport);
226 JvmtiExport::oops_do(cl);
227 }
228
229 void ZRootsIterator::do_jvmti_weak_export(ZRootsIteratorClosure* cl) {
230 ZStatTimer timer(ZSubPhasePauseRootsJVMTIWeakExport);
231 AlwaysTrueClosure always_alive;
232 JvmtiExport::weak_oops_do(&always_alive, cl);
233 }
234
235 void ZRootsIterator::do_system_dictionary(ZRootsIteratorClosure* cl) {
236 ZStatTimer timer(ZSubPhasePauseRootsSystemDictionary);
237 // Handles are processed via _vm_handles.
238 SystemDictionary::oops_do(cl, false /* include_handles */);
239 }
240
241 void ZRootsIterator::do_threads(ZRootsIteratorClosure* cl) {
242 ZStatTimer timer(ZSubPhasePauseRootsThreads);
243 ResourceMark rm;
244 ZRootsIteratorThreadClosure thread_cl(cl);
245 Threads::possibly_parallel_threads_do(true, &thread_cl);
246 }
247
248 void ZRootsIterator::do_code_cache(ZRootsIteratorClosure* cl) {
249 ZStatTimer timer(ZSubPhasePauseRootsCodeCache);
250 ZNMethod::oops_do(cl);
251 }
252
253 void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
254 ZStatTimer timer(ZSubPhasePauseRoots);
255 _universe.oops_do(cl);
256 _object_synchronizer.oops_do(cl);
257 _management.oops_do(cl);
258 _jvmti_export.oops_do(cl);
259 _system_dictionary.oops_do(cl);
260 _threads.oops_do(cl);
261 if (!ClassUnloading) {
262 _code_cache.oops_do(cl);
263 }
264 if (_visit_jvmti_weak_export) {
265 _jvmti_weak_export.oops_do(cl);
266 }
267 }
268
269 ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) :
270 _jni_handles_iter(OopStorageSet::jni_global()),
271 _vm_handles_iter(OopStorageSet::vm_global()),
272 _cld_claim(cld_claim),
273 _jni_handles(this),
274 _vm_handles(this),
275 _class_loader_data_graph(this) {
276 ZStatTimer timer(ZSubPhaseConcurrentRootsSetup);
277 ClassLoaderDataGraph::clear_claimed_marks(cld_claim);
278 }
279
280 ZConcurrentRootsIterator::~ZConcurrentRootsIterator() {
281 ZStatTimer timer(ZSubPhaseConcurrentRootsTeardown);
282 }
283
284 void ZConcurrentRootsIterator::do_jni_handles(ZRootsIteratorClosure* cl) {
285 ZStatTimer timer(ZSubPhaseConcurrentRootsJNIHandles);
286 _jni_handles_iter.oops_do(cl);
287 }
288
289 void ZConcurrentRootsIterator::do_vm_handles(ZRootsIteratorClosure* cl) {
290 ZStatTimer timer(ZSubPhaseConcurrentRootsVMHandles);
291 _vm_handles_iter.oops_do(cl);
292 }
293
294 void ZConcurrentRootsIterator::do_class_loader_data_graph(ZRootsIteratorClosure* cl) {
295 ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph);
296 CLDToOopClosure cld_cl(cl, _cld_claim);
297 ClassLoaderDataGraph::always_strong_cld_do(&cld_cl);
298 }
299
300 void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
301 ZStatTimer timer(ZSubPhaseConcurrentRoots);
302 _jni_handles.oops_do(cl);
303 _vm_handles.oops_do(cl),
304 _class_loader_data_graph.oops_do(cl);
305 }
306
307 ZWeakRootsIterator::ZWeakRootsIterator() :
308 _jvmti_weak_export(this),
309 _jfr_weak(this) {
310 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
311 ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
312 }
313
314 ZWeakRootsIterator::~ZWeakRootsIterator() {
315 ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown);
316 }
317
318 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
319 ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport);
320 JvmtiExport::weak_oops_do(is_alive, cl);
321 }
322
323 void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
324 #if INCLUDE_JFR
325 ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak);
326 Jfr::weak_oops_do(is_alive, cl);
327 #endif
328 }
329
330 void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
331 ZStatTimer timer(ZSubPhasePauseWeakRoots);
332 _jvmti_weak_export.weak_oops_do(is_alive, cl);
333 _jfr_weak.weak_oops_do(is_alive, cl);
334 }
335
336 void ZWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
337 AlwaysTrueClosure always_alive;
338 weak_oops_do(&always_alive, cl);
339 }
340
341 ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() :
342 _vm_weak_handles_iter(OopStorageSet::vm_weak()),
343 _jni_weak_handles_iter(OopStorageSet::jni_weak()),
344 _string_table_iter(OopStorageSet::string_table_weak()),
345 _resolved_method_table_iter(OopStorageSet::resolved_method_table_weak()),
346 _vm_weak_handles(this),
347 _jni_weak_handles(this),
348 _string_table(this),
349 _resolved_method_table(this) {
350 StringTable::reset_dead_counter();
351 ResolvedMethodTable::reset_dead_counter();
352 }
353
354 ZConcurrentWeakRootsIterator::~ZConcurrentWeakRootsIterator() {
355 StringTable::finish_dead_counter();
356 ResolvedMethodTable::finish_dead_counter();
357 }
358
359 void ZConcurrentWeakRootsIterator::do_vm_weak_handles(ZRootsIteratorClosure* cl) {
360 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsVMWeakHandles);
361 _vm_weak_handles_iter.oops_do(cl);
362 }
363
364 void ZConcurrentWeakRootsIterator::do_jni_weak_handles(ZRootsIteratorClosure* cl) {
365 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsJNIWeakHandles);
366 _jni_weak_handles_iter.oops_do(cl);
367 }
368
369 template <class Container>
370 class ZDeadCounterClosure : public ZRootsIteratorClosure {
371 private:
372 ZRootsIteratorClosure* const _cl;
373 size_t _ndead;
374
375 public:
376 ZDeadCounterClosure(ZRootsIteratorClosure* cl) :
377 _cl(cl),
378 _ndead(0) {}
379
380 ~ZDeadCounterClosure() {
381 Container::inc_dead_counter(_ndead);
382 }
383
384 virtual void do_oop(oop* p) {
385 _cl->do_oop(p);
386 if (*p == NULL) {
387 _ndead++;
388 }
389 }
390
391 virtual void do_oop(narrowOop* p) {
392 ShouldNotReachHere();
393 }
394 };
395
396 void ZConcurrentWeakRootsIterator::do_string_table(ZRootsIteratorClosure* cl) {
397 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsStringTable);
398 ZDeadCounterClosure<StringTable> counter_cl(cl);
399 _string_table_iter.oops_do(&counter_cl);
400 }
401
402 void ZConcurrentWeakRootsIterator::do_resolved_method_table(ZRootsIteratorClosure* cl) {
403 ZStatTimer timer(ZSubPhaseConcurrentWeakRootsResolvedMethodTable);
404 ZDeadCounterClosure<ResolvedMethodTable> counter_cl(cl);
405 _resolved_method_table_iter.oops_do(&counter_cl);
406 }
407
408 void ZConcurrentWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
409 ZStatTimer timer(ZSubPhaseConcurrentWeakRoots);
410 _vm_weak_handles.oops_do(cl);
411 _jni_weak_handles.oops_do(cl);
412 _string_table.oops_do(cl);
413 _resolved_method_table.oops_do(cl);
414 }
--- EOF ---