1 /*
2 * Copyright (c) 2019, 2020, 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/classLoaderData.hpp"
26 #include "gc/z/zAddress.hpp"
27 #include "gc/z/zHeap.inline.hpp"
28 #include "gc/z/zOop.hpp"
29 #include "gc/z/zPageAllocator.hpp"
30 #include "gc/z/zResurrection.hpp"
31 #include "gc/z/zRootsIterator.hpp"
32 #include "gc/z/zStat.hpp"
33 #include "gc/z/zVerify.hpp"
34 #include "memory/iterator.inline.hpp"
35 #include "oops/oop.hpp"
36
37 #define BAD_OOP_ARG(o, p) "Bad oop " PTR_FORMAT " found at " PTR_FORMAT, p2i(o), p2i(p)
38
z_verify_oop(oop * p)39 static void z_verify_oop(oop* p) {
40 const oop o = RawAccess<>::oop_load(p);
41 if (o != NULL) {
42 const uintptr_t addr = ZOop::to_address(o);
43 guarantee(ZAddress::is_good(addr), BAD_OOP_ARG(o, p));
44 guarantee(oopDesc::is_oop(ZOop::from_address(addr)), BAD_OOP_ARG(o, p));
45 }
46 }
47
z_verify_possibly_weak_oop(oop * p)48 static void z_verify_possibly_weak_oop(oop* p) {
49 const oop o = RawAccess<>::oop_load(p);
50 if (o != NULL) {
51 const uintptr_t addr = ZOop::to_address(o);
52 guarantee(ZAddress::is_good(addr) || ZAddress::is_finalizable_good(addr), BAD_OOP_ARG(o, p));
53 guarantee(oopDesc::is_oop(ZOop::from_address(ZAddress::good(addr))), BAD_OOP_ARG(o, p));
54 }
55 }
56
57 class ZVerifyRootClosure : public ZRootsIteratorClosure {
58 public:
do_oop(oop * p)59 virtual void do_oop(oop* p) {
60 z_verify_oop(p);
61 }
62
do_oop(narrowOop *)63 virtual void do_oop(narrowOop*) {
64 ShouldNotReachHere();
65 }
66 };
67
68 class ZVerifyOopClosure : public ClaimMetadataVisitingOopIterateClosure, public ZRootsIteratorClosure {
69 private:
70 const bool _verify_weaks;
71
72 public:
ZVerifyOopClosure(bool verify_weaks)73 ZVerifyOopClosure(bool verify_weaks) :
74 ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_other),
75 _verify_weaks(verify_weaks) {}
76
do_oop(oop * p)77 virtual void do_oop(oop* p) {
78 if (_verify_weaks) {
79 z_verify_possibly_weak_oop(p);
80 } else {
81 // We should never encounter finalizable oops through strong
82 // paths. This assumes we have only visited strong roots.
83 z_verify_oop(p);
84 }
85 }
86
do_oop(narrowOop * p)87 virtual void do_oop(narrowOop* p) {
88 ShouldNotReachHere();
89 }
90
reference_iteration_mode()91 virtual ReferenceIterationMode reference_iteration_mode() {
92 return _verify_weaks ? DO_FIELDS : DO_FIELDS_EXCEPT_REFERENT;
93 }
94
95 #ifdef ASSERT
96 // Verification handled by the closure itself
should_verify_oops()97 virtual bool should_verify_oops() {
98 return false;
99 }
100 #endif
101 };
102
103 template <typename RootsIterator>
roots()104 void ZVerify::roots() {
105 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
106 assert(!ZResurrection::is_blocked(), "Invalid phase");
107
108 if (ZVerifyRoots) {
109 ZVerifyRootClosure cl;
110 RootsIterator iter;
111 iter.oops_do(&cl);
112 }
113 }
114
roots_strong()115 void ZVerify::roots_strong() {
116 roots<ZRootsIterator>();
117 }
118
roots_weak()119 void ZVerify::roots_weak() {
120 roots<ZWeakRootsIterator>();
121 }
122
roots_concurrent_strong()123 void ZVerify::roots_concurrent_strong() {
124 roots<ZConcurrentRootsIteratorClaimNone>();
125 }
126
roots_concurrent_weak()127 void ZVerify::roots_concurrent_weak() {
128 roots<ZConcurrentWeakRootsIterator>();
129 }
130
roots(bool verify_weaks)131 void ZVerify::roots(bool verify_weaks) {
132 roots_strong();
133 roots_concurrent_strong();
134 if (verify_weaks) {
135 roots_weak();
136 roots_concurrent_weak();
137 }
138 }
139
objects(bool verify_weaks)140 void ZVerify::objects(bool verify_weaks) {
141 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
142 assert(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase");
143 assert(!ZResurrection::is_blocked(), "Invalid phase");
144
145 if (ZVerifyObjects) {
146 ZVerifyOopClosure cl(verify_weaks);
147 ObjectToOopClosure object_cl(&cl);
148 ZHeap::heap()->object_iterate(&object_cl, verify_weaks);
149 }
150 }
151
roots_and_objects(bool verify_weaks)152 void ZVerify::roots_and_objects(bool verify_weaks) {
153 roots(verify_weaks);
154 objects(verify_weaks);
155 }
156
before_zoperation()157 void ZVerify::before_zoperation() {
158 // Verify strong roots
159 ZStatTimerDisable disable;
160 roots_strong();
161 }
162
after_mark()163 void ZVerify::after_mark() {
164 // Verify all strong roots and strong references
165 ZStatTimerDisable disable;
166 roots_and_objects(false /* verify_weaks */);
167 }
168
after_weak_processing()169 void ZVerify::after_weak_processing() {
170 // Verify all roots and all references
171 ZStatTimerDisable disable;
172 roots_and_objects(true /* verify_weaks */);
173 }
174
175 template <bool Map>
176 class ZPageDebugMapOrUnmapClosure : public ZPageClosure {
177 private:
178 const ZPageAllocator* const _allocator;
179
180 public:
ZPageDebugMapOrUnmapClosure(const ZPageAllocator * allocator)181 ZPageDebugMapOrUnmapClosure(const ZPageAllocator* allocator) :
182 _allocator(allocator) {}
183
do_page(const ZPage * page)184 void do_page(const ZPage* page) {
185 if (Map) {
186 _allocator->debug_map_page(page);
187 } else {
188 _allocator->debug_unmap_page(page);
189 }
190 }
191 };
192
ZVerifyViewsFlip(const ZPageAllocator * allocator)193 ZVerifyViewsFlip::ZVerifyViewsFlip(const ZPageAllocator* allocator) :
194 _allocator(allocator) {
195 if (ZVerifyViews) {
196 // Unmap all pages
197 ZPageDebugMapOrUnmapClosure<false /* Map */> cl(_allocator);
198 ZHeap::heap()->pages_do(&cl);
199 }
200 }
201
~ZVerifyViewsFlip()202 ZVerifyViewsFlip::~ZVerifyViewsFlip() {
203 if (ZVerifyViews) {
204 // Map all pages
205 ZPageDebugMapOrUnmapClosure<true /* Map */> cl(_allocator);
206 ZHeap::heap()->pages_do(&cl);
207 }
208 }
209