1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef PANDA_MEM_HEAP_VERIFIER_H 16 #define PANDA_MEM_HEAP_VERIFIER_H 17 18 #include "libpandabase/utils/bit_utils.h" 19 #include "libpandabase/utils/logger.h" 20 #include "runtime/mem/object_helpers.h" 21 #include "runtime/mem/rendezvous.h" 22 23 namespace panda::mem { 24 25 class HeapManager; 26 class GCRoot; 27 28 /** 29 * HeapReferenceVerifier checks reference checks if the referent is with the heap and it is live. 30 */ 31 template <LangTypeT LangType = LANG_TYPE_STATIC> 32 class HeapReferenceVerifier { 33 public: HeapReferenceVerifier(HeapManager * heap,size_t * count)34 explicit HeapReferenceVerifier(HeapManager *heap, size_t *count) : HEAP(heap), FAIL_COUNT(count) {} 35 36 void operator()(ObjectHeader *object_header, ObjectHeader *referent); 37 38 void operator()(const GCRoot &root); 39 40 private: 41 HeapManager *const HEAP {nullptr}; 42 size_t *const FAIL_COUNT {nullptr}; 43 }; 44 45 /** 46 * HeapObjectVerifier iterates over HeapManager's allocated objects. If an object contains reference, it checks if the 47 * referent is with the heap and it is live. 48 */ 49 template <LangTypeT LangType = LANG_TYPE_STATIC> 50 class HeapObjectVerifier { 51 public: 52 HeapObjectVerifier() = delete; 53 HeapObjectVerifier(HeapManager * heap,size_t * count)54 HeapObjectVerifier(HeapManager *heap, size_t *count) : HEAP(heap), FAIL_COUNT(count) {} 55 56 void operator()(ObjectHeader *obj); 57 GetFailCount()58 size_t GetFailCount() const 59 { 60 return *FAIL_COUNT; 61 } 62 63 private: 64 HeapManager *const HEAP {nullptr}; 65 size_t *const FAIL_COUNT {nullptr}; 66 }; 67 68 class HeapVerifierBase { 69 public: HeapVerifierBase(HeapManager * heap)70 explicit HeapVerifierBase(HeapManager *heap) : heap_(heap) {} 71 DEFAULT_COPY_SEMANTIC(HeapVerifierBase); 72 DEFAULT_MOVE_SEMANTIC(HeapVerifierBase); 73 ~HeapVerifierBase() = default; 74 75 protected: 76 HeapManager *heap_ = nullptr; // NOLINT(misc-non-private-member-variables-in-classes) 77 }; 78 79 /** 80 * A class to query address validity. 81 */ 82 template <class LanguageConfig> 83 class HeapVerifier : public HeapVerifierBase { 84 public: HeapVerifier(HeapManager * heap)85 explicit HeapVerifier(HeapManager *heap) : HeapVerifierBase(heap) {} 86 DEFAULT_COPY_SEMANTIC(HeapVerifier); 87 DEFAULT_MOVE_SEMANTIC(HeapVerifier); 88 ~HeapVerifier() = default; 89 90 bool IsValidObjectAddress(void *addr) const; 91 92 bool IsHeapAddress(void *addr) const; 93 94 size_t VerifyRoot() const; 95 96 size_t VerifyHeap() const; 97 VerifyAll()98 size_t VerifyAll() const 99 { 100 return VerifyRoot() + VerifyHeap(); 101 } 102 103 size_t VerifyAllPaused() const; 104 }; 105 106 /** 107 * Fast heap verifier for check heap and stack 108 */ 109 template <class LanguageConfig> 110 class FastHeapVerifier : public HeapVerifierBase { 111 public: FastHeapVerifier(HeapManager * heap)112 explicit FastHeapVerifier(HeapManager *heap) : HeapVerifierBase(heap) {} 113 DEFAULT_COPY_SEMANTIC(FastHeapVerifier); 114 DEFAULT_MOVE_SEMANTIC(FastHeapVerifier); 115 ~FastHeapVerifier() = default; 116 117 size_t VerifyAll() const; 118 119 private: 120 struct ObjectCache { 121 const ObjectHeader *heap_object; 122 const ObjectHeader *referent; 123 }; 124 }; 125 126 class ObjectVerificationInfo { 127 public: 128 explicit ObjectVerificationInfo(ObjectHeader *referent); 129 DEFAULT_COPY_SEMANTIC(ObjectVerificationInfo); 130 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(ObjectVerificationInfo); 131 ~ObjectVerificationInfo() = default; 132 133 /** 134 * Check that updated reference \p updated_ref from \p object has same state as before 135 * collecting and refs updating 136 * 137 * @param object the object which contains verifying reference 138 * @param updated_ref new referent position after moving 139 * @param in_alive_space whether the object places in space which was not moved (region promotion, for example) 140 * @return true if reference is correct and false otherwise 141 */ 142 bool VerifyUpdatedRef(ObjectHeader *object, ObjectHeader *updated_ref, bool in_alive_space) const; 143 144 private: 145 void *class_address_ = nullptr; 146 ObjectHeader *old_address_ = nullptr; 147 }; 148 149 template <class LanguageConfig> 150 class HeapVerifierIntoGC : public HeapVerifierBase { 151 public: HeapVerifierIntoGC(HeapManager * heap)152 explicit HeapVerifierIntoGC(HeapManager *heap) : HeapVerifierBase(heap) {} 153 DEFAULT_COPY_SEMANTIC(HeapVerifierIntoGC); 154 DEFAULT_MOVE_SEMANTIC(HeapVerifierIntoGC); 155 ~HeapVerifierIntoGC() = default; 156 157 void CollectVerificationInfo(PandaVector<MemRange> &&collectable_mem_ranges); 158 159 size_t VerifyAll(PandaVector<MemRange> &&alive_mem_ranges = PandaVector<MemRange>()); 160 161 private: 162 using VerifyingRefs = PandaUnorderedMap<size_t, ObjectVerificationInfo>; 163 using RefsVerificationInfo = PandaUnorderedMap<ObjectHeader *, VerifyingRefs>; 164 165 bool InCollectableSpace(const ObjectHeader *object) const; 166 bool InAliveSpace(const ObjectHeader *object) const; 167 void AddToVerificationInfo(RefsVerificationInfo &verification_info, size_t ref_number, ObjectHeader *object_header, 168 ObjectHeader *referent); 169 170 RefsVerificationInfo collectable_verification_info_; 171 RefsVerificationInfo permanent_verification_info_; 172 PandaVector<MemRange> collectable_mem_ranges_; 173 PandaVector<MemRange> alive_mem_ranges_; 174 }; 175 } // namespace panda::mem 176 177 #endif // PANDA_MEM_HEAP_VERIFIER_H 178