1 /* 2 * Copyright (c) 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/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 39 static void 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 48 static void 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: 59 virtual void do_oop(oop* p) { 60 verify_oop(p); 61 } 62 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: 73 ZVerifyOopClosure(bool verify_weaks) : 74 ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_other), 75 _verify_weaks(verify_weaks) {} 76 77 virtual void do_oop(oop* p) { 78 if (_verify_weaks) { 79 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 verify_oop(p); 84 } 85 } 86 87 virtual void do_oop(narrowOop* p) { 88 ShouldNotReachHere(); 89 } 90 91 virtual ReferenceIterationMode reference_iteration_mode() { 92 return _verify_weaks ? DO_FIELDS : DO_FIELDS_EXCEPT_REFERENT; 93 } 94 }; 95 96 template <typename RootsIterator> 97 void ZVerify::roots() { 98 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); 99 assert(!ZResurrection::is_blocked(), "Invalid phase"); 100 101 if (ZVerifyRoots) { 102 ZVerifyRootClosure cl; 103 RootsIterator iter; 104 iter.oops_do(&cl); 105 } 106 } 107 108 void ZVerify::roots_strong() { 109 roots<ZRootsIterator>(); 110 } 111 112 void ZVerify::roots_weak() { 113 roots<ZWeakRootsIterator>(); 114 } 115 116 void ZVerify::roots_concurrent_strong() { 117 roots<ZConcurrentRootsIteratorClaimNone>(); 118 } 119 120 void ZVerify::roots_concurrent_weak() { 121 roots<ZConcurrentWeakRootsIterator>(); 122 } 123 124 void ZVerify::roots(bool verify_weaks) { 125 roots_strong(); 126 roots_concurrent_strong(); 127 if (verify_weaks) { 128 roots_weak(); 129 roots_concurrent_weak(); 130 } 131 } 132 133 void ZVerify::objects(bool verify_weaks) { 134 assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); 135 assert(ZGlobalPhase == ZPhaseMarkCompleted, "Invalid phase"); 136 assert(!ZResurrection::is_blocked(), "Invalid phase"); 137 138 if (ZVerifyObjects) { 139 ZVerifyOopClosure cl(verify_weaks); 140 ObjectToOopClosure object_cl(&cl); 141 ZHeap::heap()->object_iterate(&object_cl, verify_weaks); 142 } 143 } 144 145 void ZVerify::roots_and_objects(bool verify_weaks) { 146 roots(verify_weaks); 147 objects(verify_weaks); 148 } 149 150 void ZVerify::before_zoperation() { 151 // Verify strong roots 152 ZStatTimerDisable disable; 153 roots_strong(); 154 } 155 156 void ZVerify::after_mark() { 157 // Verify all strong roots and strong references 158 ZStatTimerDisable disable; 159 roots_and_objects(false /* verify_weaks */); 160 } 161 162 void ZVerify::after_weak_processing() { 163 // Verify all roots and all references 164 ZStatTimerDisable disable; 165 roots_and_objects(true /* verify_weaks */); 166 } 167 168 template <bool Map> 169 class ZPageDebugMapOrUnmapClosure : public ZPageClosure { 170 private: 171 const ZPageAllocator* const _allocator; 172 173 public: 174 ZPageDebugMapOrUnmapClosure(const ZPageAllocator* allocator) : 175 _allocator(allocator) {} 176 177 void do_page(const ZPage* page) { 178 if (Map) { 179 _allocator->debug_map_page(page); 180 } else { 181 _allocator->debug_unmap_page(page); 182 } 183 } 184 }; 185 186 ZVerifyViewsFlip::ZVerifyViewsFlip(const ZPageAllocator* allocator) : 187 _allocator(allocator) { 188 if (ZVerifyViews) { 189 // Unmap all pages 190 ZPageDebugMapOrUnmapClosure<false /* Map */> cl(_allocator); 191 ZHeap::heap()->pages_do(&cl); 192 } 193 } 194 195 ZVerifyViewsFlip::~ZVerifyViewsFlip() { 196 if (ZVerifyViews) { 197 // Map all pages 198 ZPageDebugMapOrUnmapClosure<true /* Map */> cl(_allocator); 199 ZHeap::heap()->pages_do(&cl); 200 } 201 }