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/classLoaderData.hpp"
26 #include "classfile/stringTable.hpp"
27 #include "classfile/symbolTable.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "code/codeCache.hpp"
30 #include "compiler/oopMap.hpp"
31 #include "gc/shared/oopStorageParState.inline.hpp"
32 #include "gc/z/zGlobals.hpp"
33 #include "gc/z/zNMethodTable.hpp"
34 #include "gc/z/zOopClosures.inline.hpp"
35 #include "gc/z/zRootsIterator.hpp"
36 #include "gc/z/zStat.hpp"
37 #include "gc/z/zThreadLocalData.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "memory/universe.hpp"
40 #include "prims/jvmtiExport.hpp"
41 #include "runtime/atomic.hpp"
42 #include "runtime/jniHandles.hpp"
43 #include "runtime/thread.hpp"
44 #include "runtime/safepoint.hpp"
45 #include "runtime/synchronizer.hpp"
46 #include "services/management.hpp"
47 #include "utilities/debug.hpp"
57 static const ZStatSubPhase ZSubPhasePauseRootsJNIHandles("Pause Roots JNIHandles");
58 static const ZStatSubPhase ZSubPhasePauseRootsJNIWeakHandles("Pause Roots JNIWeakHandles");
59 static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer");
60 static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management");
61 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport");
62 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport");
63 static const ZStatSubPhase ZSubPhasePauseRootsJFRWeak("Pause Roots JRFWeak");
64 static const ZStatSubPhase ZSubPhasePauseRootsSystemDictionary("Pause Roots SystemDictionary");
65 static const ZStatSubPhase ZSubPhasePauseRootsClassLoaderDataGraph("Pause Roots ClassLoaderDataGraph");
66 static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads");
67 static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache");
68 static const ZStatSubPhase ZSubPhasePauseRootsStringTable("Pause Roots StringTable");
69
70 static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup");
71 static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots");
72 static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown");
73 static const ZStatSubPhase ZSubPhasePauseWeakRootsVMWeakHandles("Pause Weak Roots VMWeakHandles");
74 static const ZStatSubPhase ZSubPhasePauseWeakRootsJNIWeakHandles("Pause Weak Roots JNIWeakHandles");
75 static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport");
76 static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak");
77 static const ZStatSubPhase ZSubPhasePauseWeakRootsSymbolTable("Pause Weak Roots SymbolTable");
78 static const ZStatSubPhase ZSubPhasePauseWeakRootsStringTable("Pause Weak Roots StringTable");
79
80 static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots");
81 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles");
82 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles");
83 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable");
84
85 template <typename T, void (T::*F)(OopClosure*)>
86 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) :
87 _iter(iter),
88 _claimed(false) {}
89
90 template <typename T, void (T::*F)(OopClosure*)>
91 void ZSerialOopsDo<T, F>::oops_do(OopClosure* cl) {
92 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
93 (_iter->*F)(cl);
94 }
95 }
96
97 template <typename T, void (T::*F)(OopClosure*)>
285 _jvmti_weak_export.oops_do(cl);
286 _jfr_weak.oops_do(cl);
287 _vm_weak_handles.oops_do(cl);
288 _jni_weak_handles.oops_do(cl);
289 _string_table.oops_do(cl);
290 } else {
291 if (visit_jvmti_weak_export) {
292 _jvmti_weak_export.oops_do(cl);
293 }
294 }
295 }
296
297 ZWeakRootsIterator::ZWeakRootsIterator() :
298 _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()),
299 _jni_weak_handles_iter(JNIHandles::weak_global_handles()),
300 _string_table_iter(StringTable::weak_storage()),
301 _jvmti_weak_export(this),
302 _jfr_weak(this),
303 _vm_weak_handles(this),
304 _jni_weak_handles(this),
305 _symbol_table(this),
306 _string_table(this) {
307 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
308 ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
309 SymbolTable::clear_parallel_claimed_index();
310 StringTable::reset_dead_counter();
311 }
312
313 ZWeakRootsIterator::~ZWeakRootsIterator() {
314 ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown);
315 StringTable::finish_dead_counter();
316 }
317
318 void ZWeakRootsIterator::do_vm_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
319 ZStatTimer timer(ZSubPhasePauseWeakRootsVMWeakHandles);
320 _vm_weak_handles_iter.weak_oops_do(is_alive, cl);
321 }
322
323 void ZWeakRootsIterator::do_jni_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
324 ZStatTimer timer(ZSubPhasePauseWeakRootsJNIWeakHandles);
325 _jni_weak_handles_iter.weak_oops_do(is_alive, cl);
326 }
327
328 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl) {
329 ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport);
330 JvmtiExport::weak_oops_do(is_alive, cl);
331 }
332
333 void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, OopClosure* cl) {
334 #if INCLUDE_JFR
335 ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak);
336 Jfr::weak_oops_do(is_alive, cl);
337 #endif
338 }
339
340 void ZWeakRootsIterator::do_symbol_table(BoolObjectClosure* is_alive, OopClosure* cl) {
341 ZStatTimer timer(ZSubPhasePauseWeakRootsSymbolTable);
342 int dummy;
343 SymbolTable::possibly_parallel_unlink(&dummy, &dummy);
344 }
345
346 class ZStringTableDeadCounterBoolObjectClosure : public BoolObjectClosure {
347 private:
348 BoolObjectClosure* const _cl;
349 size_t _ndead;
350
351 public:
352 ZStringTableDeadCounterBoolObjectClosure(BoolObjectClosure* cl) :
353 _cl(cl),
354 _ndead(0) {}
355
356 ~ZStringTableDeadCounterBoolObjectClosure() {
357 StringTable::inc_dead_counter(_ndead);
358 }
359
360 virtual bool do_object_b(oop obj) {
361 if (_cl->do_object_b(obj)) {
362 return true;
363 }
364
365 _ndead++;
366 return false;
367 }
368 };
369
370 void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) {
371 ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable);
372 ZStringTableDeadCounterBoolObjectClosure counter_is_alive(is_alive);
373 _string_table_iter.weak_oops_do(&counter_is_alive, cl);
374 }
375
376 void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
377 ZStatTimer timer(ZSubPhasePauseWeakRoots);
378 if (ZSymbolTableUnloading) {
379 _symbol_table.weak_oops_do(is_alive, cl);
380 }
381 if (ZWeakRoots) {
382 _jvmti_weak_export.weak_oops_do(is_alive, cl);
383 _jfr_weak.weak_oops_do(is_alive, cl);
384 if (!ZConcurrentVMWeakHandles) {
385 _vm_weak_handles.weak_oops_do(is_alive, cl);
386 }
387 if (!ZConcurrentJNIWeakGlobalHandles) {
388 _jni_weak_handles.weak_oops_do(is_alive, cl);
389 }
390 if (!ZConcurrentStringTable) {
391 _string_table.weak_oops_do(is_alive, cl);
392 }
393 }
394 }
395
396 void ZWeakRootsIterator::oops_do(OopClosure* cl) {
397 AlwaysTrueClosure always_alive;
398 weak_oops_do(&always_alive, cl);
399 }
400
|
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/classLoaderData.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/oopStorageParState.inline.hpp"
31 #include "gc/z/zGlobals.hpp"
32 #include "gc/z/zNMethodTable.hpp"
33 #include "gc/z/zOopClosures.inline.hpp"
34 #include "gc/z/zRootsIterator.hpp"
35 #include "gc/z/zStat.hpp"
36 #include "gc/z/zThreadLocalData.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "prims/jvmtiExport.hpp"
40 #include "runtime/atomic.hpp"
41 #include "runtime/jniHandles.hpp"
42 #include "runtime/thread.hpp"
43 #include "runtime/safepoint.hpp"
44 #include "runtime/synchronizer.hpp"
45 #include "services/management.hpp"
46 #include "utilities/debug.hpp"
56 static const ZStatSubPhase ZSubPhasePauseRootsJNIHandles("Pause Roots JNIHandles");
57 static const ZStatSubPhase ZSubPhasePauseRootsJNIWeakHandles("Pause Roots JNIWeakHandles");
58 static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer");
59 static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management");
60 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport");
61 static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport");
62 static const ZStatSubPhase ZSubPhasePauseRootsJFRWeak("Pause Roots JRFWeak");
63 static const ZStatSubPhase ZSubPhasePauseRootsSystemDictionary("Pause Roots SystemDictionary");
64 static const ZStatSubPhase ZSubPhasePauseRootsClassLoaderDataGraph("Pause Roots ClassLoaderDataGraph");
65 static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads");
66 static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache");
67 static const ZStatSubPhase ZSubPhasePauseRootsStringTable("Pause Roots StringTable");
68
69 static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup");
70 static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots");
71 static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown");
72 static const ZStatSubPhase ZSubPhasePauseWeakRootsVMWeakHandles("Pause Weak Roots VMWeakHandles");
73 static const ZStatSubPhase ZSubPhasePauseWeakRootsJNIWeakHandles("Pause Weak Roots JNIWeakHandles");
74 static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport");
75 static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak");
76 static const ZStatSubPhase ZSubPhasePauseWeakRootsStringTable("Pause Weak Roots StringTable");
77
78 static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots");
79 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsVMWeakHandles("Concurrent Weak Roots VMWeakHandles");
80 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsJNIWeakHandles("Concurrent Weak Roots JNIWeakHandles");
81 static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsStringTable("Concurrent Weak Roots StringTable");
82
83 template <typename T, void (T::*F)(OopClosure*)>
84 ZSerialOopsDo<T, F>::ZSerialOopsDo(T* iter) :
85 _iter(iter),
86 _claimed(false) {}
87
88 template <typename T, void (T::*F)(OopClosure*)>
89 void ZSerialOopsDo<T, F>::oops_do(OopClosure* cl) {
90 if (!_claimed && Atomic::cmpxchg(true, &_claimed, false) == false) {
91 (_iter->*F)(cl);
92 }
93 }
94
95 template <typename T, void (T::*F)(OopClosure*)>
283 _jvmti_weak_export.oops_do(cl);
284 _jfr_weak.oops_do(cl);
285 _vm_weak_handles.oops_do(cl);
286 _jni_weak_handles.oops_do(cl);
287 _string_table.oops_do(cl);
288 } else {
289 if (visit_jvmti_weak_export) {
290 _jvmti_weak_export.oops_do(cl);
291 }
292 }
293 }
294
295 ZWeakRootsIterator::ZWeakRootsIterator() :
296 _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()),
297 _jni_weak_handles_iter(JNIHandles::weak_global_handles()),
298 _string_table_iter(StringTable::weak_storage()),
299 _jvmti_weak_export(this),
300 _jfr_weak(this),
301 _vm_weak_handles(this),
302 _jni_weak_handles(this),
303 _string_table(this) {
304 assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
305 ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
306 StringTable::reset_dead_counter();
307 }
308
309 ZWeakRootsIterator::~ZWeakRootsIterator() {
310 ZStatTimer timer(ZSubPhasePauseWeakRootsTeardown);
311 StringTable::finish_dead_counter();
312 }
313
314 void ZWeakRootsIterator::do_vm_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
315 ZStatTimer timer(ZSubPhasePauseWeakRootsVMWeakHandles);
316 _vm_weak_handles_iter.weak_oops_do(is_alive, cl);
317 }
318
319 void ZWeakRootsIterator::do_jni_weak_handles(BoolObjectClosure* is_alive, OopClosure* cl) {
320 ZStatTimer timer(ZSubPhasePauseWeakRootsJNIWeakHandles);
321 _jni_weak_handles_iter.weak_oops_do(is_alive, cl);
322 }
323
324 void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl) {
325 ZStatTimer timer(ZSubPhasePauseWeakRootsJVMTIWeakExport);
326 JvmtiExport::weak_oops_do(is_alive, cl);
327 }
328
329 void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, OopClosure* cl) {
330 #if INCLUDE_JFR
331 ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak);
332 Jfr::weak_oops_do(is_alive, cl);
333 #endif
334 }
335
336 class ZStringTableDeadCounterBoolObjectClosure : public BoolObjectClosure {
337 private:
338 BoolObjectClosure* const _cl;
339 size_t _ndead;
340
341 public:
342 ZStringTableDeadCounterBoolObjectClosure(BoolObjectClosure* cl) :
343 _cl(cl),
344 _ndead(0) {}
345
346 ~ZStringTableDeadCounterBoolObjectClosure() {
347 StringTable::inc_dead_counter(_ndead);
348 }
349
350 virtual bool do_object_b(oop obj) {
351 if (_cl->do_object_b(obj)) {
352 return true;
353 }
354
355 _ndead++;
356 return false;
357 }
358 };
359
360 void ZWeakRootsIterator::do_string_table(BoolObjectClosure* is_alive, OopClosure* cl) {
361 ZStatTimer timer(ZSubPhasePauseWeakRootsStringTable);
362 ZStringTableDeadCounterBoolObjectClosure counter_is_alive(is_alive);
363 _string_table_iter.weak_oops_do(&counter_is_alive, cl);
364 }
365
366 void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* cl) {
367 ZStatTimer timer(ZSubPhasePauseWeakRoots);
368 if (ZWeakRoots) {
369 _jvmti_weak_export.weak_oops_do(is_alive, cl);
370 _jfr_weak.weak_oops_do(is_alive, cl);
371 if (!ZConcurrentVMWeakHandles) {
372 _vm_weak_handles.weak_oops_do(is_alive, cl);
373 }
374 if (!ZConcurrentJNIWeakGlobalHandles) {
375 _jni_weak_handles.weak_oops_do(is_alive, cl);
376 }
377 if (!ZConcurrentStringTable) {
378 _string_table.weak_oops_do(is_alive, cl);
379 }
380 }
381 }
382
383 void ZWeakRootsIterator::oops_do(OopClosure* cl) {
384 AlwaysTrueClosure always_alive;
385 weak_oops_do(&always_alive, cl);
386 }
387
|