• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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