1/*
2 * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This code is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * version 2 for more details (a copy is included in the LICENSE file that
12 * accompanied this code).
13 *
14 * You should have received a copy of the GNU General Public License version
15 * 2 along with this work; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24
25#include "precompiled.hpp"
26
27
28#include "classfile/classLoaderDataGraph.hpp"
29#include "classfile/systemDictionary.hpp"
30#include "code/codeCache.hpp"
31#include "gc/shenandoah/shenandoahAsserts.hpp"
32#include "gc/shenandoah/shenandoahHeap.hpp"
33#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
34#include "gc/shenandoah/shenandoahRootVerifier.hpp"
35#include "gc/shenandoah/shenandoahStringDedup.hpp"
36#include "gc/shenandoah/shenandoahUtils.hpp"
37#include "gc/shared/weakProcessor.inline.hpp"
38#include "memory/universe.hpp"
39#include "runtime/thread.hpp"
40#include "services/management.hpp"
41#include "utilities/debug.hpp"
42
43// Check for overflow of number of root types.
44STATIC_ASSERT((static_cast<uint>(ShenandoahRootVerifier::AllRoots) + 1) > static_cast<uint>(ShenandoahRootVerifier::AllRoots));
45
46ShenandoahRootVerifier::ShenandoahRootVerifier() : _types(AllRoots) {
47}
48
49void ShenandoahRootVerifier::excludes(RootTypes types) {
50 _types = static_cast<ShenandoahRootVerifier::RootTypes>(static_cast<uint>(_types) & (~static_cast<uint>(types)));
51}
52
53bool ShenandoahRootVerifier::verify(RootTypes type) const {
54 return (_types & type) != 0;
55}
56
57void ShenandoahRootVerifier::oops_do(OopClosure* oops) {
58 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
59 if (verify(CodeRoots)) {
60 shenandoah_assert_locked_or_safepoint(CodeCache_lock);
61 CodeCache::blobs_do(&blobs);
62 }
63
64 if (verify(CLDGRoots)) {
65 shenandoah_assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
66 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
67 ClassLoaderDataGraph::cld_do(&clds);
68 }
69
70 if (verify(SerialRoots)) {
71 shenandoah_assert_safepoint();
72 Universe::oops_do(oops);
73 Management::oops_do(oops);
74 JvmtiExport::oops_do(oops);
75 ObjectSynchronizer::oops_do(oops);
76 SystemDictionary::oops_do(oops);
77 }
78
79 if (verify(JNIHandleRoots)) {
80 shenandoah_assert_safepoint();
81 JNIHandles::oops_do(oops);
82 }
83
84 if (verify(WeakRoots)) {
85 shenandoah_assert_safepoint();
86 AlwaysTrueClosure always_true;
87 WeakProcessor::weak_oops_do(&always_true, oops);
88 }
89
90 if (ShenandoahStringDedup::is_enabled() && verify(StringDedupRoots)) {
91 shenandoah_assert_safepoint();
92 ShenandoahStringDedup::oops_do_slow(oops);
93 }
94
95 if (verify(ThreadRoots)) {
96 shenandoah_assert_safepoint();
97 // Do thread roots the last. This allows verification code to find
98 // any broken objects from those special roots first, not the accidental
99 // dangling reference from the thread root.
100 Threads::possibly_parallel_oops_do(false, oops, &blobs);
101 }
102}
103
104void ShenandoahRootVerifier::roots_do(OopClosure* oops) {
105 shenandoah_assert_safepoint();
106
107 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
108 CodeCache::blobs_do(&blobs);
109
110 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
111 ClassLoaderDataGraph::cld_do(&clds);
112
113 Universe::oops_do(oops);
114 Management::oops_do(oops);
115 JvmtiExport::oops_do(oops);
116 JNIHandles::oops_do(oops);
117 ObjectSynchronizer::oops_do(oops);
118 SystemDictionary::oops_do(oops);
119
120 AlwaysTrueClosure always_true;
121 WeakProcessor::weak_oops_do(&always_true, oops);
122
123 if (ShenandoahStringDedup::is_enabled()) {
124 ShenandoahStringDedup::oops_do_slow(oops);
125 }
126
127 // Do thread roots the last. This allows verification code to find
128 // any broken objects from those special roots first, not the accidental
129 // dangling reference from the thread root.
130 Threads::possibly_parallel_oops_do(false, oops, &blobs);
131}
132
133void ShenandoahRootVerifier::strong_roots_do(OopClosure* oops) {
134 shenandoah_assert_safepoint();
135
136 CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
137
138 CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
139 ClassLoaderDataGraph::roots_cld_do(&clds, NULL);
140
141 Universe::oops_do(oops);
142 Management::oops_do(oops);
143 JvmtiExport::oops_do(oops);
144 JNIHandles::oops_do(oops);
145 ObjectSynchronizer::oops_do(oops);
146 SystemDictionary::oops_do(oops);
147
148 // Do thread roots the last. This allows verification code to find
149 // any broken objects from those special roots first, not the accidental
150 // dangling reference from the thread root.
151 Threads::possibly_parallel_oops_do(false, oops, &blobs);
152}
153