1 /** 2 * Copyright (c) 2021-2024 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 ark::mem { 24 25 class HeapManager; 26 class GCRoot; 27 28 /// HeapReferenceVerifier checks reference checks if the referent is with the heap and it is live. 29 template <LangTypeT LANG_TYPE = LANG_TYPE_STATIC> 30 class HeapReferenceVerifier { 31 public: HeapReferenceVerifier(HeapManager * heap,size_t * count)32 explicit HeapReferenceVerifier(HeapManager *heap, size_t *count) : heap_(heap), failCount_(count) {} 33 34 void operator()(ObjectHeader *objectHeader, ObjectHeader *referent); 35 36 void operator()(const GCRoot &root); 37 38 private: 39 HeapManager *const heap_ {nullptr}; 40 size_t *const failCount_ {nullptr}; 41 }; 42 43 /** 44 * HeapObjectVerifier iterates over HeapManager's allocated objects. If an object contains reference, it checks if the 45 * referent is with the heap and it is live. 46 */ 47 template <LangTypeT LANG_TYPE = LANG_TYPE_STATIC> 48 class HeapObjectVerifier { 49 public: 50 HeapObjectVerifier() = delete; 51 HeapObjectVerifier(HeapManager * heap,size_t * count)52 HeapObjectVerifier(HeapManager *heap, size_t *count) : heap_(heap), failCount_(count) {} 53 54 void operator()(ObjectHeader *obj); 55 GetFailCount()56 size_t GetFailCount() const 57 { 58 return *failCount_; 59 } 60 61 private: 62 HeapManager *const heap_ {nullptr}; 63 size_t *const failCount_ {nullptr}; 64 }; 65 66 class HeapVerifierBase { 67 public: HeapVerifierBase(HeapManager * heap)68 explicit HeapVerifierBase(HeapManager *heap) : heap_(heap) {} 69 DEFAULT_COPY_SEMANTIC(HeapVerifierBase); 70 DEFAULT_MOVE_SEMANTIC(HeapVerifierBase); 71 ~HeapVerifierBase() = default; 72 73 protected: 74 HeapManager *heap_ = nullptr; // NOLINT(misc-non-private-member-variables-in-classes) 75 }; 76 77 /// A class to query address validity. 78 template <class LanguageConfig> 79 class HeapVerifier : public HeapVerifierBase { 80 public: HeapVerifier(HeapManager * heap)81 explicit HeapVerifier(HeapManager *heap) : HeapVerifierBase(heap) {} 82 DEFAULT_COPY_SEMANTIC(HeapVerifier); 83 DEFAULT_MOVE_SEMANTIC(HeapVerifier); 84 ~HeapVerifier() = default; 85 86 bool IsValidObjectAddress(void *addr) const; 87 88 bool IsHeapAddress(void *addr) const; 89 90 size_t VerifyRoot() const; 91 92 size_t VerifyHeap() const; 93 VerifyAll()94 size_t VerifyAll() const 95 { 96 return VerifyRoot() + VerifyHeap(); 97 } 98 99 size_t VerifyAllPaused() const; 100 }; 101 102 /// Fast heap verifier for check heap and stack 103 template <class LanguageConfig> 104 class FastHeapVerifier : public HeapVerifierBase { 105 public: FastHeapVerifier(HeapManager * heap)106 explicit FastHeapVerifier(HeapManager *heap) : HeapVerifierBase(heap) {} 107 DEFAULT_COPY_SEMANTIC(FastHeapVerifier); 108 DEFAULT_MOVE_SEMANTIC(FastHeapVerifier); 109 ~FastHeapVerifier() = default; 110 111 size_t VerifyAll() const; 112 113 private: 114 struct ObjectCache { 115 const ObjectHeader *heapObject; 116 const ObjectHeader *referent; 117 }; 118 119 size_t CheckHeap(const PandaUnorderedSet<const ObjectHeader *> &heapObjects, 120 const PandaVector<ObjectCache> &referentObjects) const; 121 }; 122 123 class ObjectVerificationInfo { 124 public: 125 explicit ObjectVerificationInfo(ObjectHeader *referent); 126 DEFAULT_COPY_SEMANTIC(ObjectVerificationInfo); 127 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(ObjectVerificationInfo); 128 ~ObjectVerificationInfo() = default; 129 130 /** 131 * Check that updated reference \p updated_ref from \p object has same state as before 132 * collecting and refs updating 133 * 134 * @param object the object which contains verifying reference 135 * @param updated_ref new referent position after moving 136 * @param in_alive_space whether the object places in space which was not moved (region promotion, for example) 137 * @return true if reference is correct and false otherwise 138 */ 139 bool VerifyUpdatedRef(ObjectHeader *object, ObjectHeader *updatedRef, bool inAliveSpace) const; 140 141 private: 142 void *classAddress_ = nullptr; 143 ObjectHeader *oldAddress_ = nullptr; 144 }; 145 146 template <class LanguageConfig> 147 class HeapVerifierIntoGC : public HeapVerifierBase { 148 public: HeapVerifierIntoGC(HeapManager * heap)149 explicit HeapVerifierIntoGC(HeapManager *heap) : HeapVerifierBase(heap) {} 150 DEFAULT_COPY_SEMANTIC(HeapVerifierIntoGC); 151 DEFAULT_MOVE_SEMANTIC(HeapVerifierIntoGC); 152 ~HeapVerifierIntoGC() = default; 153 154 void CollectVerificationInfo(PandaVector<MemRange> &&collectableMemRanges); 155 156 size_t VerifyAll(PandaVector<MemRange> &&aliveMemRanges = PandaVector<MemRange>()); 157 158 private: 159 using VerifyingRefs = PandaUnorderedMap<size_t, ObjectVerificationInfo>; 160 using RefsVerificationInfo = PandaUnorderedMap<ObjectHeader *, VerifyingRefs>; 161 162 bool InCollectableSpace(const ObjectHeader *object) const; 163 bool InAliveSpace(const ObjectHeader *object) const; 164 void AddToVerificationInfo(RefsVerificationInfo &verificationInfo, size_t refNumber, ObjectHeader *objectHeader, 165 ObjectHeader *referent); 166 167 RefsVerificationInfo collectableVerificationInfo_; 168 RefsVerificationInfo permanentVerificationInfo_; 169 PandaVector<MemRange> collectableMemRanges_; 170 PandaVector<MemRange> aliveMemRanges_; 171 }; 172 } // namespace ark::mem 173 174 #endif // PANDA_MEM_HEAP_VERIFIER_H 175